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