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 //IAccessibility2 Implementation 2009----- 1024 sal_Bool SwFEShell::IsObjSameLevelWithMarked(const SdrObject* pObj) const 1025 { 1026 if (pObj) 1027 { 1028 const SdrMarkList& aMarkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1029 if (aMarkList.GetMarkCount() == 0) 1030 { 1031 return sal_True; 1032 } 1033 SdrMark* pM=aMarkList.GetMark(0); 1034 if (pM) 1035 { 1036 SdrObject* pMarkObj = pM->GetMarkedSdrObj(); 1037 if (pMarkObj && pMarkObj->GetUpGroup() == pObj->GetUpGroup()) 1038 return sal_True; 1039 } 1040 } 1041 return sal_False; 1042 } 1043 //-----IAccessibility2 Implementation 2009 1044 /************************************************************************* 1045 |* 1046 |* SwFEShell::EndTextEdit() 1047 |* 1048 *************************************************************************/ 1049 1050 void SwFEShell::EndTextEdit() 1051 { 1052 //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt 1053 //keinen Text mehr enthaelt und keine Attribute traegt) wird das 1054 //Objekt gel�scht. Alle anderen markierten Objekte bleiben erhalten. 1055 1056 ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(), 1057 "EndTextEdit an no Object" ); 1058 1059 StartAllAction(); 1060 SdrView *pView = Imp()->GetDrawView(); 1061 SdrObject *pObj = pView->GetTextEditObject(); 1062 SdrObjUserCall* pUserCall; 1063 if( 0 != ( pUserCall = GetUserCall(pObj) ) ) 1064 { 1065 SdrObject *pTmp = ((SwContact*)pUserCall)->GetMaster(); 1066 if( !pTmp ) 1067 pTmp = pObj; 1068 pUserCall->Changed( *pTmp, SDRUSERCALL_RESIZE, pTmp->GetLastBoundRect() ); 1069 } 1070 if ( !pObj->GetUpGroup() ) 1071 { 1072 if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->SdrEndTextEdit(sal_True) ) 1073 { 1074 if ( pView->GetMarkedObjectList().GetMarkCount() > 1 ) 1075 { 1076 { 1077 SdrMarkList aSave( pView->GetMarkedObjectList() ); 1078 aSave.DeleteMark( aSave.FindObject( pObj ) ); 1079 if ( aSave.GetMarkCount() ) 1080 { 1081 pView->UnmarkAll(); 1082 pView->MarkObj( pObj, Imp()->GetPageView() ); 1083 } 1084 DelSelectedObj(); 1085 if ( aSave.GetMarkCount() ) 1086 { 1087 for ( sal_uInt16 i = 0; i < aSave.GetMarkCount(); ++i ) 1088 pView->MarkObj( aSave.GetMark( i )->GetMarkedSdrObj(), 1089 Imp()->GetPageView() ); 1090 } 1091 } 1092 } 1093 else 1094 DelSelectedObj(); 1095 } 1096 } 1097 else 1098 pView->SdrEndTextEdit(); 1099 EndAllAction(); 1100 } 1101 1102 /************************************************************************* 1103 |* 1104 |* SwFEShell::IsInsideSelectedObj() 1105 |* 1106 *************************************************************************/ 1107 1108 int SwFEShell::IsInsideSelectedObj( const Point &rPt ) 1109 { 1110 if( Imp()->HasDrawView() ) 1111 { 1112 SwDrawView *pDView = Imp()->GetDrawView(); 1113 1114 if( pDView->GetMarkedObjectList().GetMarkCount() && 1115 pDView->IsMarkedObjHit( rPt ) ) 1116 { 1117 return SDRHIT_OBJECT; 1118 } 1119 } 1120 return SDRHIT_NONE; 1121 } 1122 1123 /************************************************************************* 1124 |* 1125 |* SwFEShell::IsObjSelectable() 1126 |* 1127 *************************************************************************/ 1128 1129 bool SwFEShell::IsObjSelectable( const Point& rPt ) 1130 { 1131 SET_CURR_SHELL(this); 1132 #ifdef OLD 1133 if( Imp()->HasDrawView() ) 1134 return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE ); 1135 return 0; 1136 #else 1137 SwDrawView *pDView = Imp()->GetDrawView(); 1138 bool bRet = false; 1139 if( pDView ) 1140 { 1141 SdrObject* pObj; 1142 SdrPageView* pPV; 1143 sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 1144 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 ); 1145 1146 bRet = 0 != pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE ); 1147 pDView->SetHitTolerancePixel( nOld ); 1148 } 1149 return bRet; 1150 #endif 1151 } 1152 1153 // #107513# 1154 // Test if there is a object at that position and if it should be selected. 1155 sal_Bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) 1156 { 1157 SET_CURR_SHELL(this); 1158 SwDrawView *pDrawView = Imp()->GetDrawView(); 1159 sal_Bool bRet(sal_False); 1160 1161 if(pDrawView) 1162 { 1163 SdrObject* pObj; 1164 SdrPageView* pPV; 1165 sal_uInt16 nOld(pDrawView->GetHitTolerancePixel()); 1166 1167 pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2); 1168 bRet = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE); 1169 pDrawView->SetHitTolerancePixel(nOld); 1170 1171 if ( bRet && pObj ) 1172 { 1173 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess(); 1174 // --> OD 2009-12-30 #i89920# 1175 // Do not select object in background which is overlapping this text 1176 // at the given position. 1177 bool bObjInBackground( false ); 1178 { 1179 if ( pObj->GetLayer() == pIDDMA->GetHellId() ) 1180 { 1181 const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); 1182 const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); 1183 const SwFmtSurround& rSurround = rFmt.GetSurround(); 1184 if ( rSurround.GetSurround() == SURROUND_THROUGHT ) 1185 { 1186 bObjInBackground = true; 1187 } 1188 } 1189 } 1190 if ( bObjInBackground ) 1191 { 1192 const SwPageFrm* pPageFrm = GetLayout()->GetPageAtPos( rPt ); 1193 if( pPageFrm ) 1194 { 1195 const SwCntntFrm* pCntntFrm( pPageFrm->ContainsCntnt() ); 1196 while ( pCntntFrm ) 1197 { 1198 if ( pCntntFrm->UnionFrm().IsInside( rPt ) ) 1199 { 1200 const SwTxtFrm* pTxtFrm = 1201 dynamic_cast<const SwTxtFrm*>(pCntntFrm); 1202 if ( pTxtFrm ) 1203 { 1204 SwPosition* pPos = 1205 new SwPosition( *(pTxtFrm->GetTxtNode()) ); 1206 Point aTmpPt( rPt ); 1207 if ( pTxtFrm->GetKeyCrsrOfst( pPos, aTmpPt ) ) 1208 { 1209 SwRect aCursorCharRect; 1210 if ( pTxtFrm->GetCharRect( aCursorCharRect, *pPos ) ) 1211 { 1212 if ( aCursorCharRect.IsOver( SwRect( pObj->GetLastBoundRect() ) ) ) 1213 { 1214 bRet = sal_False; 1215 } 1216 } 1217 } 1218 } 1219 else 1220 { 1221 bRet = sal_False; 1222 } 1223 break; 1224 } 1225 1226 pCntntFrm = pCntntFrm->GetNextCntntFrm(); 1227 } 1228 } 1229 } 1230 // <-- 1231 1232 if ( bRet ) 1233 { 1234 const SdrPage* pPage = pIDDMA->GetDrawModel()->GetPage(0); 1235 for(sal_uInt32 a(pObj->GetOrdNum() + 1); bRet && a < pPage->GetObjCount(); a++) 1236 { 1237 SdrObject *pCandidate = pPage->GetObj(a); 1238 1239 if (pCandidate->ISA(SwVirtFlyDrawObj) && 1240 ( (SwVirtFlyDrawObj*)pCandidate)->GetCurrentBoundRect().IsInside(rPt) ) 1241 { 1242 bRet = sal_False; 1243 } 1244 } 1245 } 1246 } 1247 } 1248 1249 return bRet; 1250 } 1251 1252 /************************************************************************* 1253 |* 1254 |* SwFEShell::GotoObj() 1255 |* 1256 |* Beschreibung Wenn ein Obj selektiert ist, gehen wir von dessen 1257 |* TopLeft aus, andernfalls von der Mitte des aktuellen CharRects. 1258 |* 1259 *************************************************************************/ 1260 /* ------------------------------------ 1261 * Beinhaltet das Objekt ein Control oder Gruppen, 1262 * die nur aus Controls bestehen 1263 * --------------------------------------------------*/ 1264 sal_Bool lcl_IsControlGroup( const SdrObject *pObj ) 1265 { 1266 sal_Bool bRet = sal_False; 1267 if(pObj->ISA(SdrUnoObj)) 1268 bRet = sal_True; 1269 else if( pObj->ISA( SdrObjGroup ) ) 1270 { 1271 bRet = sal_True; 1272 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList(); 1273 for ( sal_uInt16 i = 0; i < pLst->GetObjCount(); ++i ) 1274 if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) ) 1275 return sal_False; 1276 } 1277 return bRet; 1278 } 1279 1280 namespace 1281 { 1282 class MarkableObjectsOnly : public ::svx::ISdrObjectFilter 1283 { 1284 public: 1285 MarkableObjectsOnly( SdrPageView* i_pPV ) 1286 :m_pPV( i_pPV ) 1287 { 1288 } 1289 1290 virtual bool includeObject( const SdrObject& i_rObject ) const 1291 { 1292 return m_pPV && m_pPV->GetView().IsObjMarkable( const_cast< SdrObject* >( &i_rObject ), m_pPV ); 1293 } 1294 1295 private: 1296 SdrPageView* m_pPV; 1297 }; 1298 } 1299 1300 const SdrObject* SwFEShell::GetBestObject( sal_Bool bNext, sal_uInt16 /*GOTOOBJ_...*/ eType, sal_Bool bFlat, const ::svx::ISdrObjectFilter* pFilter ) 1301 { 1302 if( !Imp()->HasDrawView() ) 1303 return NULL; 1304 1305 const SdrObject *pBest = 0, 1306 *pTop = 0; 1307 1308 const long nTmp = bNext ? LONG_MAX : 0; 1309 Point aBestPos( nTmp, nTmp ); 1310 Point aTopPos( nTmp, nTmp ); 1311 Point aCurPos; 1312 Point aPos; 1313 sal_Bool bNoDraw = 0 == (GOTOOBJ_DRAW_ANY & eType); 1314 sal_Bool bNoFly = 0 == (GOTOOBJ_FLY_ANY & eType); 1315 1316 if( !bNoFly && bNoDraw ) 1317 { 1318 SwFlyFrm *pFly = GetCurrFrm( sal_False )->FindFlyFrm(); 1319 if( pFly ) 1320 pBest = pFly->GetVirtDrawObj(); 1321 } 1322 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1323 SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView(); 1324 1325 MarkableObjectsOnly aDefaultFilter( pPV ); 1326 if ( !pFilter ) 1327 pFilter = &aDefaultFilter; 1328 1329 if( !pBest || rMrkList.GetMarkCount() == 1 ) 1330 { 1331 // Ausgangspunkt bestimmen. 1332 SdrObjList* pList = NULL; 1333 if ( rMrkList.GetMarkCount() ) 1334 { 1335 const SdrObject* pStartObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); 1336 if( pStartObj->ISA(SwVirtFlyDrawObj) ) 1337 aPos = ((SwVirtFlyDrawObj*)pStartObj)->GetFlyFrm()->Frm().Pos(); 1338 else 1339 aPos = pStartObj->GetSnapRect().TopLeft(); 1340 1341 // If an object inside a group is selected, we want to 1342 // iterate over the group members. 1343 if ( ! pStartObj->GetUserCall() ) 1344 pList = pStartObj->GetObjList(); 1345 } 1346 else 1347 { 1348 // If no object is selected, we check if we just entered a group. 1349 // In this case we want to iterate over the group members. 1350 aPos = GetCharRect().Center(); 1351 const SdrObject* pStartObj = pPV ? pPV->GetAktGroup() : 0; 1352 if ( pStartObj && pStartObj->ISA( SdrObjGroup ) ) 1353 pList = pStartObj->GetSubList(); 1354 } 1355 1356 if ( ! pList ) 1357 { 1358 // Here we are if 1359 // A No object has been selected and no group has been entered or 1360 // B An object has been selected and it is not inside a group 1361 pList = getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 ); 1362 } 1363 1364 1365 ASSERT( pList, "No object list to iterate" ) 1366 1367 SdrObjListIter aObjIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS ); 1368 while ( aObjIter.IsMore() ) 1369 { 1370 SdrObject* pObj = aObjIter.Next(); 1371 sal_Bool bFlyFrm = pObj->ISA(SwVirtFlyDrawObj); 1372 if( ( bNoFly && bFlyFrm ) || 1373 ( bNoDraw && !bFlyFrm ) || 1374 ( eType == GOTOOBJ_DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ) || 1375 ( eType == GOTOOBJ_DRAW_CONTROL && !lcl_IsControlGroup( pObj ) ) || 1376 ( pFilter && !pFilter->includeObject( *pObj ) ) ) 1377 continue; 1378 if( bFlyFrm ) 1379 { 1380 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pObj; 1381 SwFlyFrm *pFly = pO->GetFlyFrm(); 1382 if( GOTOOBJ_FLY_ANY != ( GOTOOBJ_FLY_ANY & eType ) ) 1383 { 1384 switch ( eType ) 1385 { 1386 case GOTOOBJ_FLY_FRM: 1387 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() ) 1388 continue; 1389 break; 1390 case GOTOOBJ_FLY_GRF: 1391 if ( pFly->Lower() && 1392 (pFly->Lower()->IsLayoutFrm() || 1393 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode())) 1394 continue; 1395 break; 1396 case GOTOOBJ_FLY_OLE: 1397 if ( pFly->Lower() && 1398 (pFly->Lower()->IsLayoutFrm() || 1399 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode())) 1400 continue; 1401 break; 1402 } 1403 } 1404 aCurPos = pFly->Frm().Pos(); 1405 } 1406 else 1407 aCurPos = pObj->GetCurrentBoundRect().TopLeft(); 1408 1409 // Sonderfall wenn ein anderes Obj auf selber Y steht. 1410 if( aCurPos != aPos && // nur wenn ich es nicht selber bin 1411 aCurPos.Y() == aPos.Y() && // ist die Y Position gleich 1412 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir 1413 (aCurPos.X() < aPos.X())) ) // " reverse 1414 { 1415 aBestPos = Point( nTmp, nTmp ); 1416 SdrObjListIter aTmpIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS ); 1417 while ( aTmpIter.IsMore() ) 1418 { 1419 SdrObject* pTmpObj = aTmpIter.Next(); 1420 bFlyFrm = pTmpObj->ISA(SwVirtFlyDrawObj); 1421 if( ( bNoFly && bFlyFrm ) || ( bNoDraw && !bFlyFrm ) ) 1422 continue; 1423 if( bFlyFrm ) 1424 { 1425 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pTmpObj; 1426 aCurPos = pO->GetFlyFrm()->Frm().Pos(); 1427 } 1428 else 1429 aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft(); 1430 1431 if( aCurPos != aPos && aCurPos.Y() == aPos.Y() && 1432 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir 1433 (aCurPos.X() < aPos.X())) && // " reverse 1434 (bNext? (aCurPos.X() < aBestPos.X()) : // besser als Beste 1435 (aCurPos.X() > aBestPos.X())) ) // " reverse 1436 { 1437 aBestPos = aCurPos; 1438 pBest = pTmpObj; 1439 } 1440 } 1441 break; 1442 } 1443 1444 if( ( 1445 (bNext? (aPos.Y() < aCurPos.Y()) : // nur unter mir 1446 (aPos.Y() > aCurPos.Y())) && // " reverse 1447 (bNext? (aBestPos.Y() > aCurPos.Y()) : // naeher drunter 1448 (aBestPos.Y() < aCurPos.Y())) 1449 ) || // " reverse 1450 (aBestPos.Y() == aCurPos.Y() && 1451 (bNext? (aBestPos.X() > aCurPos.X()) : // weiter links 1452 (aBestPos.X() < aCurPos.X())))) // " reverse 1453 1454 { 1455 aBestPos = aCurPos; 1456 pBest = pObj; 1457 } 1458 1459 if( (bNext? (aTopPos.Y() > aCurPos.Y()) : // hoeher als Beste 1460 (aTopPos.Y() < aCurPos.Y())) || // " reverse 1461 (aTopPos.Y() == aCurPos.Y() && 1462 (bNext? (aTopPos.X() > aCurPos.X()) : // weiter links 1463 (aTopPos.X() < aCurPos.X())))) // " reverse 1464 { 1465 aTopPos = aCurPos; 1466 pTop = pObj; 1467 } 1468 } 1469 // leider nichts gefunden 1470 if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) ) 1471 pBest = pTop; 1472 } 1473 1474 return pBest; 1475 } 1476 1477 sal_Bool SwFEShell::GotoObj( sal_Bool bNext, sal_uInt16 /*GOTOOBJ_...*/ eType ) 1478 { 1479 const SdrObject* pBest = GetBestObject( bNext, eType ); 1480 1481 if ( !pBest ) 1482 return sal_False; 1483 1484 sal_Bool bFlyFrm = pBest->ISA(SwVirtFlyDrawObj); 1485 if( bFlyFrm ) 1486 { 1487 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pBest; 1488 const SwRect& rFrm = pO->GetFlyFrm()->Frm(); 1489 SelectObj( rFrm.Pos(), 0, (SdrObject*)pBest ); 1490 if( !ActionPend() ) 1491 MakeVisible( rFrm ); 1492 } 1493 else 1494 { 1495 SelectObj( Point(), 0, (SdrObject*)pBest ); 1496 if( !ActionPend() ) 1497 MakeVisible( pBest->GetCurrentBoundRect() ); 1498 } 1499 CallChgLnk(); 1500 return sal_True; 1501 } 1502 1503 /************************************************************************* 1504 |* 1505 |* SwFEShell::BeginCreate() 1506 |* 1507 *************************************************************************/ 1508 1509 sal_Bool SwFEShell::BeginCreate( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, const Point &rPos ) 1510 { 1511 sal_Bool bRet = sal_False; 1512 1513 if ( !Imp()->HasDrawView() ) 1514 Imp()->MakeDrawView(); 1515 1516 if ( GetPageNumber( rPos ) ) 1517 { 1518 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind ); 1519 if ( eSdrObjectKind == OBJ_CAPTION ) 1520 bRet = Imp()->GetDrawView()->BegCreateCaptionObj( 1521 rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ), 1522 GetOut() ); 1523 else 1524 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() ); 1525 } 1526 if ( bRet ) 1527 { 1528 ::FrameNotify( this, FLY_DRAG_START ); 1529 } 1530 return bRet; 1531 } 1532 1533 sal_Bool SwFEShell::BeginCreate( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, sal_uInt32 eObjInventor, 1534 const Point &rPos ) 1535 { 1536 sal_Bool bRet = sal_False; 1537 1538 if ( !Imp()->HasDrawView() ) 1539 Imp()->MakeDrawView(); 1540 1541 if ( GetPageNumber( rPos ) ) 1542 { 1543 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor ); 1544 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() ); 1545 } 1546 if ( bRet ) 1547 ::FrameNotify( this, FLY_DRAG_START ); 1548 return bRet; 1549 } 1550 1551 /************************************************************************* 1552 |* 1553 |* SwFEShell::MoveCreate() 1554 |* 1555 *************************************************************************/ 1556 1557 void SwFEShell::MoveCreate( const Point &rPos ) 1558 { 1559 ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" ); 1560 if ( GetPageNumber( rPos ) ) 1561 { 1562 ScrollTo( rPos ); 1563 Imp()->GetDrawView()->MovCreateObj( rPos ); 1564 ::FrameNotify( this, FLY_DRAG ); 1565 } 1566 } 1567 1568 /************************************************************************* 1569 |* 1570 |* SwFEShell::EndCreate(), ImpEndCreate() 1571 |* 1572 *************************************************************************/ 1573 1574 sal_Bool SwFEShell::EndCreate( sal_uInt16 eSdrCreateCmd ) 1575 { 1576 // Damit das Undo-Object aus der DrawEngine nicht bei uns 1577 // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz 1578 // das Undo abschalten 1579 ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" ); 1580 if( !Imp()->GetDrawView()->IsGroupEntered() ) 1581 { 1582 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); 1583 } 1584 sal_Bool bCreate = Imp()->GetDrawView()->EndCreateObj( 1585 SdrCreateCmd( eSdrCreateCmd ) ); 1586 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true); 1587 1588 if ( !bCreate ) 1589 { 1590 ::FrameNotify( this, FLY_DRAG_END ); 1591 return sal_False; 1592 } 1593 1594 if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT ) 1595 { 1596 ::FrameNotify( this, FLY_DRAG ); 1597 return sal_True; 1598 } 1599 return ImpEndCreate(); 1600 } 1601 1602 1603 sal_Bool SwFEShell::ImpEndCreate() 1604 { 1605 ASSERT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1, 1606 "Neues Object nicht selektiert." ); 1607 1608 SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 1609 1610 if( rSdrObj.GetSnapRect().IsEmpty() ) 1611 { 1612 // das Object vergessen wir lieber, fuerht nur 1613 // zu Problemen 1614 Imp()->GetDrawView()->DeleteMarked(); 1615 Imp()->GetDrawView()->UnmarkAll(); 1616 ::FrameNotify( this, FLY_DRAG_END ); 1617 return sal_False; 1618 } 1619 1620 if( rSdrObj.GetUpGroup() ) 1621 { 1622 Point aTmpPos( rSdrObj.GetSnapRect().TopLeft() ); 1623 Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() ); 1624 // OD 2004-04-05 #i26791# - direct object positioning for group members 1625 rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor ); 1626 rSdrObj.NbcSetAnchorPos( aNewAnchor ); 1627 ::FrameNotify( this, FLY_DRAG ); 1628 return sal_True; 1629 } 1630 1631 LockPaint(); 1632 StartAllAction(); 1633 1634 Imp()->GetDrawView()->UnmarkAll(); 1635 1636 const Rectangle &rBound = rSdrObj.GetSnapRect(); 1637 Point aPt( rBound.TopRight() ); 1638 1639 //Fremde Identifier sollen in den Default laufen. 1640 //Ueberschneidungen sind moeglich!! 1641 sal_uInt16 nIdent = SdrInventor == rSdrObj.GetObjInventor() 1642 ? rSdrObj.GetObjIdentifier() 1643 : 0xFFFF; 1644 1645 //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst. 1646 SwFmtAnchor aAnch; 1647 const SwFrm *pAnch = 0; 1648 sal_Bool bCharBound = sal_False; 1649 if( rSdrObj.ISA( SdrUnoObj ) ) 1650 { 1651 SwPosition aPos( GetDoc()->GetNodes() ); 1652 SwCrsrMoveState aState( MV_SETONLYTEXT ); 1653 Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 ); 1654 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState ); //swmod 080317 1655 1656 //Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt 1657 if( !aPos.nNode.GetNode().IsProtect() ) 1658 { 1659 pAnch = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPoint, &aPos ); 1660 SwRect aTmp; 1661 pAnch->GetCharRect( aTmp, aPos ); 1662 1663 //Der Crsr darf nicht zu weit entfernt sein. 1664 bCharBound = sal_True; 1665 Rectangle aRect( aTmp.SVRect() ); 1666 aRect.Left() -= MM50*2; 1667 aRect.Top() -= MM50*2; 1668 aRect.Right() += MM50*2; 1669 aRect.Bottom()+= MM50*2; 1670 1671 if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() )) 1672 bCharBound = sal_False; 1673 1674 //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt. 1675 if( bCharBound ) 1676 bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode ); 1677 1678 if( bCharBound ) 1679 { 1680 aAnch.SetType( FLY_AS_CHAR ); 1681 aAnch.SetAnchor( &aPos ); 1682 } 1683 } 1684 } 1685 1686 if( !bCharBound ) 1687 { 1688 // OD 16.05.2003 #108784# - allow native drawing objects in header/footer. 1689 // Thus, set <bBodyOnly> to <false> for these objects using value 1690 // of <nIdent> - value <0xFFFF> indicates control objects, which aren't 1691 // allowed in header/footer. 1692 //bool bBodyOnly = OBJ_NONE != nIdent; 1693 bool bBodyOnly = 0xFFFF == nIdent; 1694 bool bAtPage = false; 1695 const SwFrm* pPage = 0; 1696 SwCrsrMoveState aState( MV_SETONLYTEXT ); 1697 Point aPoint( aPt ); 1698 SwPosition aPos( GetDoc()->GetNodes() ); 1699 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState ); 1700 1701 //nicht in ReadnOnly-Inhalt setzen 1702 if( aPos.nNode.GetNode().IsProtect() ) 1703 // dann darf er nur seitengebunden sein. Oder sollte man 1704 // die naechste nicht READONLY Position suchen? 1705 bAtPage = true; 1706 1707 pAnch = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPoint, 0, sal_False ); 1708 1709 if( !bAtPage ) 1710 { 1711 const SwFlyFrm *pTmp = pAnch->FindFlyFrm(); 1712 if( pTmp ) 1713 { 1714 const SwFrm* pTmpFrm = pAnch; 1715 SwRect aBound( rBound ); 1716 while( pTmp ) 1717 { 1718 if( pTmp->Frm().IsInside( aBound ) ) 1719 { 1720 if( !bBodyOnly || !pTmp->FindFooterOrHeader() ) 1721 pPage = pTmpFrm; 1722 break; 1723 } 1724 pTmp = pTmp->GetAnchorFrm() 1725 ? pTmp->GetAnchorFrm()->FindFlyFrm() 1726 : 0; 1727 pTmpFrm = pTmp; 1728 } 1729 } 1730 1731 if( !pPage ) 1732 pPage = pAnch->FindPageFrm(); 1733 1734 // immer ueber FindAnchor gehen, damit der Frame immer an den 1735 // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum 1736 // nachfolgenden kommen. DAS IST FALSCH 1737 pAnch = ::FindAnchor( pPage, aPt, bBodyOnly ); 1738 aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode(); 1739 1740 //nicht in ReadnOnly-Inhalt setzen 1741 if( aPos.nNode.GetNode().IsProtect() ) 1742 // dann darf er nur seitengebunden sein. Oder sollte man 1743 // die naechste nicht READONLY Position suchen? 1744 bAtPage = true; 1745 else 1746 { 1747 aAnch.SetType( FLY_AT_PARA ); 1748 aAnch.SetAnchor( &aPos ); 1749 } 1750 } 1751 1752 if( bAtPage ) 1753 { 1754 pPage = pAnch->FindPageFrm(); 1755 1756 aAnch.SetType( FLY_AT_PAGE ); 1757 aAnch.SetPageNum( pPage->GetPhyPageNum() ); 1758 pAnch = pPage; // die Page wird jetzt zum Anker 1759 } 1760 } 1761 1762 SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 1763 RES_SURROUND, RES_ANCHOR, 0 ); 1764 aSet.Put( aAnch ); 1765 1766 // OD 2004-03-30 #i26791# - determine relative object position 1767 SwTwips nXOffset; 1768 SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top(); 1769 { 1770 if( pAnch->IsVertical() ) 1771 { 1772 nXOffset = nYOffset; 1773 nYOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right(); 1774 } 1775 else if( pAnch->IsRightToLeft() ) 1776 nXOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right(); 1777 else 1778 nXOffset = rBound.Left() - pAnch->Frm().Left(); 1779 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() ) 1780 { 1781 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch; 1782 do { 1783 pTmp = pTmp->FindMaster(); 1784 ASSERT( pTmp, "Where's my Master?" ); 1785 // OD 2004-03-30 #i26791# - correction: add frame area height 1786 // of master frames. 1787 nYOffset += pTmp->IsVertical() ? 1788 pTmp->Frm().Width() : pTmp->Frm().Height(); 1789 } while ( pTmp->IsFollow() ); 1790 } 1791 } 1792 1793 if( OBJ_NONE == nIdent ) 1794 { 1795 //Bei OBJ_NONE wird ein Fly eingefuegt. 1796 const long nWidth = rBound.Right() - rBound.Left(); 1797 const long nHeight= rBound.Bottom() - rBound.Top(); 1798 aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth, long(MINFLY) ), 1799 Max( nHeight, long(MINFLY) ))); 1800 1801 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME ); 1802 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME ); 1803 aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) ); 1804 aSet.Put( aHori ); 1805 aSet.Put( aVert ); 1806 1807 //Schnell noch das Rechteck merken 1808 const SwRect aFlyRect( rBound ); 1809 1810 //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten 1811 //ueber vorhandene SS erzeugt werden. 1812 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); // see above 1813 // --> OD 2005-08-08 #i52858# - method name changed 1814 SdrPage *pPg = getIDocumentDrawModelAccess()->GetOrCreateDrawModel()->GetPage( 0 ); 1815 // <-- 1816 if( !pPg ) 1817 { 1818 SdrModel* pTmpSdrModel = getIDocumentDrawModelAccess()->GetDrawModel(); 1819 pPg = pTmpSdrModel->AllocPage( sal_False ); 1820 pTmpSdrModel->InsertPage( pPg ); 1821 } 1822 pPg->RecalcObjOrdNums(); 1823 SdrObject* pRemovedObject = pPg->RemoveObject( rSdrObj.GetOrdNumDirect() ); 1824 SdrObject::Free( pRemovedObject ); 1825 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true); 1826 1827 SwFlyFrm* pFlyFrm; 1828 if( NewFlyFrm( aSet, sal_True ) && 1829 ::GetHtmlMode( GetDoc()->GetDocShell() ) && 1830 0 != ( pFlyFrm = FindFlyFrm() )) 1831 { 1832 SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT ); 1833 //Horizontale Ausrichtung: 1834 const sal_Bool bLeftFrm = aFlyRect.Left() < 1835 pAnch->Frm().Left() + pAnch->Prt().Left(), 1836 bLeftPrt = aFlyRect.Left() + aFlyRect.Width() < 1837 pAnch->Frm().Left() + pAnch->Prt().Width()/2; 1838 if( bLeftFrm || bLeftPrt ) 1839 { 1840 aHori.SetHoriOrient( text::HoriOrientation::LEFT ); 1841 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); 1842 } 1843 else 1844 { 1845 const sal_Bool bRightFrm = aFlyRect.Left() > 1846 pAnch->Frm().Left() + pAnch->Prt().Width(); 1847 aHori.SetHoriOrient( text::HoriOrientation::RIGHT ); 1848 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); 1849 } 1850 aHtmlSet.Put( aHori ); 1851 aVert.SetVertOrient( text::VertOrientation::TOP ); 1852 aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA ); 1853 aHtmlSet.Put( aVert ); 1854 1855 GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() ); 1856 } 1857 } 1858 else 1859 { 1860 Point aRelNullPt; 1861 if( OBJ_CAPTION == nIdent ) 1862 aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos(); 1863 else 1864 aRelNullPt = rBound.TopLeft(); 1865 1866 aSet.Put( aAnch ); 1867 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) ); 1868 // OD 2004-03-30 #i26791# - set horizontal position 1869 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME ); 1870 aSet.Put( aHori ); 1871 // OD 2004-03-30 #i26791# - set vertical position 1872 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() ) 1873 { 1874 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch; 1875 do { 1876 pTmp = pTmp->FindMaster(); 1877 ASSERT( pTmp, "Where's my Master?" ); 1878 nYOffset += pTmp->IsVertical() ? 1879 pTmp->Prt().Width() : pTmp->Prt().Height(); 1880 } while ( pTmp->IsFollow() ); 1881 } 1882 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME ); 1883 aSet.Put( aVert ); 1884 SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet ); 1885 // --> OD 2004-10-25 #i36010# - set layout direction of the position 1886 pFmt->SetPositionLayoutDir( 1887 text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); 1888 // <-- 1889 // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set 1890 pFmt->PosAttrSet(); 1891 // <-- 1892 1893 SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj ); 1894 // --> OD 2004-11-22 #i35635# 1895 pContact->MoveObjToVisibleLayer( &rSdrObj ); 1896 // <-- 1897 if( bCharBound ) 1898 { 1899 ASSERT( aAnch.GetAnchorId() == FLY_AS_CHAR, "wrong AnchorType" ); 1900 SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode(); 1901 SwFmtFlyCnt aFmt( pFmt ); 1902 pNd->InsertItem(aFmt, 1903 aAnch.GetCntntAnchor()->nContent.GetIndex(), 0 ); 1904 SwFmtVertOrient aVertical( pFmt->GetVertOrient() ); 1905 aVertical.SetVertOrient( text::VertOrientation::LINE_CENTER ); 1906 pFmt->SetFmtAttr( aVertical ); 1907 } 1908 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() ) 1909 { 1910 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch; 1911 do { 1912 pTmp = pTmp->FindMaster(); 1913 ASSERT( pTmp, "Where's my Master?" ); 1914 } while( pTmp->IsFollow() ); 1915 pAnch = pTmp; 1916 } 1917 1918 pContact->ConnectToLayout(); 1919 1920 // OD 25.06.2003 #108784# - mark object at frame the object is inserted at. 1921 { 1922 SdrObject* pMarkObj = pContact->GetDrawObjectByAnchorFrm( *pAnch ); 1923 if ( pMarkObj ) 1924 { 1925 Imp()->GetDrawView()->MarkObj( pMarkObj, Imp()->GetPageView(), 1926 sal_False, sal_False ); 1927 } 1928 else 1929 { 1930 Imp()->GetDrawView()->MarkObj( &rSdrObj, Imp()->GetPageView(), 1931 sal_False, sal_False ); 1932 } 1933 } 1934 } 1935 1936 GetDoc()->SetModified(); 1937 1938 KillPams(); 1939 EndAllActionAndCall(); 1940 UnlockPaint(); 1941 return sal_True; 1942 } 1943 1944 1945 /************************************************************************* 1946 |* 1947 |* SwFEShell::BreakCreate() 1948 |* 1949 *************************************************************************/ 1950 1951 void SwFEShell::BreakCreate() 1952 { 1953 ASSERT( Imp()->HasDrawView(), "BreakCreate without DrawView?" ); 1954 Imp()->GetDrawView()->BrkCreateObj(); 1955 ::FrameNotify( this, FLY_DRAG_END ); 1956 } 1957 1958 /************************************************************************* 1959 |* 1960 |* SwFEShell::IsDrawCreate() 1961 |* 1962 *************************************************************************/ 1963 1964 sal_Bool SwFEShell::IsDrawCreate() const 1965 { 1966 return Imp()->HasDrawView() ? Imp()->GetDrawView()->IsCreateObj() : sal_False; 1967 } 1968 1969 /************************************************************************* 1970 |* 1971 |* SwFEShell::BeginMark() 1972 |* 1973 *************************************************************************/ 1974 1975 sal_Bool SwFEShell::BeginMark( const Point &rPos ) 1976 { 1977 if ( !Imp()->HasDrawView() ) 1978 Imp()->MakeDrawView(); 1979 1980 if ( GetPageNumber( rPos ) ) 1981 { 1982 SwDrawView* pDView = Imp()->GetDrawView(); 1983 1984 if (pDView->HasMarkablePoints()) 1985 return pDView->BegMarkPoints( rPos ); 1986 else 1987 return pDView->BegMarkObj( rPos ); 1988 } 1989 else 1990 return sal_False; 1991 } 1992 1993 /************************************************************************* 1994 |* 1995 |* SwFEShell::MoveMark() 1996 |* 1997 *************************************************************************/ 1998 1999 void SwFEShell::MoveMark( const Point &rPos ) 2000 { 2001 ASSERT( Imp()->HasDrawView(), "MoveMark without DrawView?" ); 2002 2003 if ( GetPageNumber( rPos ) ) 2004 { 2005 ScrollTo( rPos ); 2006 SwDrawView* pDView = Imp()->GetDrawView(); 2007 // Imp()->GetDrawView()->MovMarkObj( rPos ); 2008 2009 if (pDView->IsInsObjPoint()) 2010 pDView->MovInsObjPoint( rPos ); 2011 else if (pDView->IsMarkPoints()) 2012 pDView->MovMarkPoints( rPos ); 2013 else 2014 pDView->MovAction( rPos ); 2015 } 2016 } 2017 2018 /************************************************************************* 2019 |* 2020 |* SwFEShell::EndMark() 2021 |* 2022 *************************************************************************/ 2023 2024 sal_Bool SwFEShell::EndMark() 2025 { 2026 sal_Bool bRet = sal_False; 2027 ASSERT( Imp()->HasDrawView(), "EndMark without DrawView?" ); 2028 2029 if (Imp()->GetDrawView()->IsMarkObj()) 2030 { 2031 bRet = Imp()->GetDrawView()->EndMarkObj(); 2032 2033 if ( bRet ) 2034 { 2035 sal_Bool bShowHdl = sal_False; 2036 SwDrawView* pDView = Imp()->GetDrawView(); 2037 //Rahmen werden auf diese Art nicht Selektiert, es sein denn es 2038 //ist nur ein Rahmen. 2039 SdrMarkList &rMrkList = (SdrMarkList&)pDView->GetMarkedObjectList(); 2040 SwFlyFrm* pOldSelFly = ::GetFlyFromMarked( &rMrkList, this ); 2041 2042 if ( rMrkList.GetMarkCount() > 1 ) 2043 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2044 { 2045 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2046 if( pObj->ISA(SwVirtFlyDrawObj) ) 2047 { 2048 if ( !bShowHdl ) 2049 { 2050 //HMHpDView->HideMarkHdl(); 2051 bShowHdl = sal_True; 2052 } 2053 rMrkList.DeleteMark( i ); 2054 --i; //keinen auslassen. 2055 } 2056 } 2057 2058 if( bShowHdl ) 2059 { 2060 pDView->MarkListHasChanged(); 2061 pDView->AdjustMarkHdl(); 2062 //HMHpDView->ShowMarkHdl(); 2063 } 2064 2065 if ( rMrkList.GetMarkCount() ) 2066 ::lcl_GrabCursor(this, pOldSelFly); 2067 else 2068 bRet = sal_False; 2069 } 2070 if ( bRet ) 2071 ::FrameNotify( this, FLY_DRAG_START ); 2072 } 2073 else 2074 { 2075 if (Imp()->GetDrawView()->IsMarkPoints()) 2076 bRet = Imp()->GetDrawView()->EndMarkPoints(); 2077 } 2078 2079 SetChainMarker(); 2080 return bRet; 2081 } 2082 2083 /************************************************************************* 2084 |* 2085 |* SwFEShell::BreakSelect() 2086 |* 2087 *************************************************************************/ 2088 2089 void SwFEShell::BreakMark() 2090 { 2091 ASSERT( Imp()->HasDrawView(), "BreakMark without DrawView?" ); 2092 Imp()->GetDrawView()->BrkMarkObj(); 2093 } 2094 2095 /************************************************************************* 2096 |* 2097 |* SwFEShell::GetAnchorId() 2098 |* 2099 *************************************************************************/ 2100 2101 short SwFEShell::GetAnchorId() const 2102 { 2103 short nRet = SHRT_MAX; 2104 if ( Imp()->HasDrawView() ) 2105 { 2106 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2107 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2108 { 2109 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2110 if ( pObj->ISA(SwVirtFlyDrawObj) ) 2111 { 2112 nRet = -1; 2113 break; 2114 } 2115 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 2116 short nId = static_cast<short>(pContact->GetFmt()->GetAnchor().GetAnchorId()); 2117 if ( nRet == SHRT_MAX ) 2118 nRet = nId; 2119 else if ( nRet != nId ) 2120 { 2121 nRet = -1; 2122 break; 2123 } 2124 } 2125 } 2126 if ( nRet == SHRT_MAX ) 2127 nRet = -1; 2128 return nRet; 2129 } 2130 2131 /************************************************************************* 2132 |* 2133 |* SwFEShell::ChgAnchor() 2134 |* 2135 *************************************************************************/ 2136 2137 void SwFEShell::ChgAnchor( int eAnchorId, sal_Bool bSameOnly, sal_Bool bPosCorr ) 2138 { 2139 ASSERT( Imp()->HasDrawView(), "ChgAnchor without DrawView?" ); 2140 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2141 if( rMrkList.GetMarkCount() && 2142 !rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() ) 2143 { 2144 StartAllAction(); 2145 2146 if( GetDoc()->ChgAnchor( rMrkList, (RndStdIds)eAnchorId, bSameOnly, bPosCorr )) 2147 Imp()->GetDrawView()->UnmarkAll(); 2148 2149 EndAllAction(); 2150 2151 ::FrameNotify( this, FLY_DRAG ); 2152 } 2153 } 2154 2155 /************************************************************************* 2156 |* 2157 |* SwFEShell::DelSelectedObj() 2158 |* 2159 *************************************************************************/ 2160 2161 void SwFEShell::DelSelectedObj() 2162 { 2163 ASSERT( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" ); 2164 if ( Imp()->HasDrawView() ) 2165 { 2166 StartAllAction(); 2167 Imp()->GetDrawView()->DeleteMarked(); 2168 EndAllAction(); 2169 ::FrameNotify( this, FLY_DRAG_END ); 2170 } 2171 } 2172 2173 /************************************************************************* 2174 |* 2175 |* SwFEShell::GetObjSize(), GetAnchorObjDiff() 2176 |* 2177 |* Beschreibung Fuer die Statuszeile zum Erfragen der aktuellen 2178 |* Verhaeltnisse 2179 |* 2180 *************************************************************************/ 2181 2182 Size SwFEShell::GetObjSize() const 2183 { 2184 Rectangle aRect; 2185 if ( Imp()->HasDrawView() ) 2186 { 2187 if ( Imp()->GetDrawView()->IsAction() ) 2188 Imp()->GetDrawView()->TakeActionRect( aRect ); 2189 else 2190 aRect = Imp()->GetDrawView()->GetAllMarkedRect(); 2191 } 2192 return aRect.GetSize(); 2193 } 2194 2195 Point SwFEShell::GetAnchorObjDiff() const 2196 { 2197 const SdrView *pView = Imp()->GetDrawView(); 2198 ASSERT( pView, "GetAnchorObjDiff without DrawView?" ); 2199 2200 Rectangle aRect; 2201 if ( Imp()->GetDrawView()->IsAction() ) 2202 Imp()->GetDrawView()->TakeActionRect( aRect ); 2203 else 2204 aRect = Imp()->GetDrawView()->GetAllMarkedRect(); 2205 2206 Point aRet( aRect.TopLeft() ); 2207 2208 if ( IsFrmSelected() ) 2209 { 2210 SwFlyFrm *pFly = FindFlyFrm(); 2211 aRet -= pFly->GetAnchorFrm()->Frm().Pos(); 2212 } 2213 else 2214 { 2215 const SdrObject *pObj = pView->GetMarkedObjectList().GetMarkCount() == 1 ? 2216 pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj() : 0; 2217 if ( pObj ) 2218 aRet -= pObj->GetAnchorPos(); 2219 } 2220 2221 return aRet; 2222 } 2223 2224 Point SwFEShell::GetObjAbsPos() const 2225 { 2226 ASSERT( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" ); 2227 return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft(); 2228 } 2229 2230 2231 2232 /************************************************************************* 2233 |* 2234 |* SwFEShell::IsGroupSelected() 2235 |* 2236 *************************************************************************/ 2237 2238 sal_Bool SwFEShell::IsGroupSelected() 2239 { 2240 if ( IsObjSelected() ) 2241 { 2242 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2243 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2244 { 2245 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2246 // OD 30.06.2003 #108784# - consider 'virtual' drawing objects. 2247 // Thus, use corresponding method instead of checking type. 2248 if ( pObj->IsGroupObject() && 2249 // --> FME 2004-12-08 #i38505# No ungroup allowed for 3d objects 2250 !pObj->Is3DObj() && 2251 // <-- 2252 FLY_AS_CHAR != ((SwDrawContact*)GetUserCall(pObj))-> 2253 GetFmt()->GetAnchor().GetAnchorId() ) 2254 { 2255 return sal_True; 2256 } 2257 } 2258 } 2259 return sal_False; 2260 } 2261 2262 // OD 27.06.2003 #108784# - change return type. 2263 // OD 27.06.2003 #108784# - adjustments for drawing objects in header/footer: 2264 // allow group, only if all selected objects are in the same header/footer 2265 // or not in header/footer. 2266 bool SwFEShell::IsGroupAllowed() const 2267 { 2268 bool bIsGroupAllowed = false; 2269 if ( IsObjSelected() > 1 ) 2270 { 2271 bIsGroupAllowed = true; 2272 const SdrObject* pUpGroup = 0L; 2273 const SwFrm* pHeaderFooterFrm = 0L; 2274 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2275 for ( sal_uInt16 i = 0; bIsGroupAllowed && i < rMrkList.GetMarkCount(); ++i ) 2276 { 2277 const SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2278 if ( i ) 2279 bIsGroupAllowed = pObj->GetUpGroup() == pUpGroup; 2280 else 2281 pUpGroup = pObj->GetUpGroup(); 2282 2283 if ( bIsGroupAllowed ) 2284 { 2285 SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) ); 2286 if ( !pFrmFmt ) 2287 { 2288 ASSERT( false, 2289 "<SwFEShell::IsGroupAllowed()> - missing frame format" ); 2290 bIsGroupAllowed = false; 2291 } 2292 else if ( FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() ) 2293 { 2294 bIsGroupAllowed = false; 2295 } 2296 } 2297 2298 // OD 27.06.2003 #108784# - check, if all selected objects are in the 2299 // same header/footer or not in header/footer. 2300 if ( bIsGroupAllowed ) 2301 { 2302 const SwFrm* pAnchorFrm = 0L; 2303 if ( pObj->ISA(SwVirtFlyDrawObj) ) 2304 { 2305 const SwFlyFrm* pFlyFrm = 2306 static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm(); 2307 if ( pFlyFrm ) 2308 { 2309 pAnchorFrm = pFlyFrm->GetAnchorFrm(); 2310 } 2311 } 2312 else 2313 { 2314 SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall( pObj )); 2315 if ( pDrawContact ) 2316 { 2317 pAnchorFrm = pDrawContact->GetAnchorFrm( pObj ); 2318 } 2319 } 2320 if ( pAnchorFrm ) 2321 { 2322 if ( i ) 2323 { 2324 bIsGroupAllowed = 2325 ( pAnchorFrm->FindFooterOrHeader() == pHeaderFooterFrm ); 2326 } 2327 else 2328 { 2329 pHeaderFooterFrm = pAnchorFrm->FindFooterOrHeader(); 2330 } 2331 } 2332 } 2333 2334 } 2335 } 2336 2337 return bIsGroupAllowed; 2338 } 2339 2340 /************************************************************************* 2341 |* 2342 |* SwFEShell::GroupSelection() 2343 |* 2344 |* Beschreibung Die Gruppe bekommt den Anker und das Contactobjekt 2345 |* des ersten in der Selektion 2346 |* 2347 *************************************************************************/ 2348 2349 void SwFEShell::GroupSelection() 2350 { 2351 if ( IsGroupAllowed() ) 2352 { 2353 StartAllAction(); 2354 StartUndo( UNDO_START ); 2355 2356 GetDoc()->GroupSelection( *Imp()->GetDrawView() ); 2357 2358 EndUndo( UNDO_END ); 2359 EndAllAction(); 2360 } 2361 } 2362 2363 /************************************************************************* 2364 |* 2365 |* SwFEShell::UnGroupSelection() 2366 |* 2367 |* Beschreibung Die Einzelobjekte bekommen eine Kopie vom Anker und 2368 |* Contactobjekt der Gruppe. 2369 |* 2370 *************************************************************************/ 2371 2372 void SwFEShell::UnGroupSelection() 2373 { 2374 if ( IsGroupSelected() ) 2375 { 2376 StartAllAction(); 2377 StartUndo( UNDO_START ); 2378 2379 GetDoc()->UnGroupSelection( *Imp()->GetDrawView() ); 2380 2381 EndUndo( UNDO_END ); 2382 EndAllAction(); 2383 } 2384 } 2385 2386 /************************************************************************* 2387 |* 2388 |* SwFEShell::MirrorSelection() 2389 |* 2390 *************************************************************************/ 2391 2392 void SwFEShell::MirrorSelection( sal_Bool bHorizontal ) 2393 { 2394 SdrView *pView = Imp()->GetDrawView(); 2395 if ( IsObjSelected() && pView->IsMirrorAllowed() ) 2396 { 2397 if ( bHorizontal ) 2398 pView->MirrorAllMarkedHorizontal(); 2399 else 2400 pView->MirrorAllMarkedVertical(); 2401 } 2402 } 2403 2404 // springe zum benannten Rahmen (Grafik/OLE) 2405 2406 sal_Bool SwFEShell::GotoFly( const String& rName, FlyCntType eType, sal_Bool bSelFrm ) 2407 { 2408 sal_Bool bRet = sal_False; 2409 static sal_uInt8 __READONLY_DATA aChkArr[ 4 ] = { 2410 /* FLYCNTTYPE_ALL */ 0, 2411 /* FLYCNTTYPE_FRM */ ND_TEXTNODE, 2412 /* FLYCNTTYPE_GRF */ ND_GRFNODE, 2413 /* FLYCNTTYPE_OLE */ ND_OLENODE 2414 }; 2415 2416 const SwFlyFrmFmt* pFlyFmt = pDoc->FindFlyByName( rName, aChkArr[ eType]); 2417 if( pFlyFmt ) 2418 { 2419 SET_CURR_SHELL( this ); 2420 2421 SwFlyFrm* pFrm = SwIterator<SwFlyFrm,SwFmt>::FirstElement( *pFlyFmt ); 2422 if( pFrm ) 2423 { 2424 if( bSelFrm ) 2425 { 2426 SelectObj( pFrm->Frm().Pos(), 0, pFrm->GetVirtDrawObj() ); 2427 if( !ActionPend() ) 2428 MakeVisible( pFrm->Frm() ); 2429 } 2430 else 2431 { 2432 // --> OD 2004-06-11 #i28701# - no format here 2433 // pFrm->GetAnchorFrm()->Calc(); 2434 SwCntntFrm *pCFrm = pFrm->ContainsCntnt(); 2435 if ( pCFrm ) 2436 { 2437 SwCntntNode *pCNode = pCFrm->GetNode(); 2438 ClearMark(); 2439 SwPaM* pCrsr = GetCrsr(); 2440 2441 pCrsr->GetPoint()->nNode = *pCNode; 2442 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 ); 2443 2444 SwRect& rChrRect = (SwRect&)GetCharRect(); 2445 rChrRect = pFrm->Prt(); 2446 rChrRect.Pos() += pFrm->Frm().Pos(); 2447 GetCrsrDocPos() = rChrRect.Pos(); 2448 } 2449 } 2450 bRet = sal_True; 2451 } 2452 } 2453 return bRet; 2454 } 2455 2456 sal_uInt16 SwFEShell::GetFlyCount( FlyCntType eType ) const 2457 { 2458 return GetDoc()->GetFlyCount(eType); 2459 } 2460 2461 2462 const SwFrmFmt* SwFEShell::GetFlyNum(sal_uInt16 nIdx, FlyCntType eType ) const 2463 { 2464 return GetDoc()->GetFlyNum(nIdx, eType ); 2465 } 2466 2467 // zeige das akt. selektierte "Object" an 2468 void SwFEShell::MakeSelVisible() 2469 { 2470 if( Imp()->HasDrawView() && 2471 Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) 2472 { 2473 MakeVisible( Imp()->GetDrawView()->GetAllMarkedRect() ); 2474 } 2475 else 2476 SwCrsrShell::MakeSelVisible(); 2477 } 2478 2479 2480 //Welcher Schutz ist am selektierten Objekt gesetzt? 2481 sal_uInt8 SwFEShell::IsSelObjProtected( sal_uInt16 eType ) const 2482 { 2483 int nChk = 0; 2484 const bool bParent = (eType & FLYPROTECT_PARENT); 2485 if( Imp()->HasDrawView() ) 2486 { 2487 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2488 for( sal_uLong i = rMrkList.GetMarkCount(); i; ) 2489 { 2490 SdrObject *pObj = rMrkList.GetMark( --i )->GetMarkedSdrObj(); 2491 if( !bParent ) 2492 { 2493 nChk |= ( pObj->IsMoveProtect() ? FLYPROTECT_POS : 0 ) | 2494 ( pObj->IsResizeProtect()? FLYPROTECT_SIZE : 0 ); 2495 2496 if( pObj->ISA(SwVirtFlyDrawObj) ) 2497 { 2498 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 2499 if ( (FLYPROTECT_CONTENT & eType) && pFly->GetFmt()->GetProtect().IsCntntProtected() ) 2500 nChk |= FLYPROTECT_CONTENT; 2501 2502 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() ) 2503 { 2504 SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode(); 2505 uno::Reference < embed::XEmbeddedObject > xObj( pNd ? pNd->GetOLEObj().GetOleRef() : 0 ); 2506 if ( xObj.is() ) 2507 { 2508 // TODO/LATER: use correct aspect 2509 const bool bNeverResize = (embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT )); 2510 if ( ( (FLYPROTECT_CONTENT & eType) || (FLYPROTECT_SIZE & eType) ) && bNeverResize ) 2511 { 2512 nChk |= FLYPROTECT_SIZE; 2513 nChk |= FLYPROTECT_FIXED; 2514 } 2515 2516 // set FLYPROTECT_POS if it is a Math object anchored 'as char' and baseline alignment is activated 2517 const bool bProtectMathPos = SotExchange::IsMath( xObj->getClassID() ) 2518 && FLY_AS_CHAR == pFly->GetFmt()->GetAnchor().GetAnchorId() 2519 && pDoc->get( IDocumentSettingAccess::MATH_BASELINE_ALIGNMENT ); 2520 if ((FLYPROTECT_POS & eType) && bProtectMathPos) 2521 nChk |= FLYPROTECT_POS; 2522 } 2523 } 2524 } 2525 nChk &= eType; 2526 if( nChk == eType ) 2527 return static_cast<sal_uInt8>(eType); 2528 } 2529 const SwFrm* pAnch; 2530 if( pObj->ISA(SwVirtFlyDrawObj) ) 2531 pAnch = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchorFrm(); 2532 else 2533 { 2534 SwDrawContact* pTmp = (SwDrawContact*)GetUserCall(pObj); 2535 pAnch = pTmp ? pTmp->GetAnchorFrm( pObj ) : NULL; 2536 } 2537 if( pAnch && pAnch->IsProtected() ) 2538 return static_cast<sal_uInt8>(eType); 2539 } 2540 } 2541 return static_cast<sal_uInt8>(nChk); 2542 } 2543 2544 sal_Bool SwFEShell::GetObjAttr( SfxItemSet &rSet ) const 2545 { 2546 if ( !IsObjSelected() ) 2547 return sal_False; 2548 2549 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2550 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2551 { 2552 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2553 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 2554 // --> OD 2007-07-24 #143008# - make code robust 2555 ASSERT( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact> - please inform OD." ); 2556 if ( pContact ) 2557 { 2558 if ( i ) 2559 rSet.MergeValues( pContact->GetFmt()->GetAttrSet() ); 2560 else 2561 rSet.Put( pContact->GetFmt()->GetAttrSet() ); 2562 } 2563 // <-- 2564 } 2565 return sal_True; 2566 } 2567 2568 sal_Bool SwFEShell::SetObjAttr( const SfxItemSet& rSet ) 2569 { 2570 SET_CURR_SHELL( this ); 2571 2572 if ( !rSet.Count() ) 2573 { ASSERT( !this, "SetObjAttr, empty set." ); 2574 return sal_False; 2575 } 2576 2577 StartAllAction(); 2578 StartUndo( UNDO_INSATTR ); 2579 2580 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2581 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2582 { 2583 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2584 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 2585 GetDoc()->SetAttr( rSet, *pContact->GetFmt() ); 2586 } 2587 2588 EndUndo( UNDO_INSATTR ); 2589 EndAllActionAndCall(); 2590 GetDoc()->SetModified(); 2591 return sal_True; 2592 } 2593 2594 sal_Bool SwFEShell::IsAlignPossible() const 2595 { 2596 sal_uInt16 nCnt; 2597 if ( 0 < (nCnt = IsObjSelected()) ) 2598 { 2599 sal_Bool bRet = sal_True; 2600 if ( nCnt == 1 ) 2601 { 2602 SdrObject *pO = Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 2603 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pO); 2604 //only as character bound drawings can be aligned 2605 bRet = (pC->GetFmt()->GetAnchor().GetAnchorId() == FLY_AS_CHAR); 2606 } 2607 if ( bRet ) 2608 return Imp()->GetDrawView()->IsAlignPossible(); 2609 } 2610 return sal_False; 2611 } 2612 2613 2614 //Temporaerer Fix bis SS von JOE da ist 2615 void SwFEShell::CheckUnboundObjects() 2616 { 2617 SET_CURR_SHELL( this ); 2618 2619 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 2620 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 2621 { 2622 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 2623 if ( !GetUserCall(pObj) ) 2624 { 2625 const Rectangle &rBound = pObj->GetSnapRect(); 2626 const Point aPt( rBound.TopLeft() ); 2627 const SwFrm *pPage = GetLayout()->Lower(); 2628 const SwFrm *pLast = pPage; 2629 while ( pPage && !pPage->Frm().IsInside( aPt ) ) 2630 { 2631 if ( aPt.Y() > pPage->Frm().Bottom() ) 2632 pLast = pPage; 2633 pPage = pPage->GetNext(); 2634 } 2635 if ( !pPage ) 2636 pPage = pLast; 2637 ASSERT( pPage, "Page not found." ); 2638 2639 //Fremde Identifier sollen in den Default laufen. 2640 //Ueberschneidungen sind moeglich!! 2641 sal_uInt16 nIdent = 2642 Imp()->GetDrawView()->GetCurrentObjInventor() == SdrInventor ? 2643 Imp()->GetDrawView()->GetCurrentObjIdentifier() : 0xFFFF; 2644 2645 SwFmtAnchor aAnch; 2646 const SwFrm *pAnch = 0; 2647 { 2648 pAnch = ::FindAnchor( pPage, aPt, sal_True ); 2649 SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() ); 2650 aAnch.SetType( FLY_AT_PARA ); 2651 aAnch.SetAnchor( &aPos ); 2652 ((SwRect&)GetCharRect()).Pos() = aPt; 2653 } 2654 2655 //Erst hier die Action, damit das GetCharRect aktuelle Werte liefert. 2656 StartAllAction(); 2657 2658 SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 2659 RES_SURROUND, RES_ANCHOR, 0 ); 2660 aSet.Put( aAnch ); 2661 2662 Point aRelNullPt; 2663 2664 if( OBJ_CAPTION == nIdent ) 2665 aRelNullPt = ((SdrCaptionObj*)pObj)->GetTailPos(); 2666 else 2667 aRelNullPt = rBound.TopLeft(); 2668 2669 aSet.Put( aAnch ); 2670 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) ); 2671 SwFrmFmt* pFmt = getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet ); 2672 2673 SwDrawContact *pContact = new SwDrawContact( 2674 (SwDrawFrmFmt*)pFmt, pObj ); 2675 2676 // --> OD 2004-11-22 #i35635# 2677 pContact->MoveObjToVisibleLayer( pObj ); 2678 // <-- 2679 pContact->ConnectToLayout(); 2680 2681 EndAllAction(); 2682 } 2683 } 2684 } 2685 2686 void SwFEShell::SetCalcFieldValueHdl(Outliner* pOutliner) 2687 { 2688 GetDoc()->SetCalcFieldValueHdl(pOutliner); 2689 } 2690 2691 2692 2693 int SwFEShell::Chainable( SwRect &rRect, const SwFrmFmt &rSource, 2694 const Point &rPt ) const 2695 { 2696 rRect.Clear(); 2697 2698 //Die Source darf noch keinen Follow haben. 2699 const SwFmtChain &rChain = rSource.GetChain(); 2700 if ( rChain.GetNext() ) 2701 return SW_CHAIN_SOURCE_CHAINED; 2702 2703 if( Imp()->HasDrawView() ) 2704 { 2705 SdrObject* pObj; 2706 SdrPageView* pPView; 2707 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 2708 const sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 2709 pDView->SetHitTolerancePixel( 0 ); 2710 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) && 2711 pObj->ISA(SwVirtFlyDrawObj) ) 2712 { 2713 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 2714 rRect = pFly->Frm(); 2715 2716 //Ziel darf natuerlich nicht gleich Source sein und es 2717 //darf keine geschlossene Kette entstehen. 2718 SwFrmFmt *pFmt = pFly->GetFmt(); 2719 return GetDoc()->Chainable(rSource, *pFmt); 2720 } 2721 pDView->SetHitTolerancePixel( nOld ); 2722 } 2723 return SW_CHAIN_NOT_FOUND; 2724 } 2725 2726 int SwFEShell::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest ) 2727 { 2728 return GetDoc()->Chain(rSource, rDest); 2729 } 2730 2731 int SwFEShell::Chain( SwFrmFmt &rSource, const Point &rPt ) 2732 { 2733 SwRect aDummy; 2734 int nErr = Chainable( aDummy, rSource, rPt ); 2735 if ( !nErr ) 2736 { 2737 StartAllAction(); 2738 SdrObject* pObj; 2739 SdrPageView* pPView; 2740 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 2741 const sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 2742 pDView->SetHitTolerancePixel( 0 ); 2743 pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ); 2744 pDView->SetHitTolerancePixel( nOld ); 2745 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 2746 2747 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)pFly->GetFmt(); 2748 GetDoc()->Chain(rSource, *pFmt); 2749 EndAllAction(); 2750 SetChainMarker(); 2751 } 2752 return nErr; 2753 } 2754 2755 void SwFEShell::Unchain( SwFrmFmt &rFmt ) 2756 { 2757 StartAllAction(); 2758 GetDoc()->Unchain(rFmt); 2759 EndAllAction(); 2760 } 2761 2762 2763 void SwFEShell::HideChainMarker() 2764 { 2765 if ( pChainFrom ) 2766 { 2767 delete pChainFrom; 2768 pChainFrom = 0L; 2769 } 2770 if ( pChainTo ) 2771 { 2772 delete pChainTo; 2773 pChainTo = 0L; 2774 } 2775 } 2776 2777 void SwFEShell::SetChainMarker() 2778 { 2779 sal_Bool bDelFrom = sal_True, 2780 bDelTo = sal_True; 2781 if ( IsFrmSelected() ) 2782 { 2783 SwFlyFrm *pFly = FindFlyFrm(); 2784 2785 if ( pFly->GetPrevLink() ) 2786 { 2787 bDelFrom = sal_False; 2788 const SwFrm *pPre = pFly->GetPrevLink(); 2789 2790 Point aStart( pPre->Frm().Right(), pPre->Frm().Bottom()); 2791 Point aEnd(pFly->Frm().Pos()); 2792 2793 if ( !pChainFrom ) 2794 { 2795 pChainFrom = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd ); 2796 } 2797 } 2798 if ( pFly->GetNextLink() ) 2799 { 2800 bDelTo = sal_False; 2801 const SwFlyFrm *pNxt = pFly->GetNextLink(); 2802 2803 Point aStart( pFly->Frm().Right(), pFly->Frm().Bottom()); 2804 Point aEnd(pNxt->Frm().Pos()); 2805 2806 if ( !pChainTo ) 2807 { 2808 pChainTo = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd ); 2809 } 2810 } 2811 } 2812 2813 if ( bDelFrom ) 2814 { 2815 delete pChainFrom, pChainFrom = 0; 2816 } 2817 2818 if ( bDelTo ) 2819 { 2820 delete pChainTo, pChainTo = 0; 2821 } 2822 } 2823 2824 long SwFEShell::GetSectionWidth( SwFmt& rFmt ) const 2825 { 2826 SwFrm *pFrm = GetCurrFrm(); 2827 // Steht der Cursor z.Z. in einem SectionFrm? 2828 if( pFrm && pFrm->IsInSct() ) 2829 { 2830 SwSectionFrm* pSect = pFrm->FindSctFrm(); 2831 do 2832 { 2833 // Ist es der Gewuenschte? 2834 if( pSect->KnowsFormat( rFmt ) ) 2835 return pSect->Frm().Width(); 2836 // fuer geschachtelte Bereiche 2837 pSect = pSect->GetUpper()->FindSctFrm(); 2838 } 2839 while( pSect ); 2840 } 2841 SwIterator<SwSectionFrm,SwFmt> aIter( rFmt ); 2842 for ( SwSectionFrm* pSct = aIter.First(); pSct; pSct = aIter.Next() ) 2843 { 2844 if( !pSct->IsFollow() ) 2845 { 2846 return pSct->Frm().Width(); 2847 } 2848 } 2849 return 0; 2850 } 2851 2852 void SwFEShell::CreateDefaultShape( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, const Rectangle& rRect, 2853 sal_uInt16 nSlotId) 2854 { 2855 SdrView* pDrawView = GetDrawView(); 2856 SdrModel* pDrawModel = pDrawView->GetModel(); 2857 SdrObject* pObj = SdrObjFactory::MakeNewObject( 2858 SdrInventor, eSdrObjectKind, 2859 0L, pDrawModel); 2860 2861 if(pObj) 2862 { 2863 Rectangle aRect(rRect); 2864 if(OBJ_CARC == eSdrObjectKind || OBJ_CCUT == eSdrObjectKind) 2865 { 2866 // force quadratic 2867 if(aRect.GetWidth() > aRect.GetHeight()) 2868 { 2869 aRect = Rectangle( 2870 Point(aRect.Left() + ((aRect.GetWidth() - aRect.GetHeight()) / 2), aRect.Top()), 2871 Size(aRect.GetHeight(), aRect.GetHeight())); 2872 } 2873 else 2874 { 2875 aRect = Rectangle( 2876 Point(aRect.Left(), aRect.Top() + ((aRect.GetHeight() - aRect.GetWidth()) / 2)), 2877 Size(aRect.GetWidth(), aRect.GetWidth())); 2878 } 2879 } 2880 pObj->SetLogicRect(aRect); 2881 2882 if(pObj->ISA(SdrCircObj)) 2883 { 2884 SfxItemSet aAttr(pDrawModel->GetItemPool()); 2885 aAttr.Put(SdrCircStartAngleItem(9000)); 2886 aAttr.Put(SdrCircEndAngleItem(0)); 2887 pObj->SetMergedItemSet(aAttr); 2888 } 2889 else if(pObj->ISA(SdrPathObj)) 2890 { 2891 basegfx::B2DPolyPolygon aPoly; 2892 2893 switch(eSdrObjectKind) 2894 { 2895 case OBJ_PATHLINE: 2896 { 2897 basegfx::B2DPolygon aInnerPoly; 2898 2899 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom())); 2900 2901 const basegfx::B2DPoint aCenterBottom(aRect.Center().X(), aRect.Bottom()); 2902 aInnerPoly.appendBezierSegment( 2903 aCenterBottom, 2904 aCenterBottom, 2905 basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y())); 2906 2907 const basegfx::B2DPoint aCenterTop(aRect.Center().X(), aRect.Top()); 2908 aInnerPoly.appendBezierSegment( 2909 aCenterTop, 2910 aCenterTop, 2911 basegfx::B2DPoint(aRect.Right(), aRect.Top())); 2912 2913 aInnerPoly.setClosed(true); 2914 aPoly.append(aInnerPoly); 2915 } 2916 break; 2917 case OBJ_FREELINE: 2918 { 2919 basegfx::B2DPolygon aInnerPoly; 2920 2921 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom())); 2922 2923 aInnerPoly.appendBezierSegment( 2924 basegfx::B2DPoint(aRect.Left(), aRect.Top()), 2925 basegfx::B2DPoint(aRect.Center().X(), aRect.Top()), 2926 basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y())); 2927 2928 aInnerPoly.appendBezierSegment( 2929 basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()), 2930 basegfx::B2DPoint(aRect.Right(), aRect.Bottom()), 2931 basegfx::B2DPoint(aRect.Right(), aRect.Top())); 2932 2933 aInnerPoly.append(basegfx::B2DPoint(aRect.Right(), aRect.Bottom())); 2934 aInnerPoly.setClosed(true); 2935 aPoly.append(aInnerPoly); 2936 } 2937 break; 2938 case OBJ_POLY: 2939 case OBJ_PLIN: 2940 { 2941 basegfx::B2DPolygon aInnerPoly; 2942 sal_Int32 nWdt(aRect.GetWidth()); 2943 sal_Int32 nHgt(aRect.GetHeight()); 2944 2945 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom())); 2946 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 30) / 100, aRect.Top() + (nHgt * 70) / 100)); 2947 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Top() + (nHgt * 15) / 100)); 2948 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 65) / 100, aRect.Top())); 2949 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + nWdt, aRect.Top() + (nHgt * 30) / 100)); 2950 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 50) / 100)); 2951 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 75) / 100)); 2952 aInnerPoly.append(basegfx::B2DPoint(aRect.Bottom(), aRect.Right())); 2953 2954 if(OBJ_PLIN == eSdrObjectKind) 2955 { 2956 aInnerPoly.append(basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom())); 2957 } 2958 else 2959 { 2960 aInnerPoly.setClosed(true); 2961 } 2962 2963 aPoly.append(aInnerPoly); 2964 } 2965 break; 2966 case OBJ_LINE : 2967 { 2968 sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2); 2969 basegfx::B2DPolygon aTempPoly; 2970 aTempPoly.append(basegfx::B2DPoint(aRect.TopLeft().X(), nYMiddle)); 2971 aTempPoly.append(basegfx::B2DPoint(aRect.BottomRight().X(), nYMiddle)); 2972 aPoly.append(aTempPoly); 2973 } 2974 break; 2975 } 2976 2977 ((SdrPathObj*)pObj)->SetPathPoly(aPoly); 2978 } 2979 else if(pObj->ISA(SdrCaptionObj)) 2980 { 2981 sal_Bool bVerticalText = ( SID_DRAW_TEXT_VERTICAL == nSlotId || 2982 SID_DRAW_CAPTION_VERTICAL == nSlotId ); 2983 ((SdrTextObj*)pObj)->SetVerticalWriting(bVerticalText); 2984 if(bVerticalText) 2985 { 2986 SfxItemSet aSet(pObj->GetMergedItemSet()); 2987 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); 2988 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); 2989 pObj->SetMergedItemSet(aSet); 2990 } 2991 2992 ((SdrCaptionObj*)pObj)->SetLogicRect(aRect); 2993 ((SdrCaptionObj*)pObj)->SetTailPos( 2994 aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2)); 2995 } 2996 else if(pObj->ISA(SdrTextObj)) 2997 { 2998 SdrTextObj* pText = (SdrTextObj*)pObj; 2999 pText->SetLogicRect(aRect); 3000 3001 sal_Bool bVertical = (SID_DRAW_TEXT_VERTICAL == nSlotId); 3002 sal_Bool bMarquee = (SID_DRAW_TEXT_MARQUEE == nSlotId); 3003 3004 pText->SetVerticalWriting(bVertical); 3005 3006 if(bVertical) 3007 { 3008 SfxItemSet aSet(pDrawModel->GetItemPool()); 3009 aSet.Put(SdrTextAutoGrowWidthItem(sal_True)); 3010 aSet.Put(SdrTextAutoGrowHeightItem(sal_False)); 3011 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); 3012 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); 3013 pText->SetMergedItemSet(aSet); 3014 } 3015 3016 if(bMarquee) 3017 { 3018 SfxItemSet aSet(pDrawModel->GetItemPool(), SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST); 3019 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 3020 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 3021 aSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) ); 3022 aSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) ); 3023 aSet.Put( SdrTextAniCountItem( 1 ) ); 3024 aSet.Put( SdrTextAniAmountItem( (sal_Int16)GetWin()->PixelToLogic(Size(2,1)).Width()) ); 3025 pObj->SetMergedItemSetAndBroadcast(aSet); 3026 } 3027 } 3028 SdrPageView* pPageView = pDrawView->GetSdrPageView(); 3029 pDrawView->InsertObjectAtView(pObj, *pPageView); 3030 } 3031 ImpEndCreate(); 3032 } 3033 3034 /** SwFEShell::GetShapeBackgrd 3035 3036 OD 02.09.2002 for #102450#: 3037 method determines background color of the page the selected drawing 3038 object is on and returns this color. 3039 If no color is found, because no drawing object is selected or ..., 3040 color COL_BLACK (default color on constructing object of class Color) 3041 is returned. 3042 3043 @author OD 3044 3045 @returns an object of class Color 3046 */ 3047 const Color SwFEShell::GetShapeBackgrd() const 3048 { 3049 Color aRetColor; 3050 3051 // check, if a draw view exists 3052 ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!"); 3053 if( Imp()->GetDrawView() ) 3054 { 3055 // determine list of selected objects 3056 const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 3057 // check, if exactly one object is selected. 3058 ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!"); 3059 if ( pMrkList->GetMarkCount() == 1) 3060 { 3061 // get selected object 3062 const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 3063 // check, if selected object is a shape (drawing object) 3064 ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!"); 3065 if ( !pSdrObj->ISA(SwVirtFlyDrawObj) ) 3066 { 3067 // determine page frame of the frame the shape is anchored. 3068 const SwFrm* pAnchorFrm = 3069 static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj ); 3070 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!"); 3071 if ( pAnchorFrm ) 3072 { 3073 const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm(); 3074 ASSERT( pPageFrm, "inconsistent modell - no page!"); 3075 if ( pPageFrm ) 3076 { 3077 aRetColor = pPageFrm->GetDrawBackgrdColor(); 3078 } 3079 } 3080 } 3081 } 3082 } 3083 3084 return aRetColor; 3085 } 3086 3087 /** Is default horizontal text direction for selected drawing object right-to-left 3088 3089 OD 09.12.2002 #103045# 3090 Because drawing objects only painted for each page only, the default 3091 horizontal text direction of a drawing object is given by the corresponding 3092 page property. 3093 3094 @author OD 3095 3096 @returns boolean, indicating, if the horizontal text direction of the 3097 page, the selected drawing object is on, is right-to-left. 3098 */ 3099 bool SwFEShell::IsShapeDefaultHoriTextDirR2L() const 3100 { 3101 bool bRet = false; 3102 3103 // check, if a draw view exists 3104 ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!"); 3105 if( Imp()->GetDrawView() ) 3106 { 3107 // determine list of selected objects 3108 const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 3109 // check, if exactly one object is selected. 3110 ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!"); 3111 if ( pMrkList->GetMarkCount() == 1) 3112 { 3113 // get selected object 3114 const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 3115 // check, if selected object is a shape (drawing object) 3116 ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!"); 3117 if ( !pSdrObj->ISA(SwVirtFlyDrawObj) ) 3118 { 3119 // determine page frame of the frame the shape is anchored. 3120 const SwFrm* pAnchorFrm = 3121 static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj ); 3122 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!"); 3123 if ( pAnchorFrm ) 3124 { 3125 const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm(); 3126 ASSERT( pPageFrm, "inconsistent modell - no page!"); 3127 if ( pPageFrm ) 3128 { 3129 bRet = pPageFrm->IsRightToLeft() ? true : false; 3130 } 3131 } 3132 } 3133 } 3134 } 3135 3136 return bRet; 3137 } 3138 3139 Point SwFEShell::GetRelativePagePosition(const Point& rDocPos) 3140 { 3141 Point aRet(-1, -1); 3142 const SwFrm *pPage = GetLayout()->Lower(); 3143 while ( pPage && !pPage->Frm().IsInside( rDocPos ) ) 3144 { 3145 pPage = pPage->GetNext(); 3146 } 3147 if(pPage) 3148 { 3149 aRet = rDocPos - pPage->Frm().TopLeft(); 3150 } 3151 return aRet; 3152 } 3153 3154