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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_sw.hxx" 24 25 #include <com/sun/star/embed/EmbedMisc.hpp> 26 #include "hintids.hxx" 27 #include <svx/sdrobjectfilter.hxx> 28 #include <svx/svditer.hxx> 29 #include <svx/svdobj.hxx> 30 #include <svx/svdouno.hxx> 31 #include <svx/svdoole2.hxx> 32 #include <svx/svdogrp.hxx> 33 #include <svx/svdocirc.hxx> 34 #include <svx/svdopath.hxx> 35 #include <svx/sxciaitm.hxx> 36 #include <svx/xfillit.hxx> 37 #include <svx/svdocapt.hxx> 38 #include <sfx2/app.hxx> 39 #include <editeng/boxitem.hxx> 40 #include <editeng/opaqitem.hxx> 41 #include <editeng/protitem.hxx> 42 #include <svx/svdpage.hxx> 43 #include <svx/svdpagv.hxx> 44 #include <IDocumentSettingAccess.hxx> 45 #include <cmdid.h> 46 #include <poolfmt.hrc> // fuer InitFldTypes 47 #include <frmfmt.hxx> 48 #include <frmatr.hxx> 49 #include <fmtfsize.hxx> 50 #include <fmtanchr.hxx> 51 #include <fmtornt.hxx> 52 #include <fmtsrnd.hxx> 53 #include <fmtcntnt.hxx> 54 #include <fmtflcnt.hxx> 55 #include <fmtcnct.hxx> 56 #include <docary.hxx> 57 #include <tblsel.hxx> 58 #include <swtable.hxx> 59 #include <flyfrms.hxx> 60 #include "fesh.hxx" 61 #include "rootfrm.hxx" 62 #include "pagefrm.hxx" 63 #include "sectfrm.hxx" 64 #include "doc.hxx" 65 #include <IDocumentUndoRedo.hxx> 66 #include "dview.hxx" 67 #include "dflyobj.hxx" 68 #include "dcontact.hxx" 69 #include "viewimp.hxx" 70 #include "flyfrm.hxx" 71 #include "pam.hxx" 72 #include "ndole.hxx" 73 #include "ndgrf.hxx" 74 #include "ndtxt.hxx" 75 #include "viewopt.hxx" // fuer GetHTMLMode 76 #include "swundo.hxx" 77 #include "notxtfrm.hxx" 78 #include "txtfrm.hxx" 79 #include "txatbase.hxx" 80 #include "mdiexp.hxx" // fuer Update der Statuszeile bei drag 81 #include <sortedobjs.hxx> 82 #include <HandleAnchorNodeChg.hxx> 83 #include <basegfx/polygon/b2dpolygon.hxx> 84 #include <switerator.hxx> 85 #include <drawdoc.hxx> 86 87 #define SCROLLVAL 75 88 89 using namespace com::sun::star; 90 91 //Tattergrenze fuer Drawing-SS 92 #define MINMOVE ((sal_uInt16)GetOut()->PixelToLogic(Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width()) 93 94 SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh ) 95 { 96 if ( !pLst ) 97 pLst = pSh->HasDrawView() ? &pSh->Imp()->GetDrawView()->GetMarkedObjectList():0; 98 99 if ( pLst && pLst->GetMarkCount() == 1 ) 100 { 101 SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj(); 102 if ( pO && pO->ISA(SwVirtFlyDrawObj) ) 103 return ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); 104 } 105 return 0; 106 } 107 108 void lcl_GrabCursor( SwFEShell* pSh, SwFlyFrm* pOldSelFly) 109 { 110 const SwFrmFmt *pFlyFmt = pSh->SelFlyGrabCrsr(); 111 if( pFlyFmt && !pSh->ActionPend() && 112 (!pOldSelFly || pOldSelFly->GetFmt() != pFlyFmt) ) 113 { 114 // dann das evt. gesetzte Macro rufen 115 pSh->GetFlyMacroLnk().Call( (void*)pFlyFmt ); 116 extern sal_Bool bNoInterrupt; // in swapp.cxx 117 // wir in dem Makro ein Dialog gestartet, dann kommt das 118 // MouseButtonUp zu diesem und nicht zu uns. Dadurch ist 119 // Flag bei uns immer gesetzt und schaltet nie die auf die 120 // entsp. Shell um !!!!!!! 121 bNoInterrupt = sal_False; 122 } 123 else if( !pFlyFmt || RES_DRAWFRMFMT == pFlyFmt->Which() ) 124 { 125 // --> OD 2007-07-25 #136039# 126 // assure consistent cursor 127 pSh->KillPams(); 128 pSh->ClearMark(); 129 // <-- 130 pSh->SetCrsr( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), sal_True); 131 } 132 } 133 134 /************************************************************************* 135 |* 136 |* SwFEShell::SelectObj() 137 *************************************************************************/ 138 139 sal_Bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj ) 140 { 141 SwDrawView *pDView = Imp()->GetDrawView(); 142 if(!pDView) 143 return sal_False; 144 SET_CURR_SHELL( this ); 145 StartAction(); //Aktion ist Notwendig, damit nicht mehrere 146 //AttrChgdNotify (etwa durch Unmark->MarkListHasChgd) 147 //durchkommen 148 149 const SdrMarkList &rMrkList = pDView->GetMarkedObjectList(); 150 const sal_Bool bHadSelection = rMrkList.GetMarkCount() ? sal_True : sal_False; 151 const sal_Bool bAddSelect = 0 != (SW_ADD_SELECT & nFlag); 152 const sal_Bool bEnterGroup = 0 != (SW_ENTER_GROUP & nFlag); 153 SwFlyFrm* pOldSelFly = 0; 154 const Point aOldPos( pDView->GetAllMarkedRect().TopLeft() ); 155 156 if( bHadSelection ) 157 { 158 //Unmark rufen wenn !bAddSelect oder wenn ein Fly selektiert ist. 159 sal_Bool bUnmark = !bAddSelect; 160 161 if ( rMrkList.GetMarkCount() == 1 ) 162 { 163 //Wenn ein Fly selektiert ist, so muss er erst deselektiert werden. 164 pOldSelFly = ::GetFlyFromMarked( &rMrkList, this ); 165 if ( pOldSelFly ) 166 { 167 const sal_uInt16 nType = GetCntType(); 168 if( nType != CNT_TXT || (SW_LEAVE_FRAME & nFlag) || 169 ( pOldSelFly->GetFmt()->GetProtect().IsCntntProtected() 170 && !IsReadOnlyAvailable() )) 171 { 172 //Wenn ein Fly deselektiert wird, der Grafik, Ole o.ae. 173 //enthaelt, so muss der Crsr aus diesem entfernt werden. 174 //Desgleichen wenn ein Fly mit geschuetztem Inhalt deselektiert 175 //wird. Der Einfachheit halber wire der Crsr 'grad so neben die 176 //linke obere Ecke gesetzt. 177 Point aPt( pOldSelFly->Frm().Pos() ); 178 aPt.X() -= 1; 179 sal_Bool bUnLockView = !IsViewLocked(); 180 LockView( sal_True ); 181 SetCrsr( aPt, sal_True ); 182 if( bUnLockView ) 183 LockView( sal_False ); 184 } 185 if ( nType & CNT_GRF && 186 ((SwNoTxtFrm*)pOldSelFly->Lower())->HasAnimation() ) 187 { 188 GetWin()->Invalidate( pOldSelFly->Frm().SVRect() ); 189 } 190 bUnmark = sal_True; 191 } 192 } 193 if ( bUnmark ) 194 pDView->UnmarkAll(); 195 } 196 else 197 { 198 KillPams(); 199 ClearMark(); 200 } 201 202 if ( pObj ) 203 { 204 ASSERT( !bEnterGroup, "SW_ENTER_GROUP is not supported" ); 205 pDView->MarkObj( pObj, Imp()->GetPageView() ); 206 } 207 else 208 { 209 pDView->MarkObj( rPt, MINMOVE, bAddSelect, bEnterGroup ); 210 } 211 212 const sal_Bool bRet = 0 != rMrkList.GetMarkCount(); 213 214 if ( rMrkList.GetMarkCount() > 1 ) 215 { 216 //Ganz dumm ist es, wenn Zeichenobjekte Selektiert waren und 217 //nun ein Fly hinzuselektiert wird. 218 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 219 { 220 SdrObject *pTmpObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 221 sal_Bool bForget = pTmpObj->ISA(SwVirtFlyDrawObj); 222 if( bForget ) 223 { 224 pDView->UnmarkAll(); 225 pDView->MarkObj( pTmpObj, Imp()->GetPageView(), bAddSelect, bEnterGroup ); 226 break; 227 } 228 } 229 } 230 231 if ( bRet ) 232 { 233 ::lcl_GrabCursor(this, pOldSelFly); 234 if ( GetCntType() & CNT_GRF ) 235 { 236 const SwFlyFrm *pTmp = GetFlyFromMarked( &rMrkList, this ); 237 ASSERT( pTmp, "Graphic without Fly" ); 238 if ( ((SwNoTxtFrm*)pTmp->Lower())->HasAnimation() ) 239 ((SwNoTxtFrm*)pTmp->Lower())->StopAnimation( GetOut() ); 240 } 241 } 242 else if ( !pOldSelFly && bHadSelection ) 243 SetCrsr( aOldPos, sal_True); 244 245 if( bRet || !bHadSelection ) 246 CallChgLnk(); 247 248 // update der Statuszeile 249 ::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END ); 250 251 EndAction(); 252 return bRet; 253 } 254 255 /************************************************************************* 256 |* 257 |* sal_Bool SwFEShell::MoveAnchor( sal_uInt16 nDir ) 258 |* 259 |* Description: MoveAnchor( nDir ) looked for an another Anchor for 260 |* the selected drawing object (or fly frame) in the given direction. 261 |* An object "as character" doesn't moves anyway. 262 |* A page bounded object could move to the previous/next page with up/down, 263 |* an object bounded "at paragraph" moves to the previous/next paragraph, too. 264 |* An object bounded "at character" moves to the previous/next paragraph 265 |* with up/down and to the previous/next character with left/right. 266 |* If the anchor for at paragraph/character bounded objects has vertical or 267 |* right_to_left text direction, the directions for up/down/left/right will 268 |* interpreted accordingly. 269 |* An object bounded "at fly" takes the center of the actual anchor and looks 270 |* for the nearest fly frame in the given direction. 271 |* 272 *************************************************************************/ 273 274 #define LESS_X( aPt1, aPt2, bOld ) ( aPt1.X() < aPt2.X() || \ 275 ( aPt1.X() == aPt2.X() && ( aPt1.Y() < aPt2.Y() || \ 276 ( aPt1.Y() == aPt2.Y() && bOld ) ) ) ) 277 #define LESS_Y( aPt1, aPt2, bOld ) ( aPt1.Y() < aPt2.Y() || \ 278 ( aPt1.Y() == aPt2.Y() && ( aPt1.X() < aPt2.X() || \ 279 ( aPt1.X() == aPt2.X() && bOld ) ) ) ) 280 281 sal_Bool SwFEShell::MoveAnchor( sal_uInt16 nDir ) 282 { 283 const SdrMarkList* pMrkList; 284 if( !Imp()->GetDrawView() || 285 0 == (pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList()) || 286 1 != pMrkList->GetMarkCount()) 287 return sal_False; 288 SwFrm* pOld; 289 SwFlyFrm* pFly = NULL; 290 SdrObject *pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 291 if( pObj->ISA(SwVirtFlyDrawObj) ) 292 { 293 pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 294 pOld = pFly->AnchorFrm(); 295 } 296 else 297 pOld = ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj ); 298 sal_Bool bRet = sal_False; 299 if( pOld ) 300 { 301 SwFrm* pNew = pOld; 302 // --> OD 2004-07-16 #i28701# 303 SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); 304 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); 305 SwFmtAnchor aAnch( rFmt.GetAnchor() ); 306 RndStdIds nAnchorId = aAnch.GetAnchorId(); 307 if ( FLY_AS_CHAR == nAnchorId ) 308 return sal_False; 309 if( pOld->IsVertical() ) 310 { 311 if( pOld->IsTxtFrm() ) 312 { 313 switch( nDir ) { 314 case SW_MOVE_UP: nDir = SW_MOVE_LEFT; break; 315 case SW_MOVE_DOWN: nDir = SW_MOVE_RIGHT; break; 316 case SW_MOVE_LEFT: nDir = SW_MOVE_DOWN; break; 317 case SW_MOVE_RIGHT: nDir = SW_MOVE_UP; break; 318 } 319 if( pOld->IsRightToLeft() ) 320 { 321 if( nDir == SW_MOVE_LEFT ) 322 nDir = SW_MOVE_RIGHT; 323 else if( nDir == SW_MOVE_RIGHT ) 324 nDir = SW_MOVE_LEFT; 325 } 326 } 327 } 328 switch ( nAnchorId ) { 329 case FLY_AT_PAGE: 330 { 331 ASSERT( pOld->IsPageFrm(), "Wrong anchor, page exspected." ); 332 if( SW_MOVE_UP == nDir ) 333 pNew = pOld->GetPrev(); 334 else if( SW_MOVE_DOWN == nDir ) 335 pNew = pOld->GetNext(); 336 if( pNew && pNew != pOld ) 337 { 338 aAnch.SetPageNum( ((SwPageFrm*)pNew)->GetPhyPageNum() ); 339 bRet = sal_True; 340 } 341 break; 342 } 343 case FLY_AT_CHAR: 344 { 345 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." ); 346 if( SW_MOVE_LEFT == nDir || SW_MOVE_RIGHT == nDir ) 347 { 348 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor(); 349 SwTxtNode* pTxtNd = ((SwTxtFrm*)pOld)->GetTxtNode(); 350 xub_StrLen nAct = pPos->nContent.GetIndex(); 351 if( SW_MOVE_LEFT == nDir ) 352 { 353 bRet = sal_True; 354 if( nAct ) 355 { 356 --nAct; 357 pPos->nContent.Assign( pTxtNd, nAct ); 358 } 359 else 360 nDir = SW_MOVE_UP; 361 } 362 else 363 { 364 xub_StrLen nMax = 365 ((SwTxtFrm*)pOld)->GetTxtNode()->GetTxt().Len(); 366 if( nAct < nMax ) 367 { 368 ++nAct; 369 bRet = sal_True; 370 pPos->nContent.Assign( pTxtNd, nAct ); 371 } 372 else 373 nDir = SW_MOVE_DOWN; 374 } 375 } 376 } // no break! 377 case FLY_AT_PARA: 378 { 379 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." ); 380 if( SW_MOVE_UP == nDir ) 381 pNew = pOld->FindPrev(); 382 else if( SW_MOVE_DOWN == nDir ) 383 pNew = pOld->FindNext(); 384 if( pNew && pNew != pOld && pNew->IsCntntFrm() ) 385 { 386 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor(); 387 SwTxtNode* pTxtNd = ((SwTxtFrm*)pNew)->GetTxtNode(); 388 pPos->nNode = *pTxtNd; 389 xub_StrLen nTmp = 0; 390 if( bRet ) 391 { 392 nTmp = ((SwTxtFrm*)pNew)->GetTxtNode()->GetTxt().Len(); 393 if( nTmp ) 394 --nTmp; 395 } 396 pPos->nContent.Assign( pTxtNd, nTmp ); 397 bRet = sal_True; 398 } 399 else if( SW_MOVE_UP == nDir || SW_MOVE_DOWN == nDir ) 400 bRet = sal_False; 401 break; 402 } 403 case FLY_AT_FLY: 404 { 405 ASSERT( pOld->IsFlyFrm(), "Wrong anchor, fly frame exspected."); 406 SwPageFrm* pPage = pOld->FindPageFrm(); 407 ASSERT( pPage, "Where's my page?" ); 408 SwFlyFrm* pNewFly = NULL; 409 if( pPage->GetSortedObjs() ) 410 { 411 int i; 412 sal_Bool bOld = sal_False; 413 Point aCenter( pOld->Frm().Left() + pOld->Frm().Width()/2, 414 pOld->Frm().Top() + pOld->Frm().Height()/2 ); 415 Point aBest; 416 for( i = 0; (sal_uInt16)i<pPage->GetSortedObjs()->Count(); ++i ) 417 { 418 SwAnchoredObject* pAnchObj = 419 (*pPage->GetSortedObjs())[i]; 420 if( pAnchObj->ISA(SwFlyFrm) ) 421 { 422 SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(pAnchObj); 423 if( pTmp == pOld ) 424 bOld = sal_True; 425 else 426 { 427 const SwFlyFrm* pCheck = pFly ? pTmp : 0; 428 while( pCheck ) 429 { 430 if( pCheck == pFly ) 431 break; 432 const SwFrm *pNxt = pCheck->GetAnchorFrm(); 433 pCheck = pNxt ? pNxt->FindFlyFrm() : NULL; 434 } 435 if( pCheck || pTmp->IsProtected() ) 436 continue; 437 Point aNew( pTmp->Frm().Left() + 438 pTmp->Frm().Width()/2, 439 pTmp->Frm().Top() + 440 pTmp->Frm().Height()/2 ); 441 sal_Bool bAccept = sal_False; 442 switch( nDir ) { 443 case SW_MOVE_RIGHT: 444 { 445 bAccept = LESS_X( aCenter, aNew, bOld ) 446 && ( !pNewFly || 447 LESS_X( aNew, aBest, sal_False ) ); 448 break; 449 } 450 case SW_MOVE_LEFT: 451 { 452 bAccept = LESS_X( aNew, aCenter, !bOld ) 453 && ( !pNewFly || 454 LESS_X( aBest, aNew, sal_True ) ); 455 break; 456 } 457 case SW_MOVE_UP: 458 { 459 bAccept = LESS_Y( aNew, aCenter, !bOld ) 460 && ( !pNewFly || 461 LESS_Y( aBest, aNew, sal_True ) ); 462 break; 463 } 464 case SW_MOVE_DOWN: 465 { 466 bAccept = LESS_Y( aCenter, aNew, bOld ) 467 && ( !pNewFly || 468 LESS_Y( aNew, aBest, sal_False ) ); 469 break; 470 } 471 } 472 if( bAccept ) 473 { 474 pNewFly = pTmp; 475 aBest = aNew; 476 } 477 } 478 } 479 } 480 } 481 482 if( pNewFly ) 483 { 484 SwPosition aPos( *pNewFly->GetFmt()-> 485 GetCntnt().GetCntntIdx()); 486 aAnch.SetAnchor( &aPos ); 487 bRet = sal_True; 488 } 489 break; 490 } 491 default: break; 492 } 493 if( bRet ) 494 { 495 StartAllAction(); 496 // --> OD 2006-02-28 #125892# 497 // handle change of anchor node: 498 // if count of the anchor frame also change, the fly frames have to be 499 // re-created. Thus, delete all fly frames except the <this> before the 500 // anchor attribute is change and re-create them afterwards. 501 { 502 SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L ); 503 SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) ); 504 if ( pFlyFrmFmt ) 505 { 506 pHandleAnchorNodeChg = 507 new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch ); 508 } 509 rFmt.GetDoc()->SetAttr( aAnch, rFmt ); 510 delete pHandleAnchorNodeChg; 511 } 512 // <-- 513 // --> OD 2004-06-24 #i28701# - no call of method 514 // <CheckCharRectAndTopOfLine()> for to-character anchored 515 // Writer fly frame needed. This method call can cause a 516 // format of the anchor frame, which is no longer intended. 517 // Instead clear the anchor character rectangle and 518 // the top of line values for all to-character anchored objects. 519 pAnchoredObj->ClearCharRectAndTopOfLine(); 520 EndAllAction(); 521 } 522 } 523 return bRet; 524 } 525 526 /************************************************************************* 527 |* 528 |* SwFEShell::GetSelFrmType() 529 |* 530 *************************************************************************/ 531 532 const SdrMarkList* SwFEShell::_GetMarkList() const 533 { 534 const SdrMarkList* pMarkList = NULL; 535 if( Imp()->GetDrawView() != NULL ) 536 pMarkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 537 return pMarkList; 538 } 539 540 sal_uInt16 SwFEShell::GetSelFrmType() const 541 { 542 sal_uInt16 eType; 543 544 // get marked frame list, and check if anything is selected 545 const SdrMarkList* pMarkList = _GetMarkList(); 546 if( pMarkList == NULL || pMarkList->GetMarkCount() == 0 ) 547 eType = FRMTYPE_NONE; 548 else 549 { 550 // obtain marked item as fly frame; if no fly frame, it must 551 // be a draw object 552 const SwFlyFrm* pFly = ::GetFlyFromMarked(pMarkList, (ViewShell*)this); 553 if ( pFly != NULL ) 554 { 555 if( pFly->IsFlyLayFrm() ) 556 eType = FRMTYPE_FLY_FREE; 557 else if( pFly->IsFlyAtCntFrm() ) 558 eType = FRMTYPE_FLY_ATCNT; 559 else 560 { 561 ASSERT( pFly->IsFlyInCntFrm(), "Neuer Rahmentyp?" ); 562 eType = FRMTYPE_FLY_INCNT; 563 } 564 } 565 else 566 eType = FRMTYPE_DRAWOBJ; 567 } 568 569 return eType; 570 } 571 572 // #108784# does the draw selection contain a control? 573 bool SwFEShell::IsSelContainsControl() const 574 { 575 bool bRet = false; 576 577 // basically, copy the mechanism from GetSelFrmType(), but call 578 // CheckControl... if you get a drawing object 579 const SdrMarkList* pMarkList = _GetMarkList(); 580 if( pMarkList != NULL && pMarkList->GetMarkCount() == 1 ) 581 { 582 // if we have one marked object, get the SdrObject and check 583 // whether it contains a control 584 const SdrObject* pSdrObject = pMarkList->GetMark( 0 )->GetMarkedSdrObj(); 585 bRet = pSdrObject && ::CheckControlLayer( pSdrObject ); 586 } 587 return bRet; 588 } 589 590 /************************************************************************* 591 |* 592 |* SwFEShell::Scroll() 593 |* 594 *************************************************************************/ 595 596 void SwFEShell::ScrollTo( const Point &rPt ) 597 { 598 const SwRect aRect( rPt, rPt ); 599 if ( IsScrollMDI( this, aRect ) && 600 (!Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() || 601 Imp()->IsDragPossible( rPt )) ) 602 { 603 //SwSaveHdl aSave( Imp() ); 604 ScrollMDI( this, aRect, SCROLLVAL, SCROLLVAL ); 605 } 606 } 607 608 /************************************************************************* 609 |* 610 |* SwFEShell::SetDragMode() 611 |* 612 *************************************************************************/ 613 614 void SwFEShell::SetDragMode( sal_uInt16 eDragMode ) 615 { 616 if ( Imp()->HasDrawView() ) 617 Imp()->GetDrawView()->SetDragMode( (SdrDragMode)eDragMode ); 618 } 619 620 /************************************************************************* 621 |* 622 |* SwFEShell::BeginDrag() 623 |* 624 *************************************************************************/ 625 626 long SwFEShell::BeginDrag( const Point* pPt, sal_Bool ) 627 { 628 SdrView *pView = Imp()->GetDrawView(); 629 if ( pView && pView->AreObjectsMarked() ) 630 { 631 delete pChainFrom; delete pChainTo; pChainFrom = pChainTo = 0; 632 SdrHdl* pHdl = pView->PickHandle( *pPt ); 633 pView->BegDragObj( *pPt, 0 /*GetWin()*/, pHdl ); 634 ::FrameNotify( this, FLY_DRAG ); 635 return 1; 636 } 637 return 0; 638 } 639 /************************************************************************* 640 |* 641 |* SwFEShell::Drag() 642 |* 643 *************************************************************************/ 644 645 long SwFEShell::Drag( const Point *pPt, sal_Bool ) 646 { 647 ASSERT( Imp()->HasDrawView(), "Drag without DrawView?" ); 648 if ( Imp()->GetDrawView()->IsDragObj() ) 649 { 650 ScrollTo( *pPt ); 651 Imp()->GetDrawView()->MovDragObj( *pPt ); 652 Imp()->GetDrawView()->ShowDragAnchor(); 653 ::FrameNotify( this, FLY_DRAG ); 654 return 1; 655 } 656 return 0; 657 } 658 659 /************************************************************************* 660 |* 661 |* SwFEShell::EndDrag() 662 |* 663 *************************************************************************/ 664 665 long SwFEShell::EndDrag( const Point *, sal_Bool ) 666 { 667 ASSERT( Imp()->HasDrawView(), "EndDrag without DrawView?" ); 668 SdrView *pView = Imp()->GetDrawView(); 669 if ( pView->IsDragObj() ) 670 { 671 //Start-/EndActions nur an der ViewShell aufsetzen 672 ViewShell *pSh = this; 673 do { 674 pSh->StartAction(); 675 } while ( this != (pSh = (ViewShell*)pSh->GetNext()) ); 676 677 StartUndo( UNDO_START ); 678 679 //#50778# Bug im Draging: Im StartAction wird ein HideShowXor gerufen. 680 //Im EndDragObj() wird dies unsinniger und faelschlicherweise wieder 681 //Rueckgaengig gemacht. Um Konsistenz herzustellen muessen wir das 682 //Xor also wieder zur Anzeige bringen. 683 684 // Reanimation from the hack #50778 to fix bug #97057 685 // May be not the best solution, but the one with lowest risc at the moment. 686 //pView->ShowShownXor( GetOut() ); 687 688 pView->EndDragObj(); 689 // DrawUndo-Action auf FlyFrames werden nicht gespeichert 690 // Die Fly aendern das Flag 691 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true); 692 ChgAnchor( 0, sal_True ); 693 694 EndUndo( UNDO_END ); 695 696 do { 697 pSh->EndAction(); 698 if( pSh->IsA( TYPE( SwCrsrShell ) ) ) 699 ((SwCrsrShell*)pSh)->CallChgLnk(); 700 } while ( this != (pSh = (ViewShell*)pSh->GetNext()) ); 701 702 GetDoc()->SetModified(); 703 ::FrameNotify( this, FLY_DRAG ); 704 return 1; 705 } 706 return 0; 707 } 708 709 /************************************************************************* 710 |* 711 |* SwFEShell::BreakDrag() 712 |* 713 *************************************************************************/ 714 715 void SwFEShell::BreakDrag() 716 { 717 ASSERT( Imp()->HasDrawView(), "BreakDrag without DrawView?" ); 718 if ( Imp()->GetDrawView()->IsDragObj() ) 719 Imp()->GetDrawView()->BrkDragObj(); 720 SetChainMarker(); 721 } 722 723 /************************************************************************* 724 |* 725 |* SwFEShell::SelFlyGrabCrsr() 726 |* 727 |* Beschreibung Wenn ein Fly selektiert ist, zieht er den Crsr in 728 |* den ersten CntntFrm 729 *************************************************************************/ 730 731 const SwFrmFmt* SwFEShell::SelFlyGrabCrsr() 732 { 733 if ( Imp()->HasDrawView() ) 734 { 735 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 736 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this ); 737 738 if( pFly ) 739 { 740 SwCntntFrm *pCFrm = pFly->ContainsCntnt(); 741 if ( pCFrm ) 742 { 743 SwCntntNode *pCNode = pCFrm->GetNode(); 744 // --> OD 2007-07-25 #126039# 745 // assure, that the cursor is consistent. 746 KillPams(); 747 ClearMark(); 748 // <-- 749 SwPaM *pCrsr = GetCrsr(); 750 751 pCrsr->GetPoint()->nNode = *pCNode; 752 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 ); 753 754 SwRect& rChrRect = (SwRect&)GetCharRect(); 755 rChrRect = pFly->Prt(); 756 rChrRect.Pos() += pFly->Frm().Pos(); 757 GetCrsrDocPos() = rChrRect.Pos(); 758 } 759 return pFly->GetFmt(); 760 } 761 } 762 return 0; 763 } 764 765 766 /************************************************************************* 767 |* 768 |* SwFEShell::SelectionToTop(), SelectionToBottom() 769 |* 770 |* Beschreibung Selektion nach oben/unten (Z-Order) 771 |* 772 *************************************************************************/ 773 774 void lcl_NotifyNeighbours( const SdrMarkList *pLst ) 775 { 776 //Die Regeln fuer die Ausweichmanoever haben sich veraendert. 777 //1. Die Umgebung des Fly und aller innenliegenden muss benachrichtigt 778 // werden. 779 //2. Der Inhalt des Rahmen selbst muss benachrichtigt werden. 780 //3. Rahmen die dem Rahmen ausweichen bzw. wichen muessen benachrichtigt werden. 781 //4. Auch Zeichenobjekte koennen Rahmen verdraengen 782 783 for( sal_uInt16 j = 0; j < pLst->GetMarkCount(); ++j ) 784 { 785 SwPageFrm *pPage; 786 sal_Bool bCheckNeighbours = sal_False; 787 sal_Int16 aHori = text::HoriOrientation::NONE; 788 SwRect aRect; 789 SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj(); 790 if ( pO->ISA(SwVirtFlyDrawObj) ) 791 { 792 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); 793 794 const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient(); 795 aHori = rHori.GetHoriOrient(); 796 if( text::HoriOrientation::NONE != aHori && text::HoriOrientation::CENTER != aHori && 797 pFly->IsFlyAtCntFrm() ) 798 { 799 bCheckNeighbours = sal_True; 800 pFly->InvalidatePos(); 801 pFly->Frm().Pos().Y() += 1; 802 } 803 804 pPage = pFly->FindPageFrm(); 805 aRect = pFly->Frm(); 806 } 807 else 808 { 809 SwFrm* pAnch = ( (SwDrawContact*)GetUserCall(pO) )->GetAnchorFrm( pO ); 810 if( !pAnch ) 811 continue; 812 pPage = pAnch->FindPageFrm(); 813 // --> OD 2006-08-15 #i68520# - naming changed 814 aRect = GetBoundRectOfAnchoredObj( pO ); 815 // <-- 816 } 817 818 sal_uInt32 nCount = pPage->GetSortedObjs() ? pPage->GetSortedObjs()->Count() : 0; 819 for ( sal_uInt32 i = 0; i < nCount; ++i ) 820 { 821 SwAnchoredObject* pAnchoredObj = (*pPage->GetSortedObjs())[i]; 822 if ( !pAnchoredObj->ISA(SwFlyFrm) ) 823 continue; 824 825 SwFlyFrm* pAct = static_cast<SwFlyFrm*>(pAnchoredObj); 826 SwRect aTmpCalcPnt( pAct->Prt() ); 827 aTmpCalcPnt += pAct->Frm().Pos(); 828 if ( aRect.IsOver( aTmpCalcPnt ) ) 829 { 830 SwCntntFrm *pCnt = pAct->ContainsCntnt(); 831 while ( pCnt ) 832 { 833 aTmpCalcPnt = pCnt->Prt(); 834 aTmpCalcPnt += pCnt->Frm().Pos(); 835 if ( aRect.IsOver( aTmpCalcPnt ) ) 836 ((SwFrm*)pCnt)->Prepare( PREP_FLY_ATTR_CHG ); 837 pCnt = pCnt->GetNextCntntFrm(); 838 } 839 } 840 if ( bCheckNeighbours && pAct->IsFlyAtCntFrm() ) 841 { 842 const SwFmtHoriOrient &rH = pAct->GetFmt()->GetHoriOrient(); 843 if ( rH.GetHoriOrient() == aHori && 844 pAct->Frm().Top() <= aRect.Bottom() && 845 pAct->Frm().Bottom() >= aRect.Top() ) 846 { 847 pAct->InvalidatePos(); 848 pAct->Frm().Pos().Y() += 1; 849 } 850 } 851 } 852 } 853 } 854 855 void SwFEShell::SelectionToTop( sal_Bool bTop ) 856 { 857 ASSERT( Imp()->HasDrawView(), "SelectionToTop without DrawView?" ); 858 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 859 ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." ); 860 861 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this ); 862 if ( pFly && pFly->IsFlyInCntFrm() ) 863 return; 864 865 StartAllAction(); 866 if ( bTop ) 867 Imp()->GetDrawView()->PutMarkedToTop(); 868 else 869 Imp()->GetDrawView()->MovMarkedToTop(); 870 ::lcl_NotifyNeighbours( &rMrkList ); 871 GetDoc()->SetModified(); 872 EndAllAction(); 873 } 874 875 void SwFEShell::SelectionToBottom( sal_Bool bBottom ) 876 { 877 ASSERT( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" ); 878 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 879 ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." ); 880 881 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this ); 882 if ( pFly && pFly->IsFlyInCntFrm() ) 883 return; 884 885 StartAllAction(); 886 if ( bBottom ) 887 Imp()->GetDrawView()->PutMarkedToBtm(); 888 else 889 Imp()->GetDrawView()->MovMarkedToBtm(); 890 ::lcl_NotifyNeighbours( &rMrkList ); 891 GetDoc()->SetModified(); 892 EndAllAction(); 893 } 894 895 /************************************************************************* 896 |* 897 |* SwFEShell::GetLayerId() 898 |* 899 |* Beschreibung Objekt ueber/unter dem Dokument? 900 |* 2 Controls, 1 Heaven, 0 Hell, -1 Uneindeutig 901 *************************************************************************/ 902 903 short SwFEShell::GetLayerId() const 904 { 905 short nRet = SHRT_MAX; 906 if ( Imp()->HasDrawView() ) 907 { 908 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 909 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 910 { 911 const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 912 if( !pObj ) 913 continue; 914 if ( nRet == SHRT_MAX ) 915 nRet = pObj->GetLayer(); 916 else if ( nRet != pObj->GetLayer() ) 917 { 918 nRet = -1; 919 break; 920 } 921 } 922 } 923 if ( nRet == SHRT_MAX ) 924 nRet = -1; 925 return nRet; 926 } 927 928 /************************************************************************* 929 |* 930 |* SwFEShell::SelectionToHeaven(), SelectionToHell() 931 |* 932 |* Beschreibung Objekt ueber/unter dem Dokument 933 |* 934 *************************************************************************/ 935 // OD 25.06.2003 #108784# 936 // Note: only visible objects can be marked. Thus, objects with invisible 937 // layer IDs have not to be considered. 938 // If <SwFEShell> exists, layout exists!! 939 void SwFEShell::ChangeOpaque( SdrLayerID nLayerId ) 940 { 941 if ( Imp()->HasDrawView() ) 942 { 943 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 944 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess(); 945 // OD 25.06.2003 #108784# - correct type of <nControls> 946 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 947 { 948 SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 949 if( !pObj ) 950 continue; 951 // OD 21.08.2003 #i18447# - no change of layer for controls 952 // or group objects containing controls. 953 // --> OD 2010-09-14 #i113730# 954 // consider that a member of a drawing group has been selected. 955 const SwContact* pContact = ::GetUserCall( pObj ); 956 ASSERT( pContact && pContact->GetMaster(), "<SwFEShell::ChangeOpaque(..)> - missing contact or missing master object at contact!" ); 957 const bool bControlObj = ( pContact && pContact->GetMaster() ) 958 ? ::CheckControlLayer( pContact->GetMaster() ) 959 : ::CheckControlLayer( pObj ); 960 // <-- 961 if ( !bControlObj && pObj->GetLayer() != nLayerId ) 962 { 963 pObj->SetLayer( nLayerId ); 964 InvalidateWindows( SwRect( pObj->GetCurrentBoundRect() ) ); 965 if ( pObj->ISA(SwVirtFlyDrawObj) ) 966 { 967 SwFmt *pFmt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt(); 968 SvxOpaqueItem aOpa( pFmt->GetOpaque() ); 969 aOpa.SetValue( nLayerId == pIDDMA->GetHellId() ); 970 pFmt->SetFmtAttr( aOpa ); 971 } 972 } 973 } 974 GetDoc()->SetModified(); 975 } 976 } 977 978 void SwFEShell::SelectionToHeaven() 979 { 980 ChangeOpaque( getIDocumentDrawModelAccess()->GetHeavenId() ); 981 } 982 983 void SwFEShell::SelectionToHell() 984 { 985 ChangeOpaque( getIDocumentDrawModelAccess()->GetHellId() ); 986 } 987 988 /************************************************************************* 989 |* 990 |* SwFEShell::IsObjSelected(), IsFrmSelected() 991 |* 992 *************************************************************************/ 993 994 sal_uInt16 SwFEShell::IsObjSelected() const 995 { 996 if ( IsFrmSelected() || !Imp()->HasDrawView() ) 997 return 0; 998 else 999 return sal_uInt16( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ); 1000 } 1001 1002 sal_Bool SwFEShell::IsFrmSelected() const 1003 { 1004 if ( !Imp()->HasDrawView() ) 1005 return sal_False; 1006 else 1007 return 0 != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(), 1008 (ViewShell*)this ); 1009 } 1010 1011 sal_Bool SwFEShell::IsObjSelected( const SdrObject& rObj ) const 1012 { 1013 if ( IsFrmSelected() || !Imp()->HasDrawView() ) 1014 return sal_False; 1015 else 1016 return Imp()->GetDrawView() 1017 ->IsObjMarked( const_cast< SdrObject * >( &rObj ) ); 1018 } 1019 1020 sal_Bool SwFEShell::IsObjSameLevelWithMarked(const SdrObject* pObj) const 1021 { 1022 if (pObj) 1023 { 1024 const SdrMarkList& aMarkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1025 if (aMarkList.GetMarkCount() == 0) 1026 { 1027 return sal_True; 1028 } 1029 SdrMark* pM=aMarkList.GetMark(0); 1030 if (pM) 1031 { 1032 SdrObject* pMarkObj = pM->GetMarkedSdrObj(); 1033 if (pMarkObj && pMarkObj->GetUpGroup() == pObj->GetUpGroup()) 1034 return sal_True; 1035 } 1036 } 1037 return sal_False; 1038 } 1039 /************************************************************************* 1040 |* 1041 |* SwFEShell::EndTextEdit() 1042 |* 1043 *************************************************************************/ 1044 1045 void SwFEShell::EndTextEdit() 1046 { 1047 //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt 1048 //keinen Text mehr enthaelt und keine Attribute traegt) wird das 1049 //Objekt gel�scht. Alle anderen markierten Objekte bleiben erhalten. 1050 1051 ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(), 1052 "EndTextEdit an no Object" ); 1053 1054 StartAllAction(); 1055 SdrView *pView = Imp()->GetDrawView(); 1056 SdrObject *pObj = pView->GetTextEditObject(); 1057 SdrObjUserCall* pUserCall; 1058 if( 0 != ( pUserCall = GetUserCall(pObj) ) ) 1059 { 1060 SdrObject *pTmp = ((SwContact*)pUserCall)->GetMaster(); 1061 if( !pTmp ) 1062 pTmp = pObj; 1063 pUserCall->Changed( *pTmp, SDRUSERCALL_RESIZE, pTmp->GetLastBoundRect() ); 1064 } 1065 if ( !pObj->GetUpGroup() ) 1066 { 1067 if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->SdrEndTextEdit(sal_True) ) 1068 { 1069 if ( pView->GetMarkedObjectList().GetMarkCount() > 1 ) 1070 { 1071 { 1072 SdrMarkList aSave( pView->GetMarkedObjectList() ); 1073 aSave.DeleteMark( aSave.FindObject( pObj ) ); 1074 if ( aSave.GetMarkCount() ) 1075 { 1076 pView->UnmarkAll(); 1077 pView->MarkObj( pObj, Imp()->GetPageView() ); 1078 } 1079 DelSelectedObj(); 1080 if ( aSave.GetMarkCount() ) 1081 { 1082 for ( sal_uInt16 i = 0; i < aSave.GetMarkCount(); ++i ) 1083 pView->MarkObj( aSave.GetMark( i )->GetMarkedSdrObj(), 1084 Imp()->GetPageView() ); 1085 } 1086 } 1087 } 1088 else 1089 DelSelectedObj(); 1090 } 1091 } 1092 else 1093 pView->SdrEndTextEdit(); 1094 EndAllAction(); 1095 } 1096 1097 /************************************************************************* 1098 |* 1099 |* SwFEShell::IsInsideSelectedObj() 1100 |* 1101 *************************************************************************/ 1102 1103 int SwFEShell::IsInsideSelectedObj( const Point &rPt ) 1104 { 1105 if( Imp()->HasDrawView() ) 1106 { 1107 SwDrawView *pDView = Imp()->GetDrawView(); 1108 1109 if( pDView->GetMarkedObjectList().GetMarkCount() && 1110 pDView->IsMarkedObjHit( rPt ) ) 1111 { 1112 return SDRHIT_OBJECT; 1113 } 1114 } 1115 return SDRHIT_NONE; 1116 } 1117 1118 /************************************************************************* 1119 |* 1120 |* SwFEShell::IsObjSelectable() 1121 |* 1122 *************************************************************************/ 1123 1124 bool SwFEShell::IsObjSelectable( const Point& rPt ) 1125 { 1126 SET_CURR_SHELL(this); 1127 #ifdef OLD 1128 if( Imp()->HasDrawView() ) 1129 return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE ); 1130 return 0; 1131 #else 1132 SwDrawView *pDView = Imp()->GetDrawView(); 1133 bool bRet = false; 1134 if( pDView ) 1135 { 1136 SdrObject* pObj; 1137 SdrPageView* pPV; 1138 sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 1139 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 ); 1140 1141 bRet = 0 != pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE ); 1142 pDView->SetHitTolerancePixel( nOld ); 1143 } 1144 return bRet; 1145 #endif 1146 } 1147 1148 // #107513# 1149 // Test if there is a object at that position and if it should be selected. 1150 sal_Bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) 1151 { 1152 SET_CURR_SHELL(this); 1153 SwDrawView *pDrawView = Imp()->GetDrawView(); 1154 sal_Bool bRet(sal_False); 1155 1156 if(pDrawView) 1157 { 1158 SdrObject* pObj; 1159 SdrPageView* pPV; 1160 sal_uInt16 nOld(pDrawView->GetHitTolerancePixel()); 1161 1162 pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2); 1163 bRet = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE); 1164 pDrawView->SetHitTolerancePixel(nOld); 1165 1166 if ( bRet && pObj ) 1167 { 1168 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess(); 1169 // --> OD 2009-12-30 #i89920# 1170 // Do not select object in background which is overlapping this text 1171 // at the given position. 1172 bool bObjInBackground( false ); 1173 { 1174 if ( pObj->GetLayer() == pIDDMA->GetHellId() ) 1175 { 1176 const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); 1177 const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); 1178 const SwFmtSurround& rSurround = rFmt.GetSurround(); 1179 if ( rSurround.GetSurround() == SURROUND_THROUGHT ) 1180 { 1181 bObjInBackground = true; 1182 } 1183 } 1184 } 1185 if ( bObjInBackground ) 1186 { 1187 const SwPageFrm* pPageFrm = GetLayout()->GetPageAtPos( rPt ); 1188 if( pPageFrm ) 1189 { 1190 const SwCntntFrm* pCntntFrm( pPageFrm->ContainsCntnt() ); 1191 while ( pCntntFrm ) 1192 { 1193 if ( pCntntFrm->UnionFrm().IsInside( rPt ) ) 1194 { 1195 const SwTxtFrm* pTxtFrm = 1196 dynamic_cast<const SwTxtFrm*>(pCntntFrm); 1197 if ( pTxtFrm ) 1198 { 1199 SwPosition* pPos = 1200 new SwPosition( *(pTxtFrm->GetTxtNode()) ); 1201 Point aTmpPt( rPt ); 1202 if ( pTxtFrm->GetKeyCrsrOfst( pPos, aTmpPt ) ) 1203 { 1204 SwRect aCursorCharRect; 1205 if ( pTxtFrm->GetCharRect( aCursorCharRect, *pPos ) ) 1206 { 1207 if ( aCursorCharRect.IsOver( SwRect( pObj->GetLastBoundRect() ) ) ) 1208 { 1209 bRet = sal_False; 1210 } 1211 } 1212 } 1213 } 1214 else 1215 { 1216 bRet = sal_False; 1217 } 1218 break; 1219 } 1220 1221 pCntntFrm = pCntntFrm->GetNextCntntFrm(); 1222 } 1223 } 1224 } 1225 // <-- 1226 1227 if ( bRet ) 1228 { 1229 const SdrPage* pPage = pIDDMA->GetDrawModel()->GetPage(0); 1230 for(sal_uInt32 a(pObj->GetOrdNum() + 1); bRet && a < pPage->GetObjCount(); a++) 1231 { 1232 SdrObject *pCandidate = pPage->GetObj(a); 1233 1234 if (pCandidate->ISA(SwVirtFlyDrawObj) && 1235 ( (SwVirtFlyDrawObj*)pCandidate)->GetCurrentBoundRect().IsInside(rPt) ) 1236 { 1237 bRet = sal_False; 1238 } 1239 } 1240 } 1241 } 1242 } 1243 1244 return bRet; 1245 } 1246 1247 /************************************************************************* 1248 |* 1249 |* SwFEShell::GotoObj() 1250 |* 1251 |* Beschreibung Wenn ein Obj selektiert ist, gehen wir von dessen 1252 |* TopLeft aus, andernfalls von der Mitte des aktuellen CharRects. 1253 |* 1254 *************************************************************************/ 1255 /* ------------------------------------ 1256 * Beinhaltet das Objekt ein Control oder Gruppen, 1257 * die nur aus Controls bestehen 1258 * --------------------------------------------------*/ 1259 sal_Bool lcl_IsControlGroup( const SdrObject *pObj ) 1260 { 1261 sal_Bool bRet = sal_False; 1262 if(pObj->ISA(SdrUnoObj)) 1263 bRet = sal_True; 1264 else if( pObj->ISA( SdrObjGroup ) ) 1265 { 1266 bRet = sal_True; 1267 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList(); 1268 for ( sal_uInt16 i = 0; i < pLst->GetObjCount(); ++i ) 1269 if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) ) 1270 return sal_False; 1271 } 1272 return bRet; 1273 } 1274 1275 namespace 1276 { 1277 class MarkableObjectsOnly : public ::svx::ISdrObjectFilter 1278 { 1279 public: 1280 MarkableObjectsOnly( SdrPageView* i_pPV ) 1281 :m_pPV( i_pPV ) 1282 { 1283 } 1284 1285 virtual bool includeObject( const SdrObject& i_rObject ) const 1286 { 1287 return m_pPV && m_pPV->GetView().IsObjMarkable( const_cast< SdrObject* >( &i_rObject ), m_pPV ); 1288 } 1289 1290 private: 1291 SdrPageView* m_pPV; 1292 }; 1293 } 1294 1295 const SdrObject* SwFEShell::GetBestObject( sal_Bool bNext, sal_uInt16 /*GOTOOBJ_...*/ eType, sal_Bool bFlat, const ::svx::ISdrObjectFilter* pFilter ) 1296 { 1297 if( !Imp()->HasDrawView() ) 1298 return NULL; 1299 1300 const SdrObject *pBest = 0, 1301 *pTop = 0; 1302 1303 const long nTmp = bNext ? LONG_MAX : 0; 1304 Point aBestPos( nTmp, nTmp ); 1305 Point aTopPos( nTmp, nTmp ); 1306 Point aCurPos; 1307 Point aPos; 1308 sal_Bool bNoDraw = 0 == (GOTOOBJ_DRAW_ANY & eType); 1309 sal_Bool bNoFly = 0 == (GOTOOBJ_FLY_ANY & eType); 1310 1311 if( !bNoFly && bNoDraw ) 1312 { 1313 SwFlyFrm *pFly = GetCurrFrm( sal_False )->FindFlyFrm(); 1314 if( pFly ) 1315 pBest = pFly->GetVirtDrawObj(); 1316 } 1317 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1318 SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView(); 1319 1320 MarkableObjectsOnly aDefaultFilter( pPV ); 1321 if ( !pFilter ) 1322 pFilter = &aDefaultFilter; 1323 1324 if( !pBest || rMrkList.GetMarkCount() == 1 ) 1325 { 1326 // Ausgangspunkt bestimmen. 1327 SdrObjList* pList = NULL; 1328 if ( rMrkList.GetMarkCount() ) 1329 { 1330 const SdrObject* pStartObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); 1331 if( pStartObj->ISA(SwVirtFlyDrawObj) ) 1332 aPos = ((SwVirtFlyDrawObj*)pStartObj)->GetFlyFrm()->Frm().Pos(); 1333 else 1334 aPos = pStartObj->GetSnapRect().TopLeft(); 1335 1336 // If an object inside a group is selected, we want to 1337 // iterate over the group members. 1338 if ( ! pStartObj->GetUserCall() ) 1339 pList = pStartObj->GetObjList(); 1340 } 1341 else 1342 { 1343 // If no object is selected, we check if we just entered a group. 1344 // In this case we want to iterate over the group members. 1345 aPos = GetCharRect().Center(); 1346 const SdrObject* pStartObj = pPV ? pPV->GetAktGroup() : 0; 1347 if ( pStartObj && pStartObj->ISA( SdrObjGroup ) ) 1348 pList = pStartObj->GetSubList(); 1349 } 1350 1351 if ( ! pList ) 1352 { 1353 // Here we are if 1354 // A No object has been selected and no group has been entered or 1355 // B An object has been selected and it is not inside a group 1356 pList = getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 ); 1357 } 1358 1359 1360 ASSERT( pList, "No object list to iterate" ) 1361 1362 SdrObjListIter aObjIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS ); 1363 while ( aObjIter.IsMore() ) 1364 { 1365 SdrObject* pObj = aObjIter.Next(); 1366 sal_Bool bFlyFrm = pObj->ISA(SwVirtFlyDrawObj); 1367 if( ( bNoFly && bFlyFrm ) || 1368 ( bNoDraw && !bFlyFrm ) || 1369 ( eType == GOTOOBJ_DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ) || 1370 ( eType == GOTOOBJ_DRAW_CONTROL && !lcl_IsControlGroup( pObj ) ) || 1371 ( pFilter && !pFilter->includeObject( *pObj ) ) ) 1372 continue; 1373 if( bFlyFrm ) 1374 { 1375 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pObj; 1376 SwFlyFrm *pFly = pO->GetFlyFrm(); 1377 if( GOTOOBJ_FLY_ANY != ( GOTOOBJ_FLY_ANY & eType ) ) 1378 { 1379 switch ( eType ) 1380 { 1381 case GOTOOBJ_FLY_FRM: 1382 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() ) 1383 continue; 1384 break; 1385 case GOTOOBJ_FLY_GRF: 1386 if ( pFly->Lower() && 1387 (pFly->Lower()->IsLayoutFrm() || 1388 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode())) 1389 continue; 1390 break; 1391 case GOTOOBJ_FLY_OLE: 1392 if ( pFly->Lower() && 1393 (pFly->Lower()->IsLayoutFrm() || 1394 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode())) 1395 continue; 1396 break; 1397 } 1398 } 1399 aCurPos = pFly->Frm().Pos(); 1400 } 1401 else 1402 aCurPos = pObj->GetCurrentBoundRect().TopLeft(); 1403 1404 // Sonderfall wenn ein anderes Obj auf selber Y steht. 1405 if( aCurPos != aPos && // nur wenn ich es nicht selber bin 1406 aCurPos.Y() == aPos.Y() && // ist die Y Position gleich 1407 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir 1408 (aCurPos.X() < aPos.X())) ) // " reverse 1409 { 1410 aBestPos = Point( nTmp, nTmp ); 1411 SdrObjListIter aTmpIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS ); 1412 while ( aTmpIter.IsMore() ) 1413 { 1414 SdrObject* pTmpObj = aTmpIter.Next(); 1415 bFlyFrm = pTmpObj->ISA(SwVirtFlyDrawObj); 1416 if( ( bNoFly && bFlyFrm ) || ( bNoDraw && !bFlyFrm ) ) 1417 continue; 1418 if( bFlyFrm ) 1419 { 1420 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pTmpObj; 1421 aCurPos = pO->GetFlyFrm()->Frm().Pos(); 1422 } 1423 else 1424 aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft(); 1425 1426 if( aCurPos != aPos && aCurPos.Y() == aPos.Y() && 1427 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir 1428 (aCurPos.X() < aPos.X())) && // " reverse 1429 (bNext? (aCurPos.X() < aBestPos.X()) : // besser als Beste 1430 (aCurPos.X() > aBestPos.X())) ) // " reverse 1431 { 1432 aBestPos = aCurPos; 1433 pBest = pTmpObj; 1434 } 1435 } 1436 break; 1437 } 1438 1439 if( ( 1440 (bNext? (aPos.Y() < aCurPos.Y()) : // nur unter mir 1441 (aPos.Y() > aCurPos.Y())) && // " reverse 1442 (bNext? (aBestPos.Y() > aCurPos.Y()) : // naeher drunter 1443 (aBestPos.Y() < aCurPos.Y())) 1444 ) || // " reverse 1445 (aBestPos.Y() == aCurPos.Y() && 1446 (bNext? (aBestPos.X() > aCurPos.X()) : // weiter links 1447 (aBestPos.X() < aCurPos.X())))) // " reverse 1448 1449 { 1450 aBestPos = aCurPos; 1451 pBest = pObj; 1452 } 1453 1454 if( (bNext? (aTopPos.Y() > aCurPos.Y()) : // hoeher als Beste 1455 (aTopPos.Y() < aCurPos.Y())) || // " reverse 1456 (aTopPos.Y() == aCurPos.Y() && 1457 (bNext? (aTopPos.X() > aCurPos.X()) : // weiter links 1458 (aTopPos.X() < aCurPos.X())))) // " reverse 1459 { 1460 aTopPos = aCurPos; 1461 pTop = pObj; 1462 } 1463 } 1464 // leider nichts gefunden 1465 if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) ) 1466 pBest = pTop; 1467 } 1468 1469 return pBest; 1470 } 1471 1472 sal_Bool SwFEShell::GotoObj( sal_Bool bNext, sal_uInt16 /*GOTOOBJ_...*/ eType ) 1473 { 1474 const SdrObject* pBest = GetBestObject( bNext, eType ); 1475 1476 if ( !pBest ) 1477 return sal_False; 1478 1479 sal_Bool bFlyFrm = pBest->ISA(SwVirtFlyDrawObj); 1480 if( bFlyFrm ) 1481 { 1482 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pBest; 1483 const SwRect& rFrm = pO->GetFlyFrm()->Frm(); 1484 SelectObj( rFrm.Pos(), 0, (SdrObject*)pBest ); 1485 if( !ActionPend() ) 1486 MakeVisible( rFrm ); 1487 } 1488 else 1489 { 1490 SelectObj( Point(), 0, (SdrObject*)pBest ); 1491 if( !ActionPend() ) 1492 MakeVisible( pBest->GetCurrentBoundRect() ); 1493 } 1494 CallChgLnk(); 1495 return sal_True; 1496 } 1497 1498 /************************************************************************* 1499 |* 1500 |* SwFEShell::BeginCreate() 1501 |* 1502 *************************************************************************/ 1503 1504 sal_Bool SwFEShell::BeginCreate( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, const Point &rPos ) 1505 { 1506 sal_Bool bRet = sal_False; 1507 1508 if ( !Imp()->HasDrawView() ) 1509 Imp()->MakeDrawView(); 1510 1511 if ( GetPageNumber( rPos ) ) 1512 { 1513 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind ); 1514 if ( eSdrObjectKind == OBJ_CAPTION ) 1515 bRet = Imp()->GetDrawView()->BegCreateCaptionObj( 1516 rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ), 1517 GetOut() ); 1518 else 1519 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() ); 1520 } 1521 if ( bRet ) 1522 { 1523 ::FrameNotify( this, FLY_DRAG_START ); 1524 } 1525 return bRet; 1526 } 1527 1528 sal_Bool SwFEShell::BeginCreate( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, sal_uInt32 eObjInventor, 1529 const Point &rPos ) 1530 { 1531 sal_Bool bRet = sal_False; 1532 1533 if ( !Imp()->HasDrawView() ) 1534 Imp()->MakeDrawView(); 1535 1536 if ( GetPageNumber( rPos ) ) 1537 { 1538 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor ); 1539 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() ); 1540 } 1541 if ( bRet ) 1542 ::FrameNotify( this, FLY_DRAG_START ); 1543 return bRet; 1544 } 1545 1546 /************************************************************************* 1547 |* 1548 |* SwFEShell::MoveCreate() 1549 |* 1550 *************************************************************************/ 1551 1552 void SwFEShell::MoveCreate( const Point &rPos ) 1553 { 1554 ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" ); 1555 if ( GetPageNumber( rPos ) ) 1556 { 1557 ScrollTo( rPos ); 1558 Imp()->GetDrawView()->MovCreateObj( rPos ); 1559 ::FrameNotify( this, FLY_DRAG ); 1560 } 1561 } 1562 1563 /************************************************************************* 1564 |* 1565 |* SwFEShell::EndCreate(), ImpEndCreate() 1566 |* 1567 *************************************************************************/ 1568 1569 sal_Bool SwFEShell::EndCreate( sal_uInt16 eSdrCreateCmd ) 1570 { 1571 // Damit das Undo-Object aus der DrawEngine nicht bei uns 1572 // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz 1573 // das Undo abschalten 1574 ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" ); 1575 if( !Imp()->GetDrawView()->IsGroupEntered() ) 1576 { 1577 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); 1578 } 1579 sal_Bool bCreate = Imp()->GetDrawView()->EndCreateObj( 1580 SdrCreateCmd( eSdrCreateCmd ) ); 1581 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true); 1582 1583 if ( !bCreate ) 1584 { 1585 ::FrameNotify( this, FLY_DRAG_END ); 1586 return sal_False; 1587 } 1588 1589 if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT ) 1590 { 1591 ::FrameNotify( this, FLY_DRAG ); 1592 return sal_True; 1593 } 1594 return ImpEndCreate(); 1595 } 1596 1597 1598 sal_Bool SwFEShell::ImpEndCreate() 1599 { 1600 ASSERT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1, 1601 "Neues Object nicht selektiert." ); 1602 1603 SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 1604 1605 if( rSdrObj.GetSnapRect().IsEmpty() ) 1606 { 1607 // das Object vergessen wir lieber, fuerht nur 1608 // zu Problemen 1609 Imp()->GetDrawView()->DeleteMarked(); 1610 Imp()->GetDrawView()->UnmarkAll(); 1611 ::FrameNotify( this, FLY_DRAG_END ); 1612 return sal_False; 1613 } 1614 1615 if( rSdrObj.GetUpGroup() ) 1616 { 1617 Point aTmpPos( rSdrObj.GetSnapRect().TopLeft() ); 1618 Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() ); 1619 // OD 2004-04-05 #i26791# - direct object positioning for group members 1620 rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor ); 1621 rSdrObj.NbcSetAnchorPos( aNewAnchor ); 1622 ::FrameNotify( this, FLY_DRAG ); 1623 return sal_True; 1624 } 1625 1626 LockPaint(); 1627 StartAllAction(); 1628 1629 Imp()->GetDrawView()->UnmarkAll(); 1630 1631 const Rectangle &rBound = rSdrObj.GetSnapRect(); 1632 Point aPt( rBound.TopRight() ); 1633 1634 //Fremde Identifier sollen in den Default laufen. 1635 //Ueberschneidungen sind moeglich!! 1636 sal_uInt16 nIdent = SdrInventor == rSdrObj.GetObjInventor() 1637 ? rSdrObj.GetObjIdentifier() 1638 : 0xFFFF; 1639 1640 //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst. 1641 SwFmtAnchor aAnch; 1642 const SwFrm *pAnch = 0; 1643 sal_Bool bCharBound = sal_False; 1644 if( rSdrObj.ISA( SdrUnoObj ) ) 1645 { 1646 SwPosition aPos( GetDoc()->GetNodes() ); 1647 SwCrsrMoveState aState( MV_SETONLYTEXT ); 1648 Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 ); 1649 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState ); //swmod 080317 1650 1651 //Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt 1652 if( !aPos.nNode.GetNode().IsProtect() ) 1653 { 1654 pAnch = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPoint, &aPos ); 1655 SwRect aTmp; 1656 pAnch->GetCharRect( aTmp, aPos ); 1657 1658 //Der Crsr darf nicht zu weit entfernt sein. 1659 bCharBound = sal_True; 1660 Rectangle aRect( aTmp.SVRect() ); 1661 aRect.Left() -= MM50*2; 1662 aRect.Top() -= MM50*2; 1663 aRect.Right() += MM50*2; 1664 aRect.Bottom()+= MM50*2; 1665 1666 if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() )) 1667 bCharBound = sal_False; 1668 1669 //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt. 1670 if( bCharBound ) 1671 bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode ); 1672 1673 if( bCharBound ) 1674 { 1675 aAnch.SetType( FLY_AS_CHAR ); 1676 aAnch.SetAnchor( &aPos ); 1677 } 1678 } 1679 } 1680 1681 if( !bCharBound ) 1682 { 1683 // OD 16.05.2003 #108784# - allow native drawing objects in header/footer. 1684 // Thus, set <bBodyOnly> to <false> for these objects using value 1685 // of <nIdent> - value <0xFFFF> indicates control objects, which aren't 1686 // allowed in header/footer. 1687 //bool bBodyOnly = OBJ_NONE != nIdent; 1688 bool bBodyOnly = 0xFFFF == nIdent; 1689 bool bAtPage = false; 1690 const SwFrm* pPage = 0; 1691 SwCrsrMoveState aState( MV_SETONLYTEXT ); 1692 Point aPoint( aPt ); 1693 SwPosition aPos( GetDoc()->GetNodes() ); 1694 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState ); 1695 1696 //nicht in ReadnOnly-Inhalt setzen 1697 if( aPos.nNode.GetNode().IsProtect() ) 1698 // dann darf er nur seitengebunden sein. Oder sollte man 1699 // die naechste nicht READONLY Position suchen? 1700 bAtPage = true; 1701 1702 pAnch = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPoint, 0, sal_False ); 1703 1704 if( !bAtPage ) 1705 { 1706 const SwFlyFrm *pTmp = pAnch->FindFlyFrm(); 1707 if( pTmp ) 1708 { 1709 const SwFrm* pTmpFrm = pAnch; 1710 SwRect aBound( rBound ); 1711 while( pTmp ) 1712 { 1713 if( pTmp->Frm().IsInside( aBound ) ) 1714 { 1715 if( !bBodyOnly || !pTmp->FindFooterOrHeader() ) 1716 pPage = pTmpFrm; 1717 break; 1718 } 1719 pTmp = pTmp->GetAnchorFrm() 1720 ? pTmp->GetAnchorFrm()->FindFlyFrm() 1721 : 0; 1722 pTmpFrm = pTmp; 1723 } 1724 } 1725 1726 if( !pPage ) 1727 pPage = pAnch->FindPageFrm(); 1728 1729 // immer ueber FindAnchor gehen, damit der Frame immer an den 1730 // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum 1731 // nachfolgenden kommen. DAS IST FALSCH 1732 pAnch = ::FindAnchor( pPage, aPt, bBodyOnly ); 1733 aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode(); 1734 1735 //nicht in ReadnOnly-Inhalt setzen 1736 if( aPos.nNode.GetNode().IsProtect() ) 1737 // dann darf er nur seitengebunden sein. Oder sollte man 1738 // die naechste nicht READONLY Position suchen? 1739 bAtPage = true; 1740 else 1741 { 1742 aAnch.SetType( FLY_AT_PARA ); 1743 aAnch.SetAnchor( &aPos ); 1744 } 1745 } 1746 1747 if( bAtPage ) 1748 { 1749 pPage = pAnch->FindPageFrm(); 1750 1751 aAnch.SetType( FLY_AT_PAGE ); 1752 aAnch.SetPageNum( pPage->GetPhyPageNum() ); 1753 pAnch = pPage; // die Page wird jetzt zum Anker 1754 } 1755 } 1756 1757 SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 1758 RES_SURROUND, RES_ANCHOR, 0 ); 1759 aSet.Put( aAnch ); 1760 1761 // OD 2004-03-30 #i26791# - determine relative object position 1762 SwTwips nXOffset; 1763 SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top(); 1764 { 1765 if( pAnch->IsVertical() ) 1766 { 1767 nXOffset = nYOffset; 1768 nYOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right(); 1769 } 1770 else if( pAnch->IsRightToLeft() ) 1771 nXOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right(); 1772 else 1773 nXOffset = rBound.Left() - pAnch->Frm().Left(); 1774 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() ) 1775 { 1776 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch; 1777 do { 1778 pTmp = pTmp->FindMaster(); 1779 ASSERT( pTmp, "Where's my Master?" ); 1780 // OD 2004-03-30 #i26791# - correction: add frame area height 1781 // of master frames. 1782 nYOffset += pTmp->IsVertical() ? 1783 pTmp->Frm().Width() : pTmp->Frm().Height(); 1784 } while ( pTmp->IsFollow() ); 1785 } 1786 } 1787 1788 if( OBJ_NONE == nIdent ) 1789 { 1790 //Bei OBJ_NONE wird ein Fly eingefuegt. 1791 const long nWidth = rBound.Right() - rBound.Left(); 1792 const long nHeight= rBound.Bottom() - rBound.Top(); 1793 aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth, long(MINFLY) ), 1794 Max( nHeight, long(MINFLY) ))); 1795 1796 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME ); 1797 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME ); 1798 aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) ); 1799 aSet.Put( aHori ); 1800 aSet.Put( aVert ); 1801 1802 //Schnell noch das Rechteck merken 1803 const SwRect aFlyRect( rBound ); 1804 1805 //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten 1806 //ueber vorhandene SS erzeugt werden. 1807 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); // see above 1808 // --> OD 2005-08-08 #i52858# - method name changed 1809 SdrPage *pPg = getIDocumentDrawModelAccess()->GetOrCreateDrawModel()->GetPage( 0 ); 1810 // <-- 1811 if( !pPg ) 1812 { 1813 SdrModel* pTmpSdrModel = getIDocumentDrawModelAccess()->GetDrawModel(); 1814 pPg = pTmpSdrModel->AllocPage( sal_False ); 1815 pTmpSdrModel->InsertPage( pPg ); 1816 } 1817 pPg->RecalcObjOrdNums(); 1818 SdrObject* pRemovedObject = pPg->RemoveObject( rSdrObj.GetOrdNumDirect() ); 1819 SdrObject::Free( pRemovedObject ); 1820 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true); 1821 1822 SwFlyFrm* pFlyFrm; 1823 if( NewFlyFrm( aSet, sal_True ) && 1824 ::GetHtmlMode( GetDoc()->GetDocShell() ) && 1825 0 != ( pFlyFrm = FindFlyFrm() )) 1826 { 1827 SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT ); 1828 //Horizontale Ausrichtung: 1829 const sal_Bool bLeftFrm = aFlyRect.Left() < 1830 pAnch->Frm().Left() + pAnch->Prt().Left(), 1831 bLeftPrt = aFlyRect.Left() + aFlyRect.Width() < 1832 pAnch->Frm().Left() + pAnch->Prt().Width()/2; 1833 if( bLeftFrm || bLeftPrt ) 1834 { 1835 aHori.SetHoriOrient( text::HoriOrientation::LEFT ); 1836 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); 1837 } 1838 else 1839 { 1840 const sal_Bool bRightFrm = aFlyRect.Left() > 1841 pAnch->Frm().Left() + pAnch->Prt().Width(); 1842 aHori.SetHoriOrient( text::HoriOrientation::RIGHT ); 1843 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); 1844 } 1845 aHtmlSet.Put( aHori ); 1846 aVert.SetVertOrient( text::VertOrientation::TOP ); 1847 aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA ); 1848 aHtmlSet.Put( aVert ); 1849 1850 GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() ); 1851 } 1852 } 1853 else 1854 { 1855 Point aRelNullPt; 1856 if( OBJ_CAPTION == nIdent ) 1857 aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos(); 1858 else 1859 aRelNullPt = rBound.TopLeft(); 1860 1861 aSet.Put( aAnch ); 1862 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) ); 1863 // OD 2004-03-30 #i26791# - set horizontal position 1864 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME ); 1865 aSet.Put( aHori ); 1866 // OD 2004-03-30 #i26791# - set vertical position 1867 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() ) 1868 { 1869 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch; 1870 do { 1871 pTmp = pTmp->FindMaster(); 1872 ASSERT( pTmp, "Where's my Master?" ); 1873 nYOffset += pTmp->IsVertical() ? 1874 pTmp->Prt().Width() : pTmp->Prt().Height(); 1875 } while ( pTmp->IsFollow() ); 1876 } 1877 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME ); 1878 aSet.Put( aVert ); 1879 SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet ); 1880 // --> OD 2004-10-25 #i36010# - set layout direction of the position 1881 pFmt->SetPositionLayoutDir( 1882 text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); 1883 // <-- 1884 // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set 1885 pFmt->PosAttrSet(); 1886 // <-- 1887 1888 SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj ); 1889 // --> OD 2004-11-22 #i35635# 1890 pContact->MoveObjToVisibleLayer( &rSdrObj ); 1891 // <-- 1892 if( bCharBound ) 1893 { 1894 ASSERT( aAnch.GetAnchorId() == FLY_AS_CHAR, "wrong AnchorType" ); 1895 SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode(); 1896 SwFmtFlyCnt aFmt( pFmt ); 1897 pNd->InsertItem(aFmt, 1898 aAnch.GetCntntAnchor()->nContent.GetIndex(), 0 ); 1899 SwFmtVertOrient aVertical( pFmt->GetVertOrient() ); 1900 aVertical.SetVertOrient( text::VertOrientation::LINE_CENTER ); 1901 pFmt->SetFmtAttr( aVertical ); 1902 } 1903 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() ) 1904 { 1905 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch; 1906 do { 1907 pTmp = pTmp->FindMaster(); 1908 ASSERT( pTmp, "Where's my Master?" ); 1909 } while( pTmp->IsFollow() ); 1910 pAnch = pTmp; 1911 } 1912 1913 pContact->ConnectToLayout(); 1914 1915 // OD 25.06.2003 #108784# - mark object at frame the object is inserted at. 1916 { 1917 SdrObject* pMarkObj = pContact->GetDrawObjectByAnchorFrm( *pAnch ); 1918 if ( pMarkObj ) 1919 { 1920 Imp()->GetDrawView()->MarkObj( pMarkObj, Imp()->GetPageView(), 1921 sal_False, sal_False ); 1922 } 1923 else 1924 { 1925 Imp()->GetDrawView()->MarkObj( &rSdrObj, Imp()->GetPageView(), 1926 sal_False, sal_False ); 1927 } 1928 } 1929 } 1930 1931 GetDoc()->SetModified(); 1932 1933 KillPams(); 1934 EndAllActionAndCall(); 1935 UnlockPaint(); 1936 return sal_True; 1937 } 1938 1939 1940 /************************************************************************* 1941 |* 1942 |* SwFEShell::BreakCreate() 1943 |* 1944 *************************************************************************/ 1945 1946 void SwFEShell::BreakCreate() 1947 { 1948 ASSERT( Imp()->HasDrawView(), "BreakCreate without DrawView?" ); 1949 Imp()->GetDrawView()->BrkCreateObj(); 1950 ::FrameNotify( this, FLY_DRAG_END ); 1951 } 1952 1953 /************************************************************************* 1954 |* 1955 |* SwFEShell::IsDrawCreate() 1956 |* 1957 *************************************************************************/ 1958 1959 sal_Bool SwFEShell::IsDrawCreate() const 1960 { 1961 return Imp()->HasDrawView() ? Imp()->GetDrawView()->IsCreateObj() : sal_False; 1962 } 1963 1964 /************************************************************************* 1965 |* 1966 |* SwFEShell::BeginMark() 1967 |* 1968 *************************************************************************/ 1969 1970 sal_Bool SwFEShell::BeginMark( const Point &rPos ) 1971 { 1972 if ( !Imp()->HasDrawView() ) 1973 Imp()->MakeDrawView(); 1974 1975 if ( GetPageNumber( rPos ) ) 1976 { 1977 SwDrawView* pDView = Imp()->GetDrawView(); 1978 1979 if (pDView->HasMarkablePoints()) 1980 return pDView->BegMarkPoints( rPos ); 1981 else 1982 return pDView->BegMarkObj( rPos ); 1983 } 1984 else 1985 return sal_False; 1986 } 1987 1988 /************************************************************************* 1989 |* 1990 |* SwFEShell::MoveMark() 1991 |* 1992 *************************************************************************/ 1993 1994 void SwFEShell::MoveMark( const Point &rPos ) 1995 { 1996 ASSERT( Imp()->HasDrawView(), "MoveMark without DrawView?" ); 1997 1998 if ( GetPageNumber( rPos ) ) 1999 { 2000 ScrollTo( rPos ); 2001 SwDrawView* pDView = Imp()->GetDrawView(); 2002 // Imp()->GetDrawView()->MovMarkObj( rPos ); 2003 2004 if (pDView->IsInsObjPoint()) 2005 pDView->MovInsObjPoint( rPos ); 2006 else if (pDView->IsMarkPoints()) 2007 pDView->MovMarkPoints( rPos ); 2008 else 2009 pDView->MovAction( rPos ); 2010 } 2011 } 2012 2013 /************************************************************************* 2014 |* 2015 |* SwFEShell::EndMark() 2016 |* 2017 *************************************************************************/ 2018 2019 sal_Bool SwFEShell::EndMark() 2020 { 2021 sal_Bool bRet = sal_False; 2022 ASSERT( Imp()->HasDrawView(), "EndMark without DrawView?" ); 2023 2024 if (Imp()->GetDrawView()->IsMarkObj()) 2025 { 2026 bRet = Imp()->GetDrawView()->EndMarkObj(); 2027 2028 if ( bRet ) 2029 { 2030 sal_Bool bShowHdl = sal_False; 2031 SwDrawView* pDView = Imp()->GetDrawView(); 2032 //Rahmen werden auf diese Art nicht Selektiert, es sein denn es 2033 //ist nur ein Rahmen. 2034 SdrMarkList &rMrkList = (SdrMarkList&)pDView->GetMarkedObjectList(); 2035 SwFlyFrm* pOldSelFly = ::GetFlyFromMarked( &rMrkList, this ); 2036 2037 if ( rMrkList.GetMarkCount() > 1 ) 2038 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2039 { 2040 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2041 if( pObj->ISA(SwVirtFlyDrawObj) ) 2042 { 2043 if ( !bShowHdl ) 2044 { 2045 //HMHpDView->HideMarkHdl(); 2046 bShowHdl = sal_True; 2047 } 2048 rMrkList.DeleteMark( i ); 2049 --i; //keinen auslassen. 2050 } 2051 } 2052 2053 if( bShowHdl ) 2054 { 2055 pDView->MarkListHasChanged(); 2056 pDView->AdjustMarkHdl(); 2057 //HMHpDView->ShowMarkHdl(); 2058 } 2059 2060 if ( rMrkList.GetMarkCount() ) 2061 ::lcl_GrabCursor(this, pOldSelFly); 2062 else 2063 bRet = sal_False; 2064 } 2065 if ( bRet ) 2066 ::FrameNotify( this, FLY_DRAG_START ); 2067 } 2068 else 2069 { 2070 if (Imp()->GetDrawView()->IsMarkPoints()) 2071 bRet = Imp()->GetDrawView()->EndMarkPoints(); 2072 } 2073 2074 SetChainMarker(); 2075 return bRet; 2076 } 2077 2078 /************************************************************************* 2079 |* 2080 |* SwFEShell::BreakSelect() 2081 |* 2082 *************************************************************************/ 2083 2084 void SwFEShell::BreakMark() 2085 { 2086 ASSERT( Imp()->HasDrawView(), "BreakMark without DrawView?" ); 2087 Imp()->GetDrawView()->BrkMarkObj(); 2088 } 2089 2090 /************************************************************************* 2091 |* 2092 |* SwFEShell::GetAnchorId() 2093 |* 2094 *************************************************************************/ 2095 2096 short SwFEShell::GetAnchorId() const 2097 { 2098 short nRet = SHRT_MAX; 2099 if ( Imp()->HasDrawView() ) 2100 { 2101 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2102 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2103 { 2104 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2105 if ( pObj->ISA(SwVirtFlyDrawObj) ) 2106 { 2107 nRet = -1; 2108 break; 2109 } 2110 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 2111 short nId = static_cast<short>(pContact->GetFmt()->GetAnchor().GetAnchorId()); 2112 if ( nRet == SHRT_MAX ) 2113 nRet = nId; 2114 else if ( nRet != nId ) 2115 { 2116 nRet = -1; 2117 break; 2118 } 2119 } 2120 } 2121 if ( nRet == SHRT_MAX ) 2122 nRet = -1; 2123 return nRet; 2124 } 2125 2126 /************************************************************************* 2127 |* 2128 |* SwFEShell::ChgAnchor() 2129 |* 2130 *************************************************************************/ 2131 2132 void SwFEShell::ChgAnchor( int eAnchorId, sal_Bool bSameOnly, sal_Bool bPosCorr ) 2133 { 2134 ASSERT( Imp()->HasDrawView(), "ChgAnchor without DrawView?" ); 2135 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2136 if( rMrkList.GetMarkCount() && 2137 !rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() ) 2138 { 2139 StartAllAction(); 2140 2141 if( GetDoc()->ChgAnchor( rMrkList, (RndStdIds)eAnchorId, bSameOnly, bPosCorr )) 2142 Imp()->GetDrawView()->UnmarkAll(); 2143 2144 EndAllAction(); 2145 2146 ::FrameNotify( this, FLY_DRAG ); 2147 } 2148 } 2149 2150 /************************************************************************* 2151 |* 2152 |* SwFEShell::DelSelectedObj() 2153 |* 2154 *************************************************************************/ 2155 2156 void SwFEShell::DelSelectedObj() 2157 { 2158 ASSERT( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" ); 2159 if ( Imp()->HasDrawView() ) 2160 { 2161 StartAllAction(); 2162 Imp()->GetDrawView()->DeleteMarked(); 2163 EndAllAction(); 2164 ::FrameNotify( this, FLY_DRAG_END ); 2165 } 2166 } 2167 2168 /************************************************************************* 2169 |* 2170 |* SwFEShell::GetObjSize(), GetAnchorObjDiff() 2171 |* 2172 |* Beschreibung Fuer die Statuszeile zum Erfragen der aktuellen 2173 |* Verhaeltnisse 2174 |* 2175 *************************************************************************/ 2176 2177 Size SwFEShell::GetObjSize() const 2178 { 2179 Rectangle aRect; 2180 if ( Imp()->HasDrawView() ) 2181 { 2182 if ( Imp()->GetDrawView()->IsAction() ) 2183 Imp()->GetDrawView()->TakeActionRect( aRect ); 2184 else 2185 aRect = Imp()->GetDrawView()->GetAllMarkedRect(); 2186 } 2187 return aRect.GetSize(); 2188 } 2189 2190 Point SwFEShell::GetAnchorObjDiff() const 2191 { 2192 const SdrView *pView = Imp()->GetDrawView(); 2193 ASSERT( pView, "GetAnchorObjDiff without DrawView?" ); 2194 2195 Rectangle aRect; 2196 if ( Imp()->GetDrawView()->IsAction() ) 2197 Imp()->GetDrawView()->TakeActionRect( aRect ); 2198 else 2199 aRect = Imp()->GetDrawView()->GetAllMarkedRect(); 2200 2201 Point aRet( aRect.TopLeft() ); 2202 2203 if ( IsFrmSelected() ) 2204 { 2205 SwFlyFrm *pFly = FindFlyFrm(); 2206 aRet -= pFly->GetAnchorFrm()->Frm().Pos(); 2207 } 2208 else 2209 { 2210 const SdrObject *pObj = pView->GetMarkedObjectList().GetMarkCount() == 1 ? 2211 pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj() : 0; 2212 if ( pObj ) 2213 aRet -= pObj->GetAnchorPos(); 2214 } 2215 2216 return aRet; 2217 } 2218 2219 Point SwFEShell::GetObjAbsPos() const 2220 { 2221 ASSERT( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" ); 2222 return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft(); 2223 } 2224 2225 2226 2227 /************************************************************************* 2228 |* 2229 |* SwFEShell::IsGroupSelected() 2230 |* 2231 *************************************************************************/ 2232 2233 sal_Bool SwFEShell::IsGroupSelected() 2234 { 2235 if ( IsObjSelected() ) 2236 { 2237 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2238 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2239 { 2240 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2241 // OD 30.06.2003 #108784# - consider 'virtual' drawing objects. 2242 // Thus, use corresponding method instead of checking type. 2243 if ( pObj->IsGroupObject() && 2244 // --> FME 2004-12-08 #i38505# No ungroup allowed for 3d objects 2245 !pObj->Is3DObj() && 2246 // <-- 2247 FLY_AS_CHAR != ((SwDrawContact*)GetUserCall(pObj))-> 2248 GetFmt()->GetAnchor().GetAnchorId() ) 2249 { 2250 return sal_True; 2251 } 2252 } 2253 } 2254 return sal_False; 2255 } 2256 2257 // OD 27.06.2003 #108784# - change return type. 2258 // OD 27.06.2003 #108784# - adjustments for drawing objects in header/footer: 2259 // allow group, only if all selected objects are in the same header/footer 2260 // or not in header/footer. 2261 bool SwFEShell::IsGroupAllowed() const 2262 { 2263 bool bIsGroupAllowed = false; 2264 if ( IsObjSelected() > 1 ) 2265 { 2266 bIsGroupAllowed = true; 2267 const SdrObject* pUpGroup = 0L; 2268 const SwFrm* pHeaderFooterFrm = 0L; 2269 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2270 for ( sal_uInt16 i = 0; bIsGroupAllowed && i < rMrkList.GetMarkCount(); ++i ) 2271 { 2272 const SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2273 if ( i ) 2274 bIsGroupAllowed = pObj->GetUpGroup() == pUpGroup; 2275 else 2276 pUpGroup = pObj->GetUpGroup(); 2277 2278 if ( bIsGroupAllowed ) 2279 { 2280 SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) ); 2281 if ( !pFrmFmt ) 2282 { 2283 ASSERT( false, 2284 "<SwFEShell::IsGroupAllowed()> - missing frame format" ); 2285 bIsGroupAllowed = false; 2286 } 2287 else if ( FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() ) 2288 { 2289 bIsGroupAllowed = false; 2290 } 2291 } 2292 2293 // OD 27.06.2003 #108784# - check, if all selected objects are in the 2294 // same header/footer or not in header/footer. 2295 if ( bIsGroupAllowed ) 2296 { 2297 const SwFrm* pAnchorFrm = 0L; 2298 if ( pObj->ISA(SwVirtFlyDrawObj) ) 2299 { 2300 const SwFlyFrm* pFlyFrm = 2301 static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm(); 2302 if ( pFlyFrm ) 2303 { 2304 pAnchorFrm = pFlyFrm->GetAnchorFrm(); 2305 } 2306 } 2307 else 2308 { 2309 SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall( pObj )); 2310 if ( pDrawContact ) 2311 { 2312 pAnchorFrm = pDrawContact->GetAnchorFrm( pObj ); 2313 } 2314 } 2315 if ( pAnchorFrm ) 2316 { 2317 if ( i ) 2318 { 2319 bIsGroupAllowed = 2320 ( pAnchorFrm->FindFooterOrHeader() == pHeaderFooterFrm ); 2321 } 2322 else 2323 { 2324 pHeaderFooterFrm = pAnchorFrm->FindFooterOrHeader(); 2325 } 2326 } 2327 } 2328 2329 } 2330 } 2331 2332 return bIsGroupAllowed; 2333 } 2334 2335 /************************************************************************* 2336 |* 2337 |* SwFEShell::GroupSelection() 2338 |* 2339 |* Beschreibung Die Gruppe bekommt den Anker und das Contactobjekt 2340 |* des ersten in der Selektion 2341 |* 2342 *************************************************************************/ 2343 2344 void SwFEShell::GroupSelection() 2345 { 2346 if ( IsGroupAllowed() ) 2347 { 2348 StartAllAction(); 2349 StartUndo( UNDO_START ); 2350 2351 GetDoc()->GroupSelection( *Imp()->GetDrawView() ); 2352 2353 EndUndo( UNDO_END ); 2354 EndAllAction(); 2355 } 2356 } 2357 2358 /************************************************************************* 2359 |* 2360 |* SwFEShell::UnGroupSelection() 2361 |* 2362 |* Beschreibung Die Einzelobjekte bekommen eine Kopie vom Anker und 2363 |* Contactobjekt der Gruppe. 2364 |* 2365 *************************************************************************/ 2366 2367 void SwFEShell::UnGroupSelection() 2368 { 2369 if ( IsGroupSelected() ) 2370 { 2371 StartAllAction(); 2372 StartUndo( UNDO_START ); 2373 2374 GetDoc()->UnGroupSelection( *Imp()->GetDrawView() ); 2375 2376 EndUndo( UNDO_END ); 2377 EndAllAction(); 2378 } 2379 } 2380 2381 /************************************************************************* 2382 |* 2383 |* SwFEShell::MirrorSelection() 2384 |* 2385 *************************************************************************/ 2386 2387 void SwFEShell::MirrorSelection( sal_Bool bHorizontal ) 2388 { 2389 SdrView *pView = Imp()->GetDrawView(); 2390 if ( IsObjSelected() && pView->IsMirrorAllowed() ) 2391 { 2392 if ( bHorizontal ) 2393 pView->MirrorAllMarkedHorizontal(); 2394 else 2395 pView->MirrorAllMarkedVertical(); 2396 } 2397 } 2398 2399 // springe zum benannten Rahmen (Grafik/OLE) 2400 2401 sal_Bool SwFEShell::GotoFly( const String& rName, FlyCntType eType, sal_Bool bSelFrm ) 2402 { 2403 sal_Bool bRet = sal_False; 2404 static sal_uInt8 __READONLY_DATA aChkArr[ 4 ] = { 2405 /* FLYCNTTYPE_ALL */ 0, 2406 /* FLYCNTTYPE_FRM */ ND_TEXTNODE, 2407 /* FLYCNTTYPE_GRF */ ND_GRFNODE, 2408 /* FLYCNTTYPE_OLE */ ND_OLENODE 2409 }; 2410 2411 const SwFlyFrmFmt* pFlyFmt = pDoc->FindFlyByName( rName, aChkArr[ eType]); 2412 if( pFlyFmt ) 2413 { 2414 SET_CURR_SHELL( this ); 2415 2416 SwFlyFrm* pFrm = SwIterator<SwFlyFrm,SwFmt>::FirstElement( *pFlyFmt ); 2417 if( pFrm ) 2418 { 2419 if( bSelFrm ) 2420 { 2421 SelectObj( pFrm->Frm().Pos(), 0, pFrm->GetVirtDrawObj() ); 2422 if( !ActionPend() ) 2423 MakeVisible( pFrm->Frm() ); 2424 } 2425 else 2426 { 2427 // --> OD 2004-06-11 #i28701# - no format here 2428 // pFrm->GetAnchorFrm()->Calc(); 2429 SwCntntFrm *pCFrm = pFrm->ContainsCntnt(); 2430 if ( pCFrm ) 2431 { 2432 SwCntntNode *pCNode = pCFrm->GetNode(); 2433 ClearMark(); 2434 SwPaM* pCrsr = GetCrsr(); 2435 2436 pCrsr->GetPoint()->nNode = *pCNode; 2437 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 ); 2438 2439 SwRect& rChrRect = (SwRect&)GetCharRect(); 2440 rChrRect = pFrm->Prt(); 2441 rChrRect.Pos() += pFrm->Frm().Pos(); 2442 GetCrsrDocPos() = rChrRect.Pos(); 2443 } 2444 } 2445 bRet = sal_True; 2446 } 2447 } 2448 return bRet; 2449 } 2450 2451 sal_uInt16 SwFEShell::GetFlyCount( FlyCntType eType ) const 2452 { 2453 return GetDoc()->GetFlyCount(eType); 2454 } 2455 2456 2457 const SwFrmFmt* SwFEShell::GetFlyNum(sal_uInt16 nIdx, FlyCntType eType ) const 2458 { 2459 return GetDoc()->GetFlyNum(nIdx, eType ); 2460 } 2461 2462 // zeige das akt. selektierte "Object" an 2463 void SwFEShell::MakeSelVisible() 2464 { 2465 if( Imp()->HasDrawView() && 2466 Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) 2467 { 2468 MakeVisible( Imp()->GetDrawView()->GetAllMarkedRect() ); 2469 } 2470 else 2471 SwCrsrShell::MakeSelVisible(); 2472 } 2473 2474 2475 //Welcher Schutz ist am selektierten Objekt gesetzt? 2476 sal_uInt8 SwFEShell::IsSelObjProtected( sal_uInt16 eType ) const 2477 { 2478 int nChk = 0; 2479 const bool bParent = (eType & FLYPROTECT_PARENT); 2480 if( Imp()->HasDrawView() ) 2481 { 2482 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2483 for( sal_uLong i = rMrkList.GetMarkCount(); i; ) 2484 { 2485 SdrObject *pObj = rMrkList.GetMark( --i )->GetMarkedSdrObj(); 2486 if( !bParent ) 2487 { 2488 nChk |= ( pObj->IsMoveProtect() ? FLYPROTECT_POS : 0 ) | 2489 ( pObj->IsResizeProtect()? FLYPROTECT_SIZE : 0 ); 2490 2491 if( pObj->ISA(SwVirtFlyDrawObj) ) 2492 { 2493 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 2494 if ( (FLYPROTECT_CONTENT & eType) && pFly->GetFmt()->GetProtect().IsCntntProtected() ) 2495 nChk |= FLYPROTECT_CONTENT; 2496 2497 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() ) 2498 { 2499 SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode(); 2500 uno::Reference < embed::XEmbeddedObject > xObj( pNd ? pNd->GetOLEObj().GetOleRef() : 0 ); 2501 if ( xObj.is() ) 2502 { 2503 // TODO/LATER: use correct aspect 2504 const bool bNeverResize = (embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT )); 2505 if ( ( (FLYPROTECT_CONTENT & eType) || (FLYPROTECT_SIZE & eType) ) && bNeverResize ) 2506 { 2507 nChk |= FLYPROTECT_SIZE; 2508 nChk |= FLYPROTECT_FIXED; 2509 } 2510 2511 // set FLYPROTECT_POS if it is a Math object anchored 'as char' and baseline alignment is activated 2512 const bool bProtectMathPos = SotExchange::IsMath( xObj->getClassID() ) 2513 && FLY_AS_CHAR == pFly->GetFmt()->GetAnchor().GetAnchorId() 2514 && pDoc->get( IDocumentSettingAccess::MATH_BASELINE_ALIGNMENT ); 2515 if ((FLYPROTECT_POS & eType) && bProtectMathPos) 2516 nChk |= FLYPROTECT_POS; 2517 } 2518 } 2519 } 2520 nChk &= eType; 2521 if( nChk == eType ) 2522 return static_cast<sal_uInt8>(eType); 2523 } 2524 const SwFrm* pAnch; 2525 if( pObj->ISA(SwVirtFlyDrawObj) ) 2526 pAnch = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchorFrm(); 2527 else 2528 { 2529 SwDrawContact* pTmp = (SwDrawContact*)GetUserCall(pObj); 2530 pAnch = pTmp ? pTmp->GetAnchorFrm( pObj ) : NULL; 2531 } 2532 if( pAnch && pAnch->IsProtected() ) 2533 return static_cast<sal_uInt8>(eType); 2534 } 2535 } 2536 return static_cast<sal_uInt8>(nChk); 2537 } 2538 2539 sal_Bool SwFEShell::GetObjAttr( SfxItemSet &rSet ) const 2540 { 2541 if ( !IsObjSelected() ) 2542 return sal_False; 2543 2544 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2545 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2546 { 2547 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2548 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 2549 // --> OD 2007-07-24 #143008# - make code robust 2550 ASSERT( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact> - please inform OD." ); 2551 if ( pContact ) 2552 { 2553 if ( i ) 2554 rSet.MergeValues( pContact->GetFmt()->GetAttrSet() ); 2555 else 2556 rSet.Put( pContact->GetFmt()->GetAttrSet() ); 2557 } 2558 // <-- 2559 } 2560 return sal_True; 2561 } 2562 2563 sal_Bool SwFEShell::SetObjAttr( const SfxItemSet& rSet ) 2564 { 2565 SET_CURR_SHELL( this ); 2566 2567 if ( !rSet.Count() ) 2568 { ASSERT( !this, "SetObjAttr, empty set." ); 2569 return sal_False; 2570 } 2571 2572 StartAllAction(); 2573 StartUndo( UNDO_INSATTR ); 2574 2575 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2576 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2577 { 2578 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2579 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 2580 GetDoc()->SetAttr( rSet, *pContact->GetFmt() ); 2581 } 2582 2583 EndUndo( UNDO_INSATTR ); 2584 EndAllActionAndCall(); 2585 GetDoc()->SetModified(); 2586 return sal_True; 2587 } 2588 2589 sal_Bool SwFEShell::IsAlignPossible() const 2590 { 2591 sal_uInt16 nCnt; 2592 if ( 0 < (nCnt = IsObjSelected()) ) 2593 { 2594 sal_Bool bRet = sal_True; 2595 if ( nCnt == 1 ) 2596 { 2597 SdrObject *pO = Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 2598 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pO); 2599 //only as character bound drawings can be aligned 2600 bRet = (pC->GetFmt()->GetAnchor().GetAnchorId() == FLY_AS_CHAR); 2601 } 2602 if ( bRet ) 2603 return Imp()->GetDrawView()->IsAlignPossible(); 2604 } 2605 return sal_False; 2606 } 2607 2608 2609 //Temporaerer Fix bis SS von JOE da ist 2610 void SwFEShell::CheckUnboundObjects() 2611 { 2612 SET_CURR_SHELL( this ); 2613 2614 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2615 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2616 { 2617 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2618 if ( !GetUserCall(pObj) ) 2619 { 2620 const Rectangle &rBound = pObj->GetSnapRect(); 2621 const Point aPt( rBound.TopLeft() ); 2622 const SwFrm *pPage = GetLayout()->Lower(); 2623 const SwFrm *pLast = pPage; 2624 while ( pPage && !pPage->Frm().IsInside( aPt ) ) 2625 { 2626 if ( aPt.Y() > pPage->Frm().Bottom() ) 2627 pLast = pPage; 2628 pPage = pPage->GetNext(); 2629 } 2630 if ( !pPage ) 2631 pPage = pLast; 2632 ASSERT( pPage, "Page not found." ); 2633 2634 //Fremde Identifier sollen in den Default laufen. 2635 //Ueberschneidungen sind moeglich!! 2636 sal_uInt16 nIdent = 2637 Imp()->GetDrawView()->GetCurrentObjInventor() == SdrInventor ? 2638 Imp()->GetDrawView()->GetCurrentObjIdentifier() : 0xFFFF; 2639 2640 SwFmtAnchor aAnch; 2641 const SwFrm *pAnch = 0; 2642 { 2643 pAnch = ::FindAnchor( pPage, aPt, sal_True ); 2644 SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() ); 2645 aAnch.SetType( FLY_AT_PARA ); 2646 aAnch.SetAnchor( &aPos ); 2647 ((SwRect&)GetCharRect()).Pos() = aPt; 2648 } 2649 2650 //Erst hier die Action, damit das GetCharRect aktuelle Werte liefert. 2651 StartAllAction(); 2652 2653 SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 2654 RES_SURROUND, RES_ANCHOR, 0 ); 2655 aSet.Put( aAnch ); 2656 2657 Point aRelNullPt; 2658 2659 if( OBJ_CAPTION == nIdent ) 2660 aRelNullPt = ((SdrCaptionObj*)pObj)->GetTailPos(); 2661 else 2662 aRelNullPt = rBound.TopLeft(); 2663 2664 aSet.Put( aAnch ); 2665 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) ); 2666 SwFrmFmt* pFmt = getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet ); 2667 2668 SwDrawContact *pContact = new SwDrawContact( 2669 (SwDrawFrmFmt*)pFmt, pObj ); 2670 2671 // --> OD 2004-11-22 #i35635# 2672 pContact->MoveObjToVisibleLayer( pObj ); 2673 // <-- 2674 pContact->ConnectToLayout(); 2675 2676 EndAllAction(); 2677 } 2678 } 2679 } 2680 2681 void SwFEShell::SetCalcFieldValueHdl(Outliner* pOutliner) 2682 { 2683 GetDoc()->SetCalcFieldValueHdl(pOutliner); 2684 } 2685 2686 2687 2688 int SwFEShell::Chainable( SwRect &rRect, const SwFrmFmt &rSource, 2689 const Point &rPt ) const 2690 { 2691 rRect.Clear(); 2692 2693 //Die Source darf noch keinen Follow haben. 2694 const SwFmtChain &rChain = rSource.GetChain(); 2695 if ( rChain.GetNext() ) 2696 return SW_CHAIN_SOURCE_CHAINED; 2697 2698 if( Imp()->HasDrawView() ) 2699 { 2700 SdrObject* pObj; 2701 SdrPageView* pPView; 2702 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 2703 const sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 2704 pDView->SetHitTolerancePixel( 0 ); 2705 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) && 2706 pObj->ISA(SwVirtFlyDrawObj) ) 2707 { 2708 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 2709 rRect = pFly->Frm(); 2710 2711 //Ziel darf natuerlich nicht gleich Source sein und es 2712 //darf keine geschlossene Kette entstehen. 2713 SwFrmFmt *pFmt = pFly->GetFmt(); 2714 return GetDoc()->Chainable(rSource, *pFmt); 2715 } 2716 pDView->SetHitTolerancePixel( nOld ); 2717 } 2718 return SW_CHAIN_NOT_FOUND; 2719 } 2720 2721 int SwFEShell::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest ) 2722 { 2723 return GetDoc()->Chain(rSource, rDest); 2724 } 2725 2726 int SwFEShell::Chain( SwFrmFmt &rSource, const Point &rPt ) 2727 { 2728 SwRect aDummy; 2729 int nErr = Chainable( aDummy, rSource, rPt ); 2730 if ( !nErr ) 2731 { 2732 StartAllAction(); 2733 SdrObject* pObj; 2734 SdrPageView* pPView; 2735 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 2736 const sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 2737 pDView->SetHitTolerancePixel( 0 ); 2738 pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ); 2739 pDView->SetHitTolerancePixel( nOld ); 2740 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 2741 2742 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)pFly->GetFmt(); 2743 GetDoc()->Chain(rSource, *pFmt); 2744 EndAllAction(); 2745 SetChainMarker(); 2746 } 2747 return nErr; 2748 } 2749 2750 void SwFEShell::Unchain( SwFrmFmt &rFmt ) 2751 { 2752 StartAllAction(); 2753 GetDoc()->Unchain(rFmt); 2754 EndAllAction(); 2755 } 2756 2757 2758 void SwFEShell::HideChainMarker() 2759 { 2760 if ( pChainFrom ) 2761 { 2762 delete pChainFrom; 2763 pChainFrom = 0L; 2764 } 2765 if ( pChainTo ) 2766 { 2767 delete pChainTo; 2768 pChainTo = 0L; 2769 } 2770 } 2771 2772 void SwFEShell::SetChainMarker() 2773 { 2774 sal_Bool bDelFrom = sal_True, 2775 bDelTo = sal_True; 2776 if ( IsFrmSelected() ) 2777 { 2778 SwFlyFrm *pFly = FindFlyFrm(); 2779 2780 if ( pFly->GetPrevLink() ) 2781 { 2782 bDelFrom = sal_False; 2783 const SwFrm *pPre = pFly->GetPrevLink(); 2784 2785 Point aStart( pPre->Frm().Right(), pPre->Frm().Bottom()); 2786 Point aEnd(pFly->Frm().Pos()); 2787 2788 if ( !pChainFrom ) 2789 { 2790 pChainFrom = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd ); 2791 } 2792 } 2793 if ( pFly->GetNextLink() ) 2794 { 2795 bDelTo = sal_False; 2796 const SwFlyFrm *pNxt = pFly->GetNextLink(); 2797 2798 Point aStart( pFly->Frm().Right(), pFly->Frm().Bottom()); 2799 Point aEnd(pNxt->Frm().Pos()); 2800 2801 if ( !pChainTo ) 2802 { 2803 pChainTo = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd ); 2804 } 2805 } 2806 } 2807 2808 if ( bDelFrom ) 2809 { 2810 delete pChainFrom, pChainFrom = 0; 2811 } 2812 2813 if ( bDelTo ) 2814 { 2815 delete pChainTo, pChainTo = 0; 2816 } 2817 } 2818 2819 long SwFEShell::GetSectionWidth( SwFmt& rFmt ) const 2820 { 2821 SwFrm *pFrm = GetCurrFrm(); 2822 // Steht der Cursor z.Z. in einem SectionFrm? 2823 if( pFrm && pFrm->IsInSct() ) 2824 { 2825 SwSectionFrm* pSect = pFrm->FindSctFrm(); 2826 do 2827 { 2828 // Ist es der Gewuenschte? 2829 if( pSect->KnowsFormat( rFmt ) ) 2830 return pSect->Frm().Width(); 2831 // fuer geschachtelte Bereiche 2832 pSect = pSect->GetUpper()->FindSctFrm(); 2833 } 2834 while( pSect ); 2835 } 2836 SwIterator<SwSectionFrm,SwFmt> aIter( rFmt ); 2837 for ( SwSectionFrm* pSct = aIter.First(); pSct; pSct = aIter.Next() ) 2838 { 2839 if( !pSct->IsFollow() ) 2840 { 2841 return pSct->Frm().Width(); 2842 } 2843 } 2844 return 0; 2845 } 2846 2847 void SwFEShell::CreateDefaultShape( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, const Rectangle& rRect, 2848 sal_uInt16 nSlotId) 2849 { 2850 SdrView* pDrawView = GetDrawView(); 2851 SdrModel* pDrawModel = pDrawView->GetModel(); 2852 SdrObject* pObj = SdrObjFactory::MakeNewObject( 2853 SdrInventor, eSdrObjectKind, 2854 0L, pDrawModel); 2855 2856 if(pObj) 2857 { 2858 Rectangle aRect(rRect); 2859 if(OBJ_CARC == eSdrObjectKind || OBJ_CCUT == eSdrObjectKind) 2860 { 2861 // force quadratic 2862 if(aRect.GetWidth() > aRect.GetHeight()) 2863 { 2864 aRect = Rectangle( 2865 Point(aRect.Left() + ((aRect.GetWidth() - aRect.GetHeight()) / 2), aRect.Top()), 2866 Size(aRect.GetHeight(), aRect.GetHeight())); 2867 } 2868 else 2869 { 2870 aRect = Rectangle( 2871 Point(aRect.Left(), aRect.Top() + ((aRect.GetHeight() - aRect.GetWidth()) / 2)), 2872 Size(aRect.GetWidth(), aRect.GetWidth())); 2873 } 2874 } 2875 pObj->SetLogicRect(aRect); 2876 2877 if(pObj->ISA(SdrCircObj)) 2878 { 2879 SfxItemSet aAttr(pDrawModel->GetItemPool()); 2880 aAttr.Put(SdrCircStartAngleItem(9000)); 2881 aAttr.Put(SdrCircEndAngleItem(0)); 2882 pObj->SetMergedItemSet(aAttr); 2883 } 2884 else if(pObj->ISA(SdrPathObj)) 2885 { 2886 basegfx::B2DPolyPolygon aPoly; 2887 2888 switch(eSdrObjectKind) 2889 { 2890 case OBJ_PATHLINE: 2891 { 2892 basegfx::B2DPolygon aInnerPoly; 2893 2894 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom())); 2895 2896 const basegfx::B2DPoint aCenterBottom(aRect.Center().X(), aRect.Bottom()); 2897 aInnerPoly.appendBezierSegment( 2898 aCenterBottom, 2899 aCenterBottom, 2900 basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y())); 2901 2902 const basegfx::B2DPoint aCenterTop(aRect.Center().X(), aRect.Top()); 2903 aInnerPoly.appendBezierSegment( 2904 aCenterTop, 2905 aCenterTop, 2906 basegfx::B2DPoint(aRect.Right(), aRect.Top())); 2907 2908 aInnerPoly.setClosed(true); 2909 aPoly.append(aInnerPoly); 2910 } 2911 break; 2912 case OBJ_FREELINE: 2913 { 2914 basegfx::B2DPolygon aInnerPoly; 2915 2916 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom())); 2917 2918 aInnerPoly.appendBezierSegment( 2919 basegfx::B2DPoint(aRect.Left(), aRect.Top()), 2920 basegfx::B2DPoint(aRect.Center().X(), aRect.Top()), 2921 basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y())); 2922 2923 aInnerPoly.appendBezierSegment( 2924 basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()), 2925 basegfx::B2DPoint(aRect.Right(), aRect.Bottom()), 2926 basegfx::B2DPoint(aRect.Right(), aRect.Top())); 2927 2928 aInnerPoly.append(basegfx::B2DPoint(aRect.Right(), aRect.Bottom())); 2929 aInnerPoly.setClosed(true); 2930 aPoly.append(aInnerPoly); 2931 } 2932 break; 2933 case OBJ_POLY: 2934 case OBJ_PLIN: 2935 { 2936 basegfx::B2DPolygon aInnerPoly; 2937 sal_Int32 nWdt(aRect.GetWidth()); 2938 sal_Int32 nHgt(aRect.GetHeight()); 2939 2940 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom())); 2941 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 30) / 100, aRect.Top() + (nHgt * 70) / 100)); 2942 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Top() + (nHgt * 15) / 100)); 2943 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 65) / 100, aRect.Top())); 2944 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + nWdt, aRect.Top() + (nHgt * 30) / 100)); 2945 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 50) / 100)); 2946 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 75) / 100)); 2947 aInnerPoly.append(basegfx::B2DPoint(aRect.Bottom(), aRect.Right())); 2948 2949 if(OBJ_PLIN == eSdrObjectKind) 2950 { 2951 aInnerPoly.append(basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom())); 2952 } 2953 else 2954 { 2955 aInnerPoly.setClosed(true); 2956 } 2957 2958 aPoly.append(aInnerPoly); 2959 } 2960 break; 2961 case OBJ_LINE : 2962 { 2963 sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2); 2964 basegfx::B2DPolygon aTempPoly; 2965 aTempPoly.append(basegfx::B2DPoint(aRect.TopLeft().X(), nYMiddle)); 2966 aTempPoly.append(basegfx::B2DPoint(aRect.BottomRight().X(), nYMiddle)); 2967 aPoly.append(aTempPoly); 2968 } 2969 break; 2970 } 2971 2972 ((SdrPathObj*)pObj)->SetPathPoly(aPoly); 2973 } 2974 else if(pObj->ISA(SdrCaptionObj)) 2975 { 2976 sal_Bool bVerticalText = ( SID_DRAW_TEXT_VERTICAL == nSlotId || 2977 SID_DRAW_CAPTION_VERTICAL == nSlotId ); 2978 ((SdrTextObj*)pObj)->SetVerticalWriting(bVerticalText); 2979 if(bVerticalText) 2980 { 2981 SfxItemSet aSet(pObj->GetMergedItemSet()); 2982 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); 2983 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); 2984 pObj->SetMergedItemSet(aSet); 2985 } 2986 2987 ((SdrCaptionObj*)pObj)->SetLogicRect(aRect); 2988 ((SdrCaptionObj*)pObj)->SetTailPos( 2989 aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2)); 2990 } 2991 else if(pObj->ISA(SdrTextObj)) 2992 { 2993 SdrTextObj* pText = (SdrTextObj*)pObj; 2994 pText->SetLogicRect(aRect); 2995 2996 sal_Bool bVertical = (SID_DRAW_TEXT_VERTICAL == nSlotId); 2997 sal_Bool bMarquee = (SID_DRAW_TEXT_MARQUEE == nSlotId); 2998 2999 pText->SetVerticalWriting(bVertical); 3000 3001 if(bVertical) 3002 { 3003 SfxItemSet aSet(pDrawModel->GetItemPool()); 3004 aSet.Put(SdrTextAutoGrowWidthItem(sal_True)); 3005 aSet.Put(SdrTextAutoGrowHeightItem(sal_False)); 3006 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); 3007 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); 3008 pText->SetMergedItemSet(aSet); 3009 } 3010 3011 if(bMarquee) 3012 { 3013 SfxItemSet aSet(pDrawModel->GetItemPool(), SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST); 3014 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 3015 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 3016 aSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) ); 3017 aSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) ); 3018 aSet.Put( SdrTextAniCountItem( 1 ) ); 3019 aSet.Put( SdrTextAniAmountItem( (sal_Int16)GetWin()->PixelToLogic(Size(2,1)).Width()) ); 3020 pObj->SetMergedItemSetAndBroadcast(aSet); 3021 } 3022 } 3023 SdrPageView* pPageView = pDrawView->GetSdrPageView(); 3024 pDrawView->InsertObjectAtView(pObj, *pPageView); 3025 } 3026 ImpEndCreate(); 3027 } 3028 3029 /** SwFEShell::GetShapeBackgrd 3030 3031 OD 02.09.2002 for #102450#: 3032 method determines background color of the page the selected drawing 3033 object is on and returns this color. 3034 If no color is found, because no drawing object is selected or ..., 3035 color COL_BLACK (default color on constructing object of class Color) 3036 is returned. 3037 3038 @author OD 3039 3040 @returns an object of class Color 3041 */ 3042 const Color SwFEShell::GetShapeBackgrd() const 3043 { 3044 Color aRetColor; 3045 3046 // check, if a draw view exists 3047 ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!"); 3048 if( Imp()->GetDrawView() ) 3049 { 3050 // determine list of selected objects 3051 const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 3052 // check, if exactly one object is selected. 3053 ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!"); 3054 if ( pMrkList->GetMarkCount() == 1) 3055 { 3056 // get selected object 3057 const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 3058 // check, if selected object is a shape (drawing object) 3059 ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!"); 3060 if ( !pSdrObj->ISA(SwVirtFlyDrawObj) ) 3061 { 3062 // determine page frame of the frame the shape is anchored. 3063 const SwFrm* pAnchorFrm = 3064 static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj ); 3065 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!"); 3066 if ( pAnchorFrm ) 3067 { 3068 const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm(); 3069 ASSERT( pPageFrm, "inconsistent modell - no page!"); 3070 if ( pPageFrm ) 3071 { 3072 aRetColor = pPageFrm->GetDrawBackgrdColor(); 3073 } 3074 } 3075 } 3076 } 3077 } 3078 3079 return aRetColor; 3080 } 3081 3082 /** Is default horizontal text direction for selected drawing object right-to-left 3083 3084 OD 09.12.2002 #103045# 3085 Because drawing objects only painted for each page only, the default 3086 horizontal text direction of a drawing object is given by the corresponding 3087 page property. 3088 3089 @author OD 3090 3091 @returns boolean, indicating, if the horizontal text direction of the 3092 page, the selected drawing object is on, is right-to-left. 3093 */ 3094 bool SwFEShell::IsShapeDefaultHoriTextDirR2L() const 3095 { 3096 bool bRet = false; 3097 3098 // check, if a draw view exists 3099 ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!"); 3100 if( Imp()->GetDrawView() ) 3101 { 3102 // determine list of selected objects 3103 const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 3104 // check, if exactly one object is selected. 3105 ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!"); 3106 if ( pMrkList->GetMarkCount() == 1) 3107 { 3108 // get selected object 3109 const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 3110 // check, if selected object is a shape (drawing object) 3111 ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!"); 3112 if ( !pSdrObj->ISA(SwVirtFlyDrawObj) ) 3113 { 3114 // determine page frame of the frame the shape is anchored. 3115 const SwFrm* pAnchorFrm = 3116 static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj ); 3117 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!"); 3118 if ( pAnchorFrm ) 3119 { 3120 const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm(); 3121 ASSERT( pPageFrm, "inconsistent modell - no page!"); 3122 if ( pPageFrm ) 3123 { 3124 bRet = pPageFrm->IsRightToLeft() ? true : false; 3125 } 3126 } 3127 } 3128 } 3129 } 3130 3131 return bRet; 3132 } 3133 3134 Point SwFEShell::GetRelativePagePosition(const Point& rDocPos) 3135 { 3136 Point aRet(-1, -1); 3137 const SwFrm *pPage = GetLayout()->Lower(); 3138 while ( pPage && !pPage->Frm().IsInside( rDocPos ) ) 3139 { 3140 pPage = pPage->GetNext(); 3141 } 3142 if(pPage) 3143 { 3144 aRet = rDocPos - pPage->Frm().TopLeft(); 3145 } 3146 return aRet; 3147 } 3148 3149