1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include <hintids.hxx> 32 #include <svl/itemiter.hxx> 33 #include <svtools/imapobj.hxx> 34 #include <svtools/soerr.hxx> 35 #include <editeng/protitem.hxx> 36 #include <svx/svdogrp.hxx> 37 #include <svx/svdouno.hxx> 38 #include <svx/fmglob.hxx> 39 #include <com/sun/star/form/FormButtonType.hpp> 40 #include <com/sun/star/beans/XPropertySet.hpp> 41 #include <fmtanchr.hxx> 42 #include <txtflcnt.hxx> 43 #include <fmtcntnt.hxx> 44 #include <fmtornt.hxx> 45 #include <fmtflcnt.hxx> 46 #include <fmturl.hxx> 47 #include <fmtclds.hxx> 48 #include <fmtfsize.hxx> 49 #include <docary.hxx> 50 #include <fesh.hxx> 51 #include <rootfrm.hxx> 52 #include <pagefrm.hxx> 53 #include <cntfrm.hxx> 54 #include <txtfrm.hxx> 55 #include <viewimp.hxx> 56 #include <viscrs.hxx> 57 #include <doc.hxx> 58 #include <IDocumentUndoRedo.hxx> 59 #include <dview.hxx> 60 #include <dflyobj.hxx> 61 #include <dcontact.hxx> 62 #include <frmfmt.hxx> 63 #include <flyfrm.hxx> 64 #include <ndtxt.hxx> 65 #include <edimp.hxx> 66 #include <swtable.hxx> 67 #include <mvsave.hxx> // Strukturen zum Sichern beim Move/Delete 68 #include <ndgrf.hxx> 69 #include <flyfrms.hxx> 70 #include <flypos.hxx> 71 #include <fldbas.hxx> 72 #include <fmtfld.hxx> 73 #include <swundo.hxx> 74 #include <frame.hxx> 75 #include <notxtfrm.hxx> 76 // --> OD 2006-03-06 #125892# 77 #include <HandleAnchorNodeChg.hxx> 78 // <-- 79 #include <frmatr.hxx> 80 // --> 3.7.2010 #i972# 81 #include <ndole.hxx> 82 // <-- 83 // --> OD 2009-12-29 #i89920# 84 #include <fmtsrnd.hxx> 85 #include <editeng/opaqitem.hxx> 86 // <-- 87 88 using ::rtl::OUString; 89 using namespace ::com::sun::star; 90 91 //Zum anmelden von Flys in Flys in ... 92 //definiert in layout/frmtool.cxx 93 void RegistFlys( SwPageFrm*, const SwLayoutFrm* ); 94 95 /*********************************************************************** 96 #* Class : SwDoc 97 #* Methode : UseSpzLayoutFmt 98 #* Beschreibung: Anhand des Request werden zu dem Format entsprechende 99 #* Aenderungen an den Spezifischen Layouts vorgenommen. 100 #* Datum : MA 23. Sep. 92 101 #* Update : JP 09.03.98 102 #***********************************************************************/ 103 104 sal_Bool lcl_SetNewFlyPos( const SwNode& rNode, SwFmtAnchor& rAnchor, 105 const Point& rPt ) 106 { 107 sal_Bool bRet = sal_False; 108 const SwStartNode* pStNode = rNode.FindFlyStartNode(); 109 if( pStNode ) 110 { 111 SwPosition aPos( *pStNode ); 112 rAnchor.SetAnchor( &aPos ); 113 bRet = sal_True; 114 } 115 else 116 { 117 const SwCntntNode *pCntNd = rNode.GetCntntNode(); 118 const SwCntntFrm* pCFrm = pCntNd ? pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(), &rPt, 0, sal_False ) : 0; 119 const SwPageFrm *pPg = pCFrm ? pCFrm->FindPageFrm() : 0; 120 121 rAnchor.SetPageNum( pPg ? pPg->GetPhyPageNum() : 1 ); 122 rAnchor.SetType( FLY_AT_PAGE ); 123 } 124 return bRet; 125 } 126 127 sal_Bool lcl_FindAnchorPos( SwDoc& rDoc, const Point& rPt, const SwFrm& rFrm, 128 SfxItemSet& rSet ) 129 { 130 sal_Bool bRet = sal_True; 131 SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) ); 132 RndStdIds nNew = aNewAnch.GetAnchorId(); 133 const SwFrm *pNewAnch; 134 135 //Neuen Anker ermitteln 136 Point aTmpPnt( rPt ); 137 switch( nNew ) 138 { 139 case FLY_AS_CHAR: // sollte der nicht auch mit hinein? 140 case FLY_AT_PARA: 141 case FLY_AT_CHAR: // LAYER_IMPL 142 { 143 //Ausgehend von der linken oberen Ecke des Fly den 144 //dichtesten CntntFrm suchen. 145 const SwFrm* pFrm = rFrm.IsFlyFrm() ? ((SwFlyFrm&)rFrm).GetAnchorFrm() 146 : &rFrm; 147 pNewAnch = ::FindAnchor( pFrm, aTmpPnt ); 148 if( pNewAnch->IsProtected() ) 149 { 150 bRet = sal_False; 151 break; 152 } 153 154 SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() ); 155 if ((FLY_AT_CHAR == nNew) || (FLY_AS_CHAR == nNew)) 156 { 157 // es muss ein TextNode gefunden werden, denn nur in diesen 158 // ist ein Inhaltsgebundene Frames zu verankern 159 SwCrsrMoveState aState( MV_SETONLYTEXT ); 160 aTmpPnt.X() -= 1; //nicht im Fly landen!! 161 if( !pNewAnch->GetCrsrOfst( &aPos, aTmpPnt, &aState ) ) 162 { 163 SwCntntNode* pCNd = ((SwCntntFrm*)pNewAnch)->GetNode(); 164 if( pNewAnch->Frm().Bottom() < aTmpPnt.Y() ) 165 pCNd->MakeStartIndex( &aPos.nContent ); 166 else 167 pCNd->MakeEndIndex( &aPos.nContent ); 168 } 169 } 170 aNewAnch.SetAnchor( &aPos ); 171 } 172 break; 173 174 case FLY_AT_FLY: // LAYER_IMPL 175 { 176 //Ausgehend von der linken oberen Ecke des Fly den 177 //dichtesten SwFlyFrm suchen. 178 SwCrsrMoveState aState( MV_SETONLYTEXT ); 179 SwPosition aPos( rDoc.GetNodes() ); 180 aTmpPnt.X() -= 1; //nicht im Fly landen!! 181 rDoc.GetCurrentLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState ); //swmod 071108//swmod 071225 182 pNewAnch = ::FindAnchor( 183 aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( rFrm.getRootFrm(), 0, 0, sal_False ), 184 aTmpPnt )->FindFlyFrm(); 185 186 if( pNewAnch && &rFrm != pNewAnch && !pNewAnch->IsProtected() ) 187 { 188 aPos.nNode = *((SwFlyFrm*)pNewAnch)->GetFmt()->GetCntnt(). 189 GetCntntIdx(); 190 aNewAnch.SetAnchor( &aPos ); 191 break; 192 } 193 } 194 195 aNewAnch.SetType( nNew = FLY_AT_PAGE ); 196 // no break 197 198 case FLY_AT_PAGE: 199 pNewAnch = rFrm.FindPageFrm(); 200 aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() ); 201 break; 202 203 default: 204 ASSERT( !&rDoc, "Falsche ID fuer neuen Anker." ); 205 } 206 207 rSet.Put( aNewAnch ); 208 return bRet; 209 } 210 211 // 212 //! also used in unoframe.cxx 213 // 214 sal_Bool lcl_ChkAndSetNewAnchor( const SwFlyFrm& rFly, SfxItemSet& rSet ) 215 { 216 const SwFrmFmt& rFmt = *rFly.GetFmt(); 217 const SwFmtAnchor &rOldAnch = rFmt.GetAnchor(); 218 const RndStdIds nOld = rOldAnch.GetAnchorId(); 219 220 RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId(); 221 222 if( nOld == nNew ) 223 return sal_False; 224 225 SwDoc* pDoc = (SwDoc*)rFmt.GetDoc(); 226 227 #ifdef DBG_UTIL 228 ASSERT( !(nNew == FLY_AT_PAGE && 229 (FLY_AT_PARA==nOld || FLY_AT_CHAR==nOld || FLY_AS_CHAR==nOld ) && 230 pDoc->IsInHeaderFooter( rOldAnch.GetCntntAnchor()->nNode )), 231 "Unerlaubter Ankerwechsel in Head/Foot." ); 232 #endif 233 234 return ::lcl_FindAnchorPos( *pDoc, rFly.Frm().Pos(), rFly, rSet ); 235 } 236 237 void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, sal_Bool bNew ) 238 { 239 SET_CURR_SHELL( this ); 240 241 // Wenn es ein neuer Rahmen ist, so soll er selektiert sein. 242 // !!Rahmen immer selektieren, wenn sie nicht selektiert sind. 243 // - Es kann ein neuer 'alter' sein weil der Anker gewechselt wurde. 244 // - 'alte' Rahmen sind vorher immer selektiert denn sonst wird nix 245 // an ihnen veraendert. 246 // Der Rahmen darf nicht per Dokumentposition selektiert werden, weil er 247 // auf jedenfall selektiert sein muss! 248 SwViewImp *pImpl = Imp(); 249 if( GetWin() && (bNew || !pImpl->GetDrawView()->AreObjectsMarked()) ) 250 { 251 ASSERT( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" ); 252 253 //Wenn der Fly bereits selektiert ist gibt es hier ja wohl nichts 254 //zu tun. 255 if ( FindFlyFrm() == &rFrm ) 256 return; 257 258 //Damit der Anker ueberhaupt noch gepaintet wird. 259 if( rFrm.IsFlyInCntFrm() && rFrm.GetAnchorFrm() ) 260 rFrm.GetAnchorFrm()->SetCompletePaint(); 261 262 // --> OD 2004-06-11 #i28701# - no format at all. 263 // //Hier wurde immer kalkuliert. Leider ist der Sonderfall Fly in Fly mit 264 // //Spalten u.U. sehr kritisch wenn der innenliegende zuerst formatiert 265 // //wird. Um kein Risiko einzugehen entschaerfen wir nur diesen Sonderfall. 266 // if( !rFrm.GetAnchorFrm()->IsInFly() ) 267 // rFrm.Calc(); 268 269 if( pImpl->GetDrawView()->AreObjectsMarked() ) 270 pImpl->GetDrawView()->UnmarkAll(); 271 272 pImpl->GetDrawView()->MarkObj( rFrm.GetVirtDrawObj(), 273 pImpl->GetPageView(), sal_False, sal_False ); 274 KillPams(); 275 ClearMark(); 276 SelFlyGrabCrsr(); 277 } 278 } 279 280 /************************************************************************* 281 |* 282 |* SwFEShell::FindFlyFrm() 283 |* 284 |* Beschreibung Liefert den Fly wenn einer Selektiert ist. 285 |* Ersterstellung MA 03. Nov. 92 286 |* Letzte Aenderung MA 05. Mar. 96 287 |* 288 *************************************************************************/ 289 290 SwFlyFrm *SwFEShell::FindFlyFrm() const 291 { 292 if ( Imp()->HasDrawView() ) 293 { 294 // Ein Fly ist genau dann erreichbar, wenn er selektiert ist. 295 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 296 if( rMrkList.GetMarkCount() != 1 ) 297 return 0; 298 299 SdrObject *pO = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 300 return ( pO && pO->ISA(SwVirtFlyDrawObj) ) ? ((SwVirtFlyDrawObj*)pO)->GetFlyFrm() : 0; 301 } 302 return 0; 303 } 304 305 /************************************************************************* 306 |* 307 |* SwFEShell::IsFlyInFly() 308 |* 309 |* Beschreibung Liefert sal_True, wenn der aktuelle Fly an einem anderen 310 |* verankert werden koennte (also innerhalb ist) 311 |* Ersterstellung AMA 11. Sep. 97 312 |* Letzte Aenderung AMA 14. Jan. 98 313 |* 314 *************************************************************************/ 315 316 const SwFrmFmt* SwFEShell::IsFlyInFly() 317 { 318 SET_CURR_SHELL( this ); 319 320 if ( !Imp()->HasDrawView() ) 321 return NULL; 322 323 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 324 if ( !rMrkList.GetMarkCount() ) 325 { 326 SwCntntFrm *pCntnt = GetCurrFrm( sal_False ); 327 if( !pCntnt ) 328 return NULL; 329 SwFlyFrm *pFly = pCntnt->FindFlyFrm(); 330 if ( !pFly ) 331 return NULL; 332 return pFly->GetFmt(); 333 } 334 else if ( rMrkList.GetMarkCount() != 1 || 335 !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) ) 336 return NULL; 337 338 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 339 340 SwFrmFmt *pFmt = FindFrmFmt( pObj ); 341 if( pFmt && FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId() ) 342 { 343 const SwFrm* pFly = pObj->ISA(SwVirtFlyDrawObj) ? 344 ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchorFrm() : 345 ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj ); 346 ASSERT( pFly, "IsFlyInFly: Where's my anchor?" ); 347 ASSERT( pFly->IsFlyFrm(), "IsFlyInFly: Funny anchor!" ); 348 return ((SwFlyFrm*)pFly)->GetFmt(); 349 } 350 351 Point aTmpPos = pObj->GetCurrentBoundRect().TopLeft(); 352 353 SwFrm *pTxtFrm; 354 { 355 SwCrsrMoveState aState( MV_SETONLYTEXT ); 356 SwNodeIndex aSwNodeIndex( GetDoc()->GetNodes() ); 357 SwPosition aPos( aSwNodeIndex ); 358 Point aPoint( aTmpPos ); 359 aPoint.X() -= 1; //nicht im Fly landen!! 360 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState ); 361 // OD 01.07.2003 #108784# - determine text frame by left-top-corner 362 // of object 363 //pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm( 0, 0, sal_False ); 364 pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aTmpPos, 0, sal_False ); 365 } 366 const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aTmpPos ); 367 const SwFlyFrm *pFly = pTmp->FindFlyFrm(); 368 if( pFly ) 369 return pFly->GetFmt(); 370 return NULL; 371 } 372 373 /************************************************************************* 374 |* 375 |* SwFEShell::SetFlyPos 376 |* 377 |* Ersterstellung MA 14. Jan. 93 378 |* Letzte Aenderung MA 14. Feb. 95 379 |* 380 *************************************************************************/ 381 382 void SwFEShell::SetFlyPos( const Point& rAbsPos ) 383 { 384 SET_CURR_SHELL( this ); 385 386 //Bezugspunkt in Dokumentkoordinaten bestimmen 387 SwCntntFrm *pCntnt = GetCurrFrm( sal_False ); 388 if( !pCntnt ) 389 return; 390 SwFlyFrm *pFly = pCntnt->FindFlyFrm(); 391 if ( !pFly ) 392 return; 393 394 //SwSaveHdl aSaveX( Imp() ); 395 396 //Bei Absatzgebundenen Flys muss ausgehend von der absoluten 397 //Position ein neuer Anker gesetzt werden. Anker und neue RelPos werden 398 //vom Fly selbst berechnet und gesetzt. 399 if ( pFly->IsFlyAtCntFrm() ) 400 ((SwFlyAtCntFrm*)pFly)->SetAbsPos( rAbsPos ); 401 else 402 { 403 const SwFrm *pAnch = pFly->GetAnchorFrm(); 404 // --> OD 2004-06-11 #i28701# - no format here 405 // pAnch->Calc(); 406 Point aOrient( pAnch->Frm().Pos() ); 407 408 if ( pFly->IsFlyInCntFrm() ) 409 aOrient.X() = rAbsPos.X(); 410 411 //RelPos errechnen. 412 aOrient.X() = rAbsPos.X() - aOrient.X(); 413 aOrient.Y() = rAbsPos.Y() - aOrient.Y(); 414 pFly->ChgRelPos( aOrient ); 415 } 416 // --> OD 2004-06-11 #i28701# - no format here 417 // pFly->Calc(); 418 CallChgLnk(); // rufe das AttrChangeNotify auf der UI-Seite. 419 } 420 421 /************************************************************************* 422 |* 423 |* SwFEShell::FindAnchorPos 424 |* 425 |* Ersterstellung AMA 24. Sep. 97 426 |* Letzte Aenderung AMA 24. Sep. 97 427 |* 428 *************************************************************************/ 429 430 Point SwFEShell::FindAnchorPos( const Point& rAbsPos, sal_Bool bMoveIt ) 431 { 432 Point aRet; 433 434 SET_CURR_SHELL( this ); 435 436 if ( !Imp()->HasDrawView() ) 437 return aRet; 438 439 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 440 if ( rMrkList.GetMarkCount() != 1 || 441 !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) ) 442 return aRet; 443 444 SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 445 // --> OD 2004-07-16 #i28701# 446 SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); 447 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); 448 RndStdIds nAnchorId = rFmt.GetAnchor().GetAnchorId(); 449 450 if ( FLY_AS_CHAR == nAnchorId ) 451 return aRet; 452 453 sal_Bool bFlyFrame = pObj->ISA(SwVirtFlyDrawObj); 454 455 SwFlyFrm* pFly = 0L; 456 const SwFrm* pOldAnch; 457 const SwFrm* pFooterOrHeader = NULL; 458 459 if( bFlyFrame ) 460 { 461 //Bezugspunkt in Dokumentkoordinaten bestimmen 462 SwCntntFrm *pCntnt = GetCurrFrm( sal_False ); 463 if( !pCntnt ) 464 return aRet; 465 pFly = pCntnt->FindFlyFrm(); 466 if ( !pFly ) 467 return aRet; 468 pOldAnch = pFly->GetAnchorFrm(); 469 if( !pOldAnch ) 470 return aRet; 471 if ( FLY_AT_PAGE != nAnchorId ) 472 { 473 pFooterOrHeader = pCntnt->FindFooterOrHeader(); 474 } 475 } 476 // OD 26.06.2003 #108784# - set <pFooterOrHeader> also for drawing 477 // objects, but not for control objects. 478 // Necessary for moving 'anchor symbol' at the user interface inside header/footer. 479 else if ( !::CheckControlLayer( pObj ) ) 480 { 481 SwCntntFrm *pCntnt = GetCurrFrm( sal_False ); 482 if( !pCntnt ) 483 return aRet; 484 pFooterOrHeader = pCntnt->FindFooterOrHeader(); 485 } 486 487 //Ausgehend von der linken oberen Ecke des Fly den 488 //dichtesten SwFlyFrm suchen. 489 SwCntntFrm *pTxtFrm; 490 { 491 SwCrsrMoveState aState( MV_SETONLYTEXT ); 492 SwPosition aPos( GetDoc()->GetNodes().GetEndOfExtras() ); 493 Point aTmpPnt( rAbsPos ); 494 GetLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState ); 495 pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(),0,&aPos,sal_False ); 496 } 497 const SwFrm *pNewAnch; 498 if( pTxtFrm ) 499 { 500 if ( FLY_AT_PAGE == nAnchorId ) 501 { 502 pNewAnch = pTxtFrm->FindPageFrm(); 503 } 504 else 505 { 506 pNewAnch = ::FindAnchor( pTxtFrm, rAbsPos ); 507 508 if( FLY_AT_FLY == nAnchorId ) // LAYER_IMPL 509 { 510 pNewAnch = pNewAnch->FindFlyFrm(); 511 } 512 } 513 } 514 else 515 pNewAnch = 0; 516 517 if( pNewAnch && !pNewAnch->IsProtected() ) 518 { 519 const SwFlyFrm* pCheck = bFlyFrame ? pNewAnch->FindFlyFrm() : 0; 520 // Falls wir innerhalb eines Rahmens landen, muss sichergestellt werden, 521 // dass der Rahmen nicht in seinem eigenen Inhalt landet! 522 while( pCheck ) 523 { 524 if( pCheck == pFly ) 525 break; 526 const SwFrm *pTmp = pCheck->GetAnchorFrm(); 527 pCheck = pTmp ? pTmp->FindFlyFrm() : NULL; 528 } 529 // Es darf nicht aus einer Kopf-/Fusszeile in einen anderen Bereich 530 // gewechselt werden, es darf nicht in eine Kopf-/Fusszeile hinein- 531 // gewechselt werden. 532 if( !pCheck && 533 pFooterOrHeader == pNewAnch->FindFooterOrHeader() ) 534 { 535 aRet = pNewAnch->GetFrmAnchorPos( ::HasWrap( pObj ) ); 536 537 if ( bMoveIt || (nAnchorId == FLY_AT_CHAR) ) 538 { 539 SwFmtAnchor aAnch( rFmt.GetAnchor() ); 540 switch ( nAnchorId ) 541 { 542 case FLY_AT_PARA: 543 { 544 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor(); 545 pPos->nNode = *pTxtFrm->GetNode(); 546 pPos->nContent.Assign(0,0); 547 break; 548 } 549 case FLY_AT_PAGE: 550 { 551 aAnch.SetPageNum( ((const SwPageFrm*)pNewAnch)-> 552 GetPhyPageNum() ); 553 break; 554 } 555 case FLY_AT_FLY: 556 { 557 SwPosition aPos( *((SwFlyFrm*)pNewAnch)->GetFmt()-> 558 GetCntnt().GetCntntIdx() ); 559 aAnch.SetAnchor( &aPos ); 560 break; 561 } 562 case FLY_AT_CHAR: 563 { 564 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor(); 565 Point aTmpPnt( rAbsPos ); 566 if( pTxtFrm->GetCrsrOfst( pPos, aTmpPnt, NULL ) ) 567 { 568 SwRect aTmpRect; 569 pTxtFrm->GetCharRect( aTmpRect, *pPos ); 570 aRet = aTmpRect.Pos(); 571 } 572 else 573 { 574 pPos->nNode = *pTxtFrm->GetNode(); 575 pPos->nContent.Assign(0,0); 576 } 577 break; 578 } 579 default: 580 break; 581 } 582 if( bMoveIt ) 583 { 584 StartAllAction(); 585 // --> OD 2006-02-28 #125892# 586 // handle change of anchor node: 587 // if count of the anchor frame also change, the fly frames have to be 588 // re-created. Thus, delete all fly frames except the <this> before the 589 // anchor attribute is change and re-create them afterwards. 590 { 591 SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L ); 592 SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) ); 593 if ( pFlyFrmFmt ) 594 { 595 pHandleAnchorNodeChg = 596 new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch ); 597 } 598 rFmt.GetDoc()->SetAttr( aAnch, rFmt ); 599 delete pHandleAnchorNodeChg; 600 } 601 // <-- 602 // --> OD 2004-06-24 #i28701# - no call of method 603 // <CheckCharRectAndTopOfLine()> for to-character anchored 604 // Writer fly frame needed. This method call can cause a 605 // format of the anchor frame, which is no longer intended. 606 // Instead clear the anchor character rectangle and 607 // the top of line values for all to-character anchored objects. 608 pAnchoredObj->ClearCharRectAndTopOfLine(); 609 // <-- 610 EndAllAction(); 611 } 612 } 613 614 SwRect aTmpRect( aRet, rAbsPos ); 615 if( aTmpRect.HasArea() ) 616 MakeVisible( aTmpRect ); 617 #ifdef DBG_UTIL 618 //TODO: That doesn't seem to be intended 619 if( Color(COL_TRANSPARENT) != GetOut()->GetLineColor() ) 620 { 621 ASSERT( sal_False, "Hey, Joe: Where's my Null Pen?" ); 622 GetOut()->SetLineColor( Color(COL_TRANSPARENT) ); 623 } 624 #endif 625 } 626 } 627 628 return aRet; 629 } 630 631 /*********************************************************************** 632 #* Class : SwFEShell 633 #* Methode : NewFlyFrm 634 #* Beschreibung: 635 #* Datum : MA 03. Nov. 92 636 #* Update : JP 11. Aug. 93 637 #***********************************************************************/ 638 639 const SwFrmFmt *SwFEShell::NewFlyFrm( const SfxItemSet& rSet, sal_Bool bAnchValid, 640 SwFrmFmt *pParent ) 641 { 642 SET_CURR_SHELL( this ); 643 StartAllAction(); 644 645 SwPaM* pCrsr = GetCrsr(); 646 const Point aPt( GetCrsrDocPos() ); 647 648 SwSelBoxes aBoxes; 649 sal_Bool bMoveCntnt = sal_True; 650 if( IsTableMode() ) 651 { 652 GetTblSel( *this, aBoxes ); 653 if( aBoxes.Count() ) 654 { 655 // die Crsr muessen noch aus dem Loeschbereich entfernt 656 // werden. Setze sie immer hinter/auf die Tabelle; ueber die 657 // Dokument-Position werden sie dann immer an die alte 658 // Position gesetzt. 659 ParkCrsr( SwNodeIndex( *aBoxes[0]->GetSttNd() )); 660 661 // --> FME 2005-12-01 #i127787# pCurCrsr will be deleted in ParkCrsr, 662 // we better get the current pCurCrsr instead of working with the 663 // deleted one: 664 pCrsr = GetCrsr(); 665 // <-- 666 667 // KillPams(); 668 } 669 else 670 bMoveCntnt = sal_False; 671 } 672 else if( !pCrsr->HasMark() && pCrsr->GetNext() == pCrsr ) 673 bMoveCntnt = sal_False; 674 675 const SwPosition& rPos = *pCrsr->Start(); 676 677 SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR ); 678 RndStdIds eRndId = rAnch.GetAnchorId(); 679 switch( eRndId ) 680 { 681 case FLY_AT_PAGE: 682 if( !rAnch.GetPageNum() ) //HotFix: Bug in UpdateByExample 683 rAnch.SetPageNum( 1 ); 684 break; 685 686 case FLY_AT_FLY: 687 case FLY_AT_PARA: 688 case FLY_AT_CHAR: 689 case FLY_AS_CHAR: 690 if( !bAnchValid ) 691 { 692 if( FLY_AT_FLY != eRndId ) 693 { 694 rAnch.SetAnchor( &rPos ); 695 } 696 else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) ) 697 { 698 eRndId = FLY_AT_PAGE; 699 } 700 } 701 break; 702 703 default: 704 ASSERT( !this, "Was sollte das fuer ein Fly werden?" ) 705 break; 706 } 707 708 SwFlyFrmFmt *pRet; 709 if( bMoveCntnt ) 710 { 711 GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL ); 712 SwFmtAnchor* pOldAnchor = 0; 713 sal_Bool bHOriChgd = sal_False, bVOriChgd = sal_False; 714 SwFmtVertOrient aOldV; 715 SwFmtHoriOrient aOldH; 716 717 if ( FLY_AT_PAGE != eRndId ) 718 { 719 // erstmal als mit Seitenbindung, Absatz/Zeichenbindung erst wenn 720 // alles verschoben ist. Dann ist die Position gueltig! 721 // JP 13.05.98: ggfs. auch noch die Hori/Vert-Orientierung 722 // umsetzen, damit diese beim Umanker NICHT 723 // korrigiert wird 724 pOldAnchor = new SwFmtAnchor( rAnch ); 725 const_cast<SfxItemSet&>(rSet).Put( SwFmtAnchor( FLY_AT_PAGE, 1 ) ); 726 727 const SfxPoolItem* pItem; 728 if( SFX_ITEM_SET == rSet.GetItemState( RES_HORI_ORIENT, sal_False, &pItem ) 729 && text::HoriOrientation::NONE == ((SwFmtHoriOrient*)pItem)->GetHoriOrient() ) 730 { 731 bHOriChgd = sal_True; 732 aOldH = *((SwFmtHoriOrient*)pItem); 733 ((SfxItemSet&)rSet).Put( SwFmtHoriOrient( 0, text::HoriOrientation::LEFT ) ); 734 } 735 if( SFX_ITEM_SET == rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem ) 736 && text::VertOrientation::NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() ) 737 { 738 bVOriChgd = sal_True; 739 aOldV = *((SwFmtVertOrient*)pItem); 740 ((SfxItemSet&)rSet).Put( SwFmtVertOrient( 0, text::VertOrientation::TOP ) ); 741 } 742 } 743 744 pRet = GetDoc()->MakeFlyAndMove( *pCrsr, rSet, &aBoxes, pParent ); 745 746 KillPams(); 747 748 if( pOldAnchor ) 749 { 750 if( pRet ) 751 { 752 // neue Position bestimmen 753 //JP 24.03.97: immer ueber die Seitenbindung gehen - der 754 // chaos::Anchor darf nie im verschobenen Bereich 755 // liegen 756 pRet->DelFrms(); 757 758 const SwFrm* pAnch = ::FindAnchor( GetLayout(), aPt, sal_False ); 759 SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() ); 760 if ( FLY_AS_CHAR == eRndId ) 761 { 762 aPos.nContent.Assign( ((SwCntntFrm*)pAnch)->GetNode(), 0 ); 763 } 764 pOldAnchor->SetAnchor( &aPos ); 765 766 // das verschieben von TabelleSelektion ist noch nicht 767 // Undofaehig - also darf das UmAnkern auch nicht 768 // aufgezeichnet werden. 769 bool const bDoesUndo = 770 GetDoc()->GetIDocumentUndoRedo().DoesUndo(); 771 SwUndoId nLastUndoId(UNDO_EMPTY); 772 if (bDoesUndo && 773 GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0, 774 & nLastUndoId)) 775 { 776 if (UNDO_INSLAYFMT == nLastUndoId) 777 { 778 GetDoc()->GetIDocumentUndoRedo().DoUndo(false); 779 } 780 } 781 782 ((SfxItemSet&)rSet).Put( *pOldAnchor ); 783 784 if( bHOriChgd ) 785 ((SfxItemSet&)rSet).Put( aOldH ); 786 if( bVOriChgd ) 787 ((SfxItemSet&)rSet).Put( aOldV ); 788 789 GetDoc()->SetFlyFrmAttr( *pRet, (SfxItemSet&)rSet ); 790 GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo); 791 } 792 delete pOldAnchor; 793 } 794 GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL ); 795 } 796 else 797 /* #109161# If called from a shell try to propagate an 798 existing adjust item from rPos to the content node of the 799 new frame. */ 800 pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent, sal_True ); 801 802 if( pRet ) 803 { 804 SwFlyFrm* pFrm = pRet->GetFrm( &aPt ); 805 if( pFrm ) 806 SelectFlyFrm( *pFrm, sal_True ); 807 else 808 { 809 GetLayout()->SetAssertFlyPages(); 810 pRet = 0; 811 } 812 } 813 EndAllActionAndCall(); 814 815 return pRet; 816 } 817 818 /*********************************************************************** 819 #* Class : SwFEShell 820 #* Methode : Insert 821 #* Datum : ?? 822 #* Update : MA 12. Sep. 94 823 #***********************************************************************/ 824 825 void SwFEShell::Insert( const String& rGrfName, const String& rFltName, 826 const Graphic* pGraphic, 827 const SfxItemSet* pFlyAttrSet, 828 const SfxItemSet* pGrfAttrSet, 829 SwFrmFmt* pFrmFmt ) 830 { 831 SwFlyFrmFmt* pFmt = 0; 832 SET_CURR_SHELL( this ); 833 StartAllAction(); 834 SwShellCrsr *pStartCursor = dynamic_cast<SwShellCrsr*>(this->GetSwCrsr()); 835 SwShellCrsr *pCursor = pStartCursor; 836 do { 837 838 // Anker noch nicht oder unvollstaendig gesetzt ? 839 if( pFlyAttrSet ) 840 { 841 const SfxPoolItem* pItem; 842 if( SFX_ITEM_SET == pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False, 843 &pItem ) ) 844 { 845 SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem; 846 switch( pAnchor->GetAnchorId()) 847 { 848 case FLY_AT_PARA: 849 case FLY_AT_CHAR: // LAYER_IMPL 850 case FLY_AS_CHAR: 851 if( !pAnchor->GetCntntAnchor() ) 852 { 853 pAnchor->SetAnchor( pCursor->GetPoint() ); 854 } 855 break; 856 case FLY_AT_FLY: 857 if( !pAnchor->GetCntntAnchor() ) 858 { 859 lcl_SetNewFlyPos( *pCursor->GetNode(), 860 *pAnchor, GetCrsrDocPos() ); 861 } 862 break; 863 case FLY_AT_PAGE: 864 if( !pAnchor->GetPageNum() ) 865 { 866 pAnchor->SetPageNum( pCursor->GetPageNum( 867 sal_True, &pCursor->GetPtPos() ) ); 868 } 869 break; 870 default : 871 break; 872 } 873 } 874 } 875 pFmt = GetDoc()->Insert(*pCursor, rGrfName, 876 rFltName, pGraphic, 877 pFlyAttrSet, 878 pGrfAttrSet, pFrmFmt ); 879 ASSERT( pFmt, "Doc->Insert(notxt) failed." ); 880 881 } while( (pCursor = dynamic_cast<SwShellCrsr*>(pCursor->GetNext())) 882 != pStartCursor ); 883 884 EndAllAction(); 885 886 if( pFmt ) 887 { 888 const Point aPt( GetCrsrDocPos() ); 889 SwFlyFrm* pFrm = pFmt->GetFrm( &aPt ); 890 891 if( pFrm ) 892 SelectFlyFrm( *pFrm, sal_True ); 893 else 894 GetLayout()->SetAssertFlyPages(); 895 } 896 } 897 898 SwFlyFrmFmt* SwFEShell::InsertObject( const svt::EmbeddedObjectRef& xObj, 899 const SfxItemSet* pFlyAttrSet, 900 const SfxItemSet* pGrfAttrSet, 901 SwFrmFmt* pFrmFmt ) 902 { 903 SwFlyFrmFmt* pFmt = 0; 904 SET_CURR_SHELL( this ); 905 StartAllAction(); 906 FOREACHPAM_START( this ) 907 pFmt = GetDoc()->Insert(*PCURCRSR, xObj, 908 pFlyAttrSet, pGrfAttrSet, pFrmFmt ); 909 ASSERT( pFmt, "Doc->Insert(notxt) failed." ); 910 911 FOREACHPAM_END() 912 EndAllAction(); 913 914 if( pFmt ) 915 { 916 const Point aPt( GetCrsrDocPos() ); 917 SwFlyFrm* pFrm = pFmt->GetFrm( &aPt ); 918 919 if( pFrm ) 920 SelectFlyFrm( *pFrm, sal_True ); 921 else 922 GetLayout()->SetAssertFlyPages(); 923 } 924 925 return pFmt; 926 } 927 928 929 void SwFEShell::InsertDrawObj( SdrObject& rDrawObj, 930 const Point& rInsertPosition ) 931 { 932 SET_CURR_SHELL( this ); 933 934 SfxItemSet rFlyAttrSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange ); 935 rFlyAttrSet.Put( SwFmtAnchor( FLY_AT_PARA )); 936 // --> OD 2009-12-29 #i89920# 937 rFlyAttrSet.Put( SwFmtSurround( SURROUND_THROUGHT ) ); 938 rDrawObj.SetLayer( getIDocumentDrawModelAccess()->GetHeavenId() ); 939 // <-- 940 941 // find anchor position 942 SwPaM aPam( pDoc->GetNodes() ); 943 { 944 SwCrsrMoveState aState( MV_SETONLYTEXT ); 945 Point aTmpPt( rInsertPosition ); 946 GetLayout()->GetCrsrOfst( aPam.GetPoint(), aTmpPt, &aState ); 947 const SwFrm* pFrm = aPam.GetCntntNode()->getLayoutFrm( GetLayout(), 0, 0, sal_False ); 948 const Point aRelPos( rInsertPosition.X() - pFrm->Frm().Left(), 949 rInsertPosition.Y() - pFrm->Frm().Top() ); 950 rDrawObj.SetRelativePos( aRelPos ); 951 ::lcl_FindAnchorPos( *GetDoc(), rInsertPosition, *pFrm, rFlyAttrSet ); 952 } 953 // insert drawing object into the document creating a new <SwDrawFrmFmt> instance 954 SwDrawFrmFmt* pFmt = GetDoc()->Insert( aPam, rDrawObj, &rFlyAttrSet, 0 ); 955 956 // move object to visible layer 957 SwContact* pContact = static_cast<SwContact*>(rDrawObj.GetUserCall()); 958 if ( pContact ) 959 { 960 pContact->MoveObjToVisibleLayer( &rDrawObj ); 961 } 962 963 if ( pFmt ) 964 { 965 // select drawing object 966 Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView(), 967 sal_False, sal_False ); 968 } 969 else 970 { 971 GetLayout()->SetAssertFlyPages(); 972 } 973 } 974 975 /*********************************************************************** 976 #* Class : SwFEShell 977 #* Methode : GetPageObjs 978 #* Datum : ?? 979 #* Update : MA 11. Jan. 95 980 #***********************************************************************/ 981 982 void SwFEShell::GetPageObjs( SvPtrarr& rFillArr ) 983 { 984 if( rFillArr.Count() ) 985 rFillArr.Remove( 0, rFillArr.Count() ); 986 987 const SwFrmFmt* pFmt; 988 for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n ) 989 { 990 pFmt = (const SwFrmFmt*)(*pDoc->GetSpzFrmFmts())[n]; 991 if (FLY_AT_PAGE == pFmt->GetAnchor().GetAnchorId()) 992 { 993 rFillArr.Insert( (VoidPtr)pFmt, rFillArr.Count() ); 994 } 995 } 996 } 997 998 /*********************************************************************** 999 #* Class : SwFEShell 1000 #* Methode : SetPageFlysNewPage 1001 #* Datum : ?? 1002 #* Update : MA 14. Feb. 95 1003 #***********************************************************************/ 1004 1005 void SwFEShell::SetPageObjsNewPage( SvPtrarr& rFillArr, int nOffset ) 1006 { 1007 if( !rFillArr.Count() || !nOffset ) 1008 return; 1009 1010 StartAllAction(); 1011 StartUndo(); 1012 1013 SwFrmFmt* pFmt; 1014 long nNewPage; 1015 SwRootFrm* pTmpRootFrm = GetLayout();//swmod 080317 1016 sal_uInt16 nMaxPage = pTmpRootFrm->GetPageNum(); 1017 sal_Bool bTmpAssert = sal_False; 1018 for( sal_uInt16 n = 0; n < rFillArr.Count(); ++n ) 1019 { 1020 pFmt = (SwFrmFmt*)rFillArr[n]; 1021 if( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pFmt )) 1022 { 1023 // FlyFmt ist noch gueltig, also behandeln 1024 SwFmtAnchor aNewAnchor( pFmt->GetAnchor() ); 1025 if ((FLY_AT_PAGE != aNewAnchor.GetAnchorId()) || 1026 0 >= ( nNewPage = aNewAnchor.GetPageNum() + nOffset ) ) 1027 // chaos::Anchor wurde veraendert oder ungueltige SeitenNummer, 1028 // also nicht veraendern !! 1029 continue; 1030 1031 if( sal_uInt16(nNewPage) > nMaxPage ) 1032 { 1033 if ( RES_DRAWFRMFMT == pFmt->Which() ) 1034 { 1035 SwContact *pCon = pFmt->FindContactObj(); 1036 if( pCon ) 1037 ((SwDrawContact*)pCon)->DisconnectFromLayout(); 1038 } 1039 else 1040 pFmt->DelFrms(); 1041 bTmpAssert = sal_True; 1042 } 1043 aNewAnchor.SetPageNum( sal_uInt16(nNewPage) ); 1044 pDoc->SetAttr( aNewAnchor, *pFmt ); 1045 } 1046 } 1047 1048 if( bTmpAssert ) 1049 pTmpRootFrm->SetAssertFlyPages(); 1050 1051 EndUndo(); 1052 EndAllAction(); 1053 } 1054 1055 /*********************************************************************** 1056 #* Class : SwFEShell 1057 #* Methode : GetFlyFrmAttr 1058 #* Beschreibung: Alle Attribute in dem 'Koerbchen' werden mit den 1059 #* Attributen des aktuellen FlyFrms gefuellt. 1060 #* Sind Attribute nicht zu fuellen weil fehl am Platz oder 1061 #* uneindeutig (Mehrfachtselektionen) so werden sie entfernt. 1062 #* Datum : MA 03. Nov. 92 1063 #* Update : MA 03. Feb. 94 1064 #***********************************************************************/ 1065 1066 sal_Bool SwFEShell::GetFlyFrmAttr( SfxItemSet &rSet ) const 1067 { 1068 SwFlyFrm *pFly = FindFlyFrm(); 1069 if ( !pFly ) 1070 { 1071 // --> OD 2006-11-08 #139670# - make code robust 1072 SwFrm* pCurrFrm( GetCurrFrm() ); 1073 if ( !pCurrFrm ) 1074 { 1075 ASSERT( false, 1076 "<SwFEShell::GetFlyFrmAttr(..)> - missing current frame. This is a serious defect, please inform OD." ); 1077 return sal_False; 1078 } 1079 // <-- 1080 pFly = GetCurrFrm()->FindFlyFrm(); 1081 if ( !pFly ) 1082 { 1083 ASSERT( !this, "GetFlyFrmAttr, no Fly selected." ); 1084 return sal_False; 1085 } 1086 } 1087 1088 SET_CURR_SHELL( (ViewShell*)this ); 1089 1090 if( !rSet.Set( pFly->GetFmt()->GetAttrSet(), sal_True ) ) 1091 return sal_False; 1092 1093 //Und die Attribute durchschaufeln. Unerlaubte Attribute entfernen, dann 1094 //alle restlichen Attribute besorgen und eintragen. 1095 const SfxPoolItem* pItem; 1096 if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False, &pItem ) ) 1097 { 1098 SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem; 1099 RndStdIds eType = pAnchor->GetAnchorId(); 1100 1101 if ( FLY_AT_PAGE != eType ) 1102 { 1103 // OD 12.11.2003 #i22341# - content anchor of anchor item is needed. 1104 // Thus, don't overwrite anchor item by default contructed anchor item. 1105 //rSet.Put( SwFmtAnchor( eType ) ); 1106 if ( FLY_AS_CHAR == eType ) 1107 { 1108 rSet.ClearItem( RES_OPAQUE ); 1109 rSet.ClearItem( RES_SURROUND ); 1110 } 1111 } 1112 } 1113 rSet.SetParent( pFly->GetFmt()->GetAttrSet().GetParent() ); 1114 //JP 11.02.97: Bug #35894#: die Attribute MUESSEN entfern werden! 1115 rSet.ClearItem( RES_FILL_ORDER ); 1116 rSet.ClearItem( RES_CNTNT ); 1117 //MA: Ersteinmal entfernen (Template by example usw.) 1118 rSet.ClearItem( RES_CHAIN ); 1119 return sal_True; 1120 } 1121 /*********************************************************************** 1122 #* Class : SwFEShell 1123 #* Methode : SetFlyFrmAttr 1124 #* Beschreibung: Die Attribute des aktuellen Flys aendern sich. 1125 #* Datum : MA 03. Nov. 92 1126 #* Update : MA 01. Aug. 95 1127 #***********************************************************************/ 1128 1129 sal_Bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet ) 1130 { 1131 SET_CURR_SHELL( this ); 1132 sal_Bool bRet = sal_False; 1133 1134 if( rSet.Count() ) 1135 { 1136 SwFlyFrm *pFly = FindFlyFrm(); 1137 if( !pFly ) 1138 { 1139 ASSERT( GetCurrFrm(), "Crsr in parking zone" ); 1140 pFly = GetCurrFrm()->FindFlyFrm(); 1141 ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." ); 1142 } 1143 if( pFly ) 1144 { 1145 StartAllAction(); 1146 const Point aPt( pFly->Frm().Pos() ); 1147 1148 if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False )) 1149 ::lcl_ChkAndSetNewAnchor( *pFly, rSet ); 1150 SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt(); 1151 1152 if( GetDoc()->SetFlyFrmAttr( *pFlyFmt, rSet )) 1153 { 1154 bRet = sal_True; 1155 SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt ); 1156 if( pFrm ) 1157 SelectFlyFrm( *pFrm, sal_True ); 1158 else 1159 GetLayout()->SetAssertFlyPages(); 1160 } 1161 1162 EndAllActionAndCall(); 1163 } 1164 } 1165 return bRet; 1166 } 1167 /*-- 30.03.2004 15:05:07--------------------------------------------------- 1168 1169 -----------------------------------------------------------------------*/ 1170 sal_Bool SwFEShell::SetDrawingAttr( SfxItemSet& rSet ) 1171 { 1172 sal_Bool bRet = sal_False; 1173 SET_CURR_SHELL( this ); 1174 if ( !rSet.Count() || 1175 !Imp()->HasDrawView() ) 1176 return bRet; 1177 1178 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1179 if ( rMrkList.GetMarkCount() != 1 ) 1180 return bRet; 1181 1182 StartUndo(); 1183 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 1184 SwFrmFmt *pFmt = FindFrmFmt( pObj ); 1185 StartAllAction(); 1186 if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False )) 1187 { 1188 RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId(); 1189 if ( nNew != pFmt->GetAnchor().GetAnchorId() ) 1190 { 1191 ChgAnchor( nNew ); 1192 // --> OD 2004-06-17 #i26791# - clear anchor attribute in item set, 1193 // because method <ChgAnchor(..)> takes care of it. 1194 rSet.ClearItem( RES_ANCHOR ); 1195 } 1196 } 1197 1198 if( GetDoc()->SetFlyFrmAttr( *pFmt, rSet )) 1199 { 1200 bRet = sal_True; 1201 Point aTmp; 1202 SelectObj( aTmp, 0, pObj ); 1203 } 1204 EndAllActionAndCall(); 1205 EndUndo(); 1206 return bRet; 1207 } 1208 1209 1210 /*********************************************************************** 1211 #* Class : SwFEShell 1212 #* Methode : ResetFlyFrmAttr 1213 #* Beschreibung: Das gewuenschte Attribut oder die im Set befindlichen 1214 #* werden zurueckgesetzt. 1215 #* Datum : MA 14. Mar. 97 1216 #* Update : MA 14. Mar. 97 1217 #***********************************************************************/ 1218 1219 sal_Bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet ) 1220 { 1221 sal_Bool bRet = sal_False; 1222 1223 if( RES_ANCHOR != nWhich && RES_CHAIN != nWhich && RES_CNTNT != nWhich ) 1224 { 1225 SET_CURR_SHELL( this ); 1226 1227 SwFlyFrm *pFly = FindFlyFrm(); 1228 if( !pFly ) 1229 { 1230 ASSERT( GetCurrFrm(), "Crsr in parking zone" ); 1231 pFly = GetCurrFrm()->FindFlyFrm(); 1232 ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." ); 1233 } 1234 1235 if( pFly ) 1236 { 1237 StartAllAction(); 1238 1239 if( pSet ) 1240 { 1241 SfxItemIter aIter( *pSet ); 1242 const SfxPoolItem* pItem = aIter.FirstItem(); 1243 while( pItem ) 1244 { 1245 if( !IsInvalidItem( pItem ) && 1246 RES_ANCHOR != ( nWhich = pItem->Which() ) && 1247 RES_CHAIN != nWhich && RES_CNTNT != nWhich ) 1248 pFly->GetFmt()->ResetFmtAttr( nWhich ); 1249 pItem = aIter.NextItem(); 1250 } 1251 } 1252 else 1253 pFly->GetFmt()->ResetFmtAttr( nWhich ); 1254 1255 bRet = sal_True; 1256 EndAllActionAndCall(); 1257 GetDoc()->SetModified(); 1258 } 1259 } 1260 return bRet; 1261 } 1262 1263 /*********************************************************************** 1264 #* Class : SwFEShell 1265 #* Methode : GetCurFrmFmt 1266 #* Beschreibung: liefert wenn Rahmen, dann Rahmenvorlage, sonst 0 1267 #* Datum : ST 04. Jun. 93 1268 #* Update : 1269 #***********************************************************************/ 1270 1271 SwFrmFmt* SwFEShell::GetCurFrmFmt() const 1272 { 1273 SwFrmFmt* pRet = 0; 1274 SwLayoutFrm *pFly = FindFlyFrm(); 1275 if( pFly && ( pRet = (SwFrmFmt*)pFly->GetFmt()->DerivedFrom() ) == 1276 GetDoc()->GetDfltFrmFmt() ) 1277 pRet = 0; 1278 return pRet; 1279 } 1280 1281 /****************************************************************************** 1282 * Methode : void SwFEShell::SetFrmFmt(SwFrmFmt *pNewFmt) 1283 * Beschreibung: 1284 * Erstellt : OK 14.04.94 15:40 1285 * Aenderung : MA 23. Apr. 97 1286 ******************************************************************************/ 1287 1288 void SwFEShell::SetFrmFmt( SwFrmFmt *pNewFmt, sal_Bool bKeepOrient, Point* pDocPos ) 1289 { 1290 SwFlyFrm *pFly = 0; 1291 if(pDocPos) 1292 { 1293 const SwFrmFmt* pFmt = GetFmtFromObj( *pDocPos ); 1294 1295 if(PTR_CAST(SwFlyFrmFmt, pFmt)) 1296 pFly = ((SwFlyFrmFmt*)pFmt)->GetFrm(); 1297 } 1298 else 1299 pFly = FindFlyFrm(); 1300 ASSERT( pFly, "SetFrmFmt: kein Frame" ); 1301 if( pFly ) 1302 { 1303 StartAllAction(); 1304 SET_CURR_SHELL( this ); 1305 1306 SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt(); 1307 const Point aPt( pFly->Frm().Pos() ); 1308 1309 SfxItemSet* pSet = 0; 1310 const SfxPoolItem* pItem; 1311 if( SFX_ITEM_SET == pNewFmt->GetItemState( RES_ANCHOR, sal_False, &pItem )) 1312 { 1313 pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange ); 1314 pSet->Put( *pItem ); 1315 if( !::lcl_ChkAndSetNewAnchor( *pFly, *pSet )) 1316 delete pSet, pSet = 0; 1317 } 1318 1319 if( GetDoc()->SetFrmFmtToFly( *pFlyFmt, *pNewFmt, pSet, bKeepOrient )) 1320 { 1321 SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt ); 1322 if( pFrm ) 1323 SelectFlyFrm( *pFrm, sal_True ); 1324 else 1325 GetLayout()->SetAssertFlyPages(); 1326 } 1327 if( pSet ) 1328 delete pSet; 1329 1330 EndAllActionAndCall(); 1331 } 1332 } 1333 1334 /************************************************************************* 1335 |* 1336 |* SwFEShell::GetFlyFrmFmt() 1337 |* 1338 |* Ersterstellung OK 23.06.93 13:15 1339 |* Letzte Aenderung OK 23.06.93 13:15 1340 |* 1341 *************************************************************************/ 1342 1343 const SwFrmFmt* SwFEShell::GetFlyFrmFmt() const 1344 { 1345 const SwFlyFrm* pFly = FindFlyFrm(); 1346 if ( !pFly ) 1347 { 1348 SwFrm* pCurrFrm = GetCurrFrm(); 1349 pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0; 1350 } 1351 if( pFly ) 1352 return pFly->GetFmt(); 1353 return 0; 1354 } 1355 1356 SwFrmFmt* SwFEShell::GetFlyFrmFmt() 1357 { 1358 SwFlyFrm* pFly = FindFlyFrm(); 1359 if ( !pFly ) 1360 { 1361 SwFrm* pCurrFrm = GetCurrFrm(); 1362 pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0; 1363 } 1364 if( pFly ) 1365 return pFly->GetFmt(); 1366 return 0; 1367 } 1368 1369 /************************************************************************* 1370 |* 1371 |* SwFEShell::GetFlyRect() 1372 |* 1373 |* Ersterstellung AMA 6. Mae. 97 1374 |* Letzte Aenderung AMA 6. Mae. 97 1375 |* 1376 *************************************************************************/ 1377 1378 SwRect SwFEShell::GetFlyRect() const 1379 { 1380 SwCntntFrm *pCntnt = GetCurrFrm( sal_False ); 1381 SwFlyFrm *pFly = pCntnt ? pCntnt->FindFlyFrm() : 0; 1382 if ( !pFly ) 1383 { 1384 SwRect aRect; 1385 return aRect; 1386 } 1387 else 1388 return pFly->Frm(); 1389 } 1390 1391 /************************************************************************* 1392 |* 1393 |* SwFEShell::GetObjRect() 1394 |* 1395 |* Ersterstellung MA 22. Aug. 93 1396 |* Letzte Aenderung MA 11. Jan. 95 1397 |* 1398 *************************************************************************/ 1399 1400 SwRect SwFEShell::GetObjRect() const 1401 { 1402 if( Imp()->HasDrawView() ) 1403 return Imp()->GetDrawView()->GetAllMarkedRect(); 1404 else 1405 { 1406 SwRect aRect; 1407 return aRect; 1408 } 1409 } 1410 1411 void SwFEShell::SetObjRect( const SwRect& rRect ) 1412 { 1413 if ( Imp()->HasDrawView() ) 1414 { 1415 Imp()->GetDrawView()->SetAllMarkedRect( rRect.SVRect() ); 1416 CallChgLnk(); // rufe das AttrChangeNotify auf der UI-Seite. 1417 } 1418 } 1419 1420 /*********************************************************************** 1421 #* Class : SwFEShell 1422 #* Methode : RequestObjectResize() 1423 #* Datum : MA 10. Feb. 95 1424 #* Update : MA 13. Jul. 95 1425 #***********************************************************************/ 1426 1427 Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference < embed::XEmbeddedObject >& xObj ) 1428 { 1429 Size aResult; 1430 1431 SwFlyFrm *pFly = FindFlyFrm( xObj ); 1432 if ( !pFly ) 1433 { 1434 aResult = rRect.SSize(); 1435 return aResult; 1436 } 1437 1438 aResult = pFly->Prt().SSize(); 1439 1440 sal_Bool bPosProt = pFly->GetFmt()->GetProtect().IsPosProtected(); 1441 sal_Bool bSizeProt = pFly->GetFmt()->GetProtect().IsSizeProtected(); 1442 1443 StartAllAction(); 1444 1445 //MA wir lassen den Fly nicht Clippen, damit die Ole-Server mit 1446 //beliebigen Wuenschen kommen koennen. Die Formatierung uebernimmt das 1447 //Clippen. Die richtige Darstellung wird per Scalierung erledigt. 1448 //Die Scalierung wird von SwNoTxtFrm::Format durch einen Aufruf von 1449 //SwWrtShell::CalcAndSetScale() erledigt. 1450 if ( rRect.SSize() != pFly->Prt().SSize() && !bSizeProt ) 1451 { 1452 Size aSz( rRect.SSize() ); 1453 1454 //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size 1455 // 1456 const SwFrm* pAnchor; 1457 const SwTxtNode* pTNd; 1458 const SwpHints* pHts; 1459 const SwFmtFrmSize& rFrmSz = pFly->GetFmt()->GetFrmSize(); 1460 if( bCheckForOLEInCaption && 1461 0 != rFrmSz.GetWidthPercent() && 1462 0 != (pAnchor = pFly->GetAnchorFrm()) && 1463 pAnchor->IsTxtFrm() && 1464 !pAnchor->GetNext() && !pAnchor->GetPrev() && 1465 pAnchor->GetUpper()->IsFlyFrm() && 1466 0 != ( pTNd = ((SwTxtFrm*)pAnchor)->GetNode()->GetTxtNode()) && 1467 0 != ( pHts = pTNd->GetpSwpHints() )) 1468 { 1469 // search for a sequence field: 1470 const SfxPoolItem* pItem; 1471 for( sal_uInt16 n = 0, nEnd = pHts->Count(); n < nEnd; ++n ) 1472 if( RES_TXTATR_FIELD == ( pItem = 1473 &(*pHts)[ n ]->GetAttr())->Which() && 1474 TYP_SEQFLD == ((SwFmtFld*)pItem)->GetFld()->GetTypeId() ) 1475 { 1476 // sequence field found 1477 SwFlyFrm* pChgFly = (SwFlyFrm*)pAnchor->GetUpper(); 1478 // calculate the changed size: 1479 // width must change, height can change 1480 Size aNewSz( aSz.Width() + pChgFly->Frm().Width() - 1481 pFly->Prt().Width(), aSz.Height() ); 1482 1483 SwFrmFmt *pFmt = pChgFly->GetFmt(); 1484 SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() ); 1485 aFrmSz.SetWidth( aNewSz.Width() ); 1486 if( ATT_MIN_SIZE != aFrmSz.GetHeightSizeType() ) 1487 { 1488 aNewSz.Height() += pChgFly->Frm().Height() - 1489 pFly->Prt().Height(); 1490 if( Abs( aNewSz.Height() - pChgFly->Frm().Height()) > 1 ) 1491 aFrmSz.SetHeight( aNewSz.Height() ); 1492 } 1493 // uebers Doc fuers Undo! 1494 pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt ); 1495 break; 1496 } 1497 } 1498 1499 // set the new Size at the fly themself 1500 if ( pFly->Prt().Height() > 0 && pFly->Prt().Width() > 0 ) 1501 { 1502 aSz.Width() += pFly->Frm().Width() - pFly->Prt().Width(); 1503 aSz.Height()+= pFly->Frm().Height()- pFly->Prt().Height(); 1504 } 1505 aResult = pFly->ChgSize( aSz ); 1506 1507 //Wenn sich das Objekt aendert ist die Kontur hoechstwahrscheinlich daneben. 1508 ASSERT( pFly->Lower()->IsNoTxtFrm(), "Request ohne NoTxt" ); 1509 SwNoTxtNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetNoTxtNode(); 1510 ASSERT( pNd, "Request ohne Node" ); 1511 pNd->SetContour( 0 ); 1512 ClrContourCache(); 1513 } 1514 1515 //Wenn nur die Size angepasst werden soll, so wird eine Pos mit 1516 //ausgezeichneten Werten transportiert. 1517 Point aPt( pFly->Prt().Pos() ); 1518 aPt += pFly->Frm().Pos(); 1519 if ( rRect.Top() != LONG_MIN && rRect.Pos() != aPt && !bPosProt ) 1520 { 1521 aPt = rRect.Pos(); 1522 aPt.X() -= pFly->Prt().Left(); 1523 aPt.Y() -= pFly->Prt().Top(); 1524 //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein 1525 //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly 1526 //selbst berechnet und gesetzt. 1527 if( pFly->IsFlyAtCntFrm() ) 1528 ((SwFlyAtCntFrm*)pFly)->SetAbsPos( aPt ); 1529 else 1530 { 1531 const SwFrmFmt *pFmt = pFly->GetFmt(); 1532 const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); 1533 const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient(); 1534 const long lXDiff = aPt.X() - pFly->Frm().Left(); 1535 const long lYDiff = aPt.Y() - pFly->Frm().Top(); 1536 const Point aTmp( rHori.GetPos() + lXDiff, 1537 rVert.GetPos() + lYDiff ); 1538 pFly->ChgRelPos( aTmp ); 1539 } 1540 } 1541 1542 SwFlyFrmFmt *pFlyFrmFmt = pFly->GetFmt(); 1543 ASSERT( pFlyFrmFmt, "fly frame format missing!" ); 1544 if ( pFlyFrmFmt ) 1545 pFlyFrmFmt->SetLastFlyFrmPrtRectPos( pFly->Prt().Pos() ); //stores the value of last Prt rect 1546 1547 EndAllAction(); 1548 1549 return aResult; 1550 } 1551 1552 1553 /*********************************************************************** 1554 #* Class : SwFEShell 1555 #* Methode : WizzardFindCurFrmFmt 1556 #* Datum : JP 31.07.95 1557 #* Update : JP 31.07.95 1558 #***********************************************************************/ 1559 1560 SwFrmFmt* SwFEShell::WizzardGetFly() 1561 { 1562 // mal nicht uebers Layout den Fly suchen. Dann kann auch ohne gueltiges 1563 // Layout ein Rahmen geloescht werden. ( z.B.: fuer die Wizard's ) 1564 SwSpzFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts(); 1565 sal_uInt16 nCnt = rSpzArr.Count(); 1566 if( nCnt ) 1567 { 1568 SwNodeIndex& rCrsrNd = GetCrsr()->GetPoint()->nNode; 1569 if( rCrsrNd.GetIndex() > pDoc->GetNodes().GetEndOfExtras().GetIndex() ) 1570 // Cusor steht im Body-Bereich! 1571 return 0; 1572 1573 for( sal_uInt16 n = 0; n < nCnt; ++n ) 1574 { 1575 SwFrmFmt* pFmt = rSpzArr[ n ]; 1576 const SwNodeIndex* pIdx = pFmt->GetCntnt( sal_False ).GetCntntIdx(); 1577 SwStartNode* pSttNd; 1578 if( pIdx && 1579 0 != ( pSttNd = pIdx->GetNode().GetStartNode() ) && 1580 pSttNd->GetIndex() < rCrsrNd.GetIndex() && 1581 rCrsrNd.GetIndex() < pSttNd->EndOfSectionIndex() ) 1582 { 1583 // gefunden: also raus damit 1584 return pFmt; 1585 } 1586 } 1587 } 1588 return 0; 1589 } 1590 1591 void SwFEShell::SetFlyName( const String& rName ) 1592 { 1593 SwLayoutFrm *pFly = FindFlyFrm(); 1594 if( pFly ) 1595 GetDoc()->SetFlyName( *(SwFlyFrmFmt*)pFly->GetFmt(), rName ); 1596 else { 1597 ASSERT( !this, "kein FlyFrame selektiert" ) 1598 } 1599 } 1600 1601 const String& SwFEShell::GetFlyName() const 1602 { 1603 SwLayoutFrm *pFly = FindFlyFrm(); 1604 if( pFly ) 1605 return pFly->GetFmt()->GetName(); 1606 1607 ASSERT( !this, "kein FlyFrame selektiert" ) 1608 return aEmptyStr; 1609 } 1610 1611 1612 const uno::Reference < embed::XEmbeddedObject > SwFEShell::GetOleRef() const 1613 { 1614 uno::Reference < embed::XEmbeddedObject > xObj; 1615 SwFlyFrm * pFly = FindFlyFrm(); 1616 if (pFly && pFly->Lower() && pFly->Lower()->IsNoTxtFrm()) 1617 { 1618 SwOLENode *pNd = ((SwNoTxtFrm*)pFly->Lower())->GetNode()->GetOLENode(); 1619 if (pNd) 1620 xObj = pNd->GetOLEObj().GetOleRef(); 1621 } 1622 return xObj; 1623 } 1624 1625 1626 String SwFEShell::GetUniqueGrfName() const 1627 { 1628 return GetDoc()->GetUniqueGrfName(); 1629 } 1630 1631 const SwFrmFmt* SwFEShell::IsURLGrfAtPos( const Point& rPt, String* pURL, 1632 String *pTargetFrameName, 1633 String *pDescription ) const 1634 { 1635 if( !Imp()->HasDrawView() ) 1636 return 0; 1637 1638 SdrObject* pObj; 1639 SdrPageView* pPV; 1640 const SwFrmFmt* pRet = 0; 1641 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 1642 1643 sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 1644 pDView->SetHitTolerancePixel( 2 ); 1645 1646 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV,SDRSEARCH_PICKMACRO ) && 1647 pObj->ISA(SwVirtFlyDrawObj) ) 1648 { 1649 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 1650 const SwFmtURL &rURL = pFly->GetFmt()->GetURL(); 1651 if( rURL.GetURL().Len() || rURL.GetMap() ) 1652 { 1653 sal_Bool bSetTargetFrameName = pTargetFrameName != 0; 1654 sal_Bool bSetDescription = pDescription != 0; 1655 if ( rURL.GetMap() ) 1656 { 1657 IMapObject *pObject = pFly->GetFmt()->GetIMapObject( rPt, pFly ); 1658 if ( pObject && pObject->GetURL().Len() ) 1659 { 1660 if( pURL ) 1661 *pURL = pObject->GetURL(); 1662 if ( bSetTargetFrameName && pObject->GetTarget().Len() ) 1663 { 1664 bSetTargetFrameName = sal_False; 1665 *pTargetFrameName = pObject->GetTarget(); 1666 } 1667 if ( bSetDescription ) 1668 { 1669 bSetDescription = sal_False; 1670 *pDescription = pObject->GetAltText(); 1671 } 1672 pRet = pFly->GetFmt(); 1673 } 1674 } 1675 else 1676 { 1677 if( pURL ) 1678 { 1679 *pURL = rURL.GetURL(); 1680 if( rURL.IsServerMap() ) 1681 { 1682 // dann die rel. Pixel Position anhaengen !! 1683 Point aPt( rPt ); 1684 aPt -= pFly->Frm().Pos(); 1685 // ohne MapMode-Offset, ohne Offset, o ... !!!!! 1686 aPt = GetOut()->LogicToPixel( 1687 aPt, MapMode( MAP_TWIP ) ); 1688 ((( *pURL += '?' ) += String::CreateFromInt32( aPt.X() )) 1689 += ',' ) += String::CreateFromInt32(aPt.Y() ); 1690 } 1691 } 1692 pRet = pFly->GetFmt(); 1693 } 1694 if ( bSetTargetFrameName ) 1695 *pTargetFrameName = rURL.GetTargetFrameName(); 1696 if ( bSetDescription ) 1697 *pDescription = pFly->GetFmt()->GetName(); 1698 } 1699 } 1700 pDView->SetHitTolerancePixel( nOld ); 1701 return pRet; 1702 } 1703 1704 const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt, 1705 String &rName, sal_Bool &rbLink ) const 1706 { 1707 if( !Imp()->HasDrawView() ) 1708 return 0; 1709 1710 SdrObject* pObj; 1711 SdrPageView* pPV; 1712 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 1713 1714 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV ) && pObj->ISA(SwVirtFlyDrawObj) ) 1715 { 1716 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 1717 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() ) 1718 { 1719 SwGrfNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode(); 1720 if ( pNd ) 1721 { 1722 if ( pNd->IsGrfLink() ) 1723 { 1724 //Halbfertige Grafik? 1725 ::sfx2::SvLinkSource* pLnkObj = pNd->GetLink()->GetObj(); 1726 if( pLnkObj && pLnkObj->IsPending() ) 1727 return 0; 1728 rbLink = sal_True; 1729 } 1730 1731 pNd->GetFileFilterNms( &rName, 0 ); 1732 if ( !rName.Len() ) 1733 rName = pFly->GetFmt()->GetName(); 1734 pNd->SwapIn( sal_True ); 1735 return &pNd->GetGrf(); 1736 } 1737 } 1738 } 1739 return 0; 1740 } 1741 1742 1743 const SwFrmFmt* SwFEShell::GetFmtFromObj( const Point& rPt, SwRect** pRectToFill ) const 1744 { 1745 SwFrmFmt* pRet = 0; 1746 1747 if( Imp()->HasDrawView() ) 1748 { 1749 SdrObject* pObj; 1750 SdrPageView* pPView; 1751 1752 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 1753 1754 sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 1755 // Tattergrenze fuer Drawing-SS 1756 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 ); 1757 1758 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) ) 1759 { 1760 // dann teste mal was es ist: 1761 if ( pObj->ISA(SwVirtFlyDrawObj) ) 1762 pRet = ((SwVirtFlyDrawObj*)pObj)->GetFmt(); 1763 else if ( pObj->GetUserCall() ) //nicht fuer Gruppenobjekte 1764 pRet = ((SwDrawContact*)pObj->GetUserCall())->GetFmt(); 1765 if(pRet && pRectToFill) 1766 **pRectToFill = pObj->GetCurrentBoundRect(); 1767 } 1768 pDView->SetHitTolerancePixel( nOld ); 1769 } 1770 return pRet; 1771 } 1772 1773 // returns a format too, if the point is over the text of any fly 1774 const SwFrmFmt* SwFEShell::GetFmtFromAnyObj( const Point& rPt ) const 1775 { 1776 const SwFrmFmt* pRet = GetFmtFromObj( rPt ); 1777 if( !pRet || RES_FLYFRMFMT == pRet->Which() ) 1778 { 1779 SwPosition aPos( *GetCrsr()->GetPoint() ); 1780 Point aPt( rPt ); 1781 GetLayout()->GetCrsrOfst( &aPos, aPt ); 1782 SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode(); 1783 SwFrm* pFrm = pNd->getLayoutFrm( GetLayout(), &rPt, 0, sal_False )->FindFlyFrm(); 1784 pRet = pFrm ? ((SwLayoutFrm*)pFrm)->GetFmt() : 0; 1785 } 1786 return pRet; 1787 } 1788 1789 ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj ) const 1790 { 1791 ObjCntType eType = OBJCNT_NONE; 1792 1793 // OD 23.06.2003 #108784# - investigate 'master' drawing object, if method 1794 // is called for a 'virtual' drawing object. 1795 const SdrObject* pInvestigatedObj; 1796 if ( rObj.ISA(SwDrawVirtObj) ) 1797 { 1798 const SwDrawVirtObj* pDrawVirtObj = static_cast<const SwDrawVirtObj*>(&rObj); 1799 pInvestigatedObj = &(pDrawVirtObj->GetReferencedObj()); 1800 } 1801 else 1802 { 1803 pInvestigatedObj = &rObj; 1804 } 1805 1806 if( FmFormInventor == pInvestigatedObj->GetObjInventor() ) 1807 { 1808 eType = OBJCNT_CONTROL; 1809 uno::Reference< awt::XControlModel > xModel = 1810 ((SdrUnoObj&)(*pInvestigatedObj)).GetUnoControlModel(); 1811 if( xModel.is() ) 1812 { 1813 uno::Any aVal; 1814 OUString sName = OUString::createFromAscii("ButtonType"); 1815 uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY); 1816 1817 uno::Reference< beans::XPropertySetInfo > xInfo = xSet->getPropertySetInfo(); 1818 if(xInfo->hasPropertyByName( sName )) 1819 { 1820 beans::Property xProperty = xInfo->getPropertyByName( sName ); 1821 aVal = xSet->getPropertyValue( sName ); 1822 if( aVal.getValue() && form::FormButtonType_URL == *((form::FormButtonType*)aVal.getValue()) ) 1823 eType = OBJCNT_URLBUTTON; 1824 } 1825 } 1826 } 1827 else if( pInvestigatedObj->ISA(SwVirtFlyDrawObj) ) 1828 { 1829 SwFlyFrm *pFly = ((SwVirtFlyDrawObj&)(*pInvestigatedObj)).GetFlyFrm(); 1830 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() ) 1831 { 1832 if ( ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode() ) 1833 eType = OBJCNT_GRF; 1834 else 1835 eType = OBJCNT_OLE; 1836 } 1837 else 1838 eType = OBJCNT_FLY; 1839 } 1840 else if ( pInvestigatedObj->ISA( SdrObjGroup ) ) 1841 { 1842 SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(GetUserCall( pInvestigatedObj ) ) ); 1843 if ( !pDrawContact ) 1844 { 1845 ASSERT( false, 1846 "<SwFEShell::GetObjCntType(..)> - missing draw contact object" ); 1847 eType = OBJCNT_NONE; 1848 } 1849 else 1850 { 1851 SwFrmFmt* pFrmFmt( pDrawContact->GetFmt() ); 1852 if ( !pFrmFmt ) 1853 { 1854 ASSERT( false, 1855 "<SwFEShell::GetObjCntType(..)> - missing frame format" ); 1856 eType = OBJCNT_NONE; 1857 } 1858 else if ( FLY_AS_CHAR != pFrmFmt->GetAnchor().GetAnchorId() ) 1859 { 1860 eType = OBJCNT_GROUPOBJ; 1861 } 1862 } 1863 } 1864 else 1865 eType = OBJCNT_SIMPLE; 1866 return eType; 1867 } 1868 1869 ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const 1870 { 1871 ObjCntType eType = OBJCNT_NONE; 1872 1873 if( Imp()->HasDrawView() ) 1874 { 1875 SdrObject* pObj; 1876 SdrPageView* pPView; 1877 1878 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView(); 1879 1880 sal_uInt16 nOld = pDView->GetHitTolerancePixel(); 1881 // Tattergrenze fuer Drawing-SS 1882 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 ); 1883 1884 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) ) 1885 eType = GetObjCntType( *(rpObj = pObj) ); 1886 1887 pDView->SetHitTolerancePixel( nOld ); 1888 } 1889 return eType; 1890 } 1891 1892 ObjCntType SwFEShell::GetObjCntTypeOfSelection( SdrObject** ppObj ) const 1893 { 1894 ObjCntType eType = OBJCNT_NONE; 1895 1896 if( Imp()->HasDrawView() ) 1897 { 1898 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1899 for( sal_uInt32 i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i ) 1900 { 1901 SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 1902 if( !pObj ) 1903 continue; 1904 ObjCntType eTmp = GetObjCntType( *pObj ); 1905 if( !i ) 1906 { 1907 eType = eTmp; 1908 if( ppObj ) *ppObj = pObj; 1909 } 1910 else if( eTmp != eType ) 1911 { 1912 eType = OBJCNT_DONTCARE; 1913 // einmal DontCare, immer DontCare! 1914 break; 1915 } 1916 } 1917 } 1918 return eType; 1919 } 1920 1921 1922 sal_Bool SwFEShell::ReplaceSdrObj( const String& rGrfName, const String& rFltName, 1923 const Graphic* pGrf ) 1924 { 1925 SET_CURR_SHELL( this ); 1926 1927 sal_Bool bRet = sal_False; 1928 const SdrMarkList *pMrkList; 1929 if( Imp()->HasDrawView() && 1 == 1930 ( pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount() ) 1931 { 1932 SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 1933 SwFrmFmt *pFmt = FindFrmFmt( pObj ); 1934 1935 // Attribute sichern und dann an der Grafik setzen 1936 SfxItemSet aFrmSet( pDoc->GetAttrPool(), 1937 pFmt->GetAttrSet().GetRanges() ); 1938 aFrmSet.Set( pFmt->GetAttrSet() ); 1939 1940 // Groesse und Position setzen ?? 1941 if( !pObj->ISA(SwVirtFlyDrawObj) ) 1942 { 1943 // dann mal los: 1944 const Rectangle &rBound = pObj->GetSnapRect(); 1945 Point aRelPos( pObj->GetRelativePos() ); 1946 1947 const long nWidth = rBound.Right() - rBound.Left(); 1948 const long nHeight= rBound.Bottom() - rBound.Top(); 1949 aFrmSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, 1950 Max( nWidth, long(MINFLY) ), 1951 Max( nHeight, long(MINFLY) ))); 1952 1953 if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_HORI_ORIENT )) 1954 aFrmSet.Put( SwFmtHoriOrient( aRelPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME )); 1955 1956 if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_VERT_ORIENT )) 1957 aFrmSet.Put( SwFmtVertOrient( aRelPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME )); 1958 1959 } 1960 1961 pObj->GetOrdNum(); 1962 1963 StartAllAction(); 1964 StartUndo(); 1965 1966 // das "Sdr-Object" loeschen und dafuer die Grafik einfuegen 1967 DelSelectedObj(); 1968 1969 pFmt = GetDoc()->Insert( *GetCrsr(), rGrfName, rFltName, pGrf, &aFrmSet, NULL, NULL ); 1970 1971 // die Ordnungsnummer (Z-Order) noch uebertragen 1972 // JP 04.07.98: klappt aber nicht richtig! 1973 //SdrObject* pNewObj = ::FindSdrObject( pFmt ); 1974 //pNewObj->SetOrdNum( nOrdNum ); 1975 1976 EndUndo(); 1977 EndAllAction(); 1978 bRet = sal_True; 1979 } 1980 return bRet; 1981 } 1982 1983 static sal_uInt16 SwFmtGetPageNum(const SwFlyFrmFmt * pFmt) 1984 { 1985 ASSERT(pFmt != NULL, "invalid argument"); 1986 1987 SwFlyFrm * pFrm = pFmt->GetFrm(); 1988 1989 sal_uInt16 aResult; 1990 1991 if (pFrm != NULL) 1992 aResult = pFrm->GetPhyPageNum(); 1993 else 1994 aResult = pFmt->GetAnchor().GetPageNum(); 1995 1996 return aResult; 1997 } 1998 1999 #include <fmtcnct.hxx> 2000 2001 void SwFEShell::GetConnectableFrmFmts(SwFrmFmt & rFmt, 2002 const String & rReference, 2003 sal_Bool bSuccessors, 2004 ::std::vector< String > & aPrevPageVec, 2005 ::std::vector< String > & aThisPageVec, 2006 ::std::vector< String > & aNextPageVec, 2007 ::std::vector< String > & aRestVec) 2008 { 2009 StartAction(); 2010 2011 SwFmtChain rChain = rFmt.GetChain(); 2012 SwFrmFmt * pOldChainNext = (SwFrmFmt *) rChain.GetNext(); 2013 SwFrmFmt * pOldChainPrev = (SwFrmFmt *) rChain.GetPrev(); 2014 2015 if (pOldChainNext) 2016 pDoc->Unchain(rFmt); 2017 2018 if (pOldChainPrev) 2019 pDoc->Unchain(*pOldChainPrev); 2020 2021 sal_uInt16 nCnt = pDoc->GetFlyCount(FLYCNTTYPE_FRM); 2022 2023 /* potential successors resp. predecessors */ 2024 ::std::vector< const SwFrmFmt * > aTmpSpzArray; 2025 2026 (SwFrmFmt *) pDoc->FindFlyByName(rReference); 2027 2028 for (sal_uInt16 n = 0; n < nCnt; n++) 2029 { 2030 const SwFrmFmt & rFmt1 = *(pDoc->GetFlyNum(n, FLYCNTTYPE_FRM)); 2031 2032 /* 2033 pFmt is a potential successor of rFmt if it is chainable after 2034 rFmt. 2035 2036 pFmt is a potential predecessor of rFmt if rFmt is chainable 2037 after pFmt. 2038 */ 2039 2040 int nChainState; 2041 2042 if (bSuccessors) 2043 nChainState = pDoc->Chainable(rFmt, rFmt1); 2044 else 2045 nChainState = pDoc->Chainable(rFmt1, rFmt); 2046 2047 if (nChainState == SW_CHAIN_OK) 2048 { 2049 aTmpSpzArray.push_back(&rFmt1); 2050 2051 } 2052 2053 } 2054 2055 if (aTmpSpzArray.size() > 0) 2056 { 2057 aPrevPageVec.clear(); 2058 aThisPageVec.clear(); 2059 aNextPageVec.clear(); 2060 aRestVec.clear(); 2061 2062 /* number of page rFmt resides on */ 2063 sal_uInt16 nPageNum = SwFmtGetPageNum((SwFlyFrmFmt *) &rFmt); 2064 2065 ::std::vector< const SwFrmFmt * >::const_iterator aIt; 2066 2067 for (aIt = aTmpSpzArray.begin(); aIt != aTmpSpzArray.end(); aIt++) 2068 { 2069 String aString = (*aIt)->GetName(); 2070 2071 /* rFmt is not a vaild successor or predecessor of 2072 itself */ 2073 if (aString != rReference && aString != rFmt.GetName()) 2074 { 2075 sal_uInt16 nNum1 = 2076 SwFmtGetPageNum((SwFlyFrmFmt *) *aIt); 2077 2078 if (nNum1 == nPageNum -1) 2079 aPrevPageVec.push_back(aString); 2080 else if (nNum1 == nPageNum) 2081 aThisPageVec.push_back(aString); 2082 else if (nNum1 == nPageNum + 1) 2083 aNextPageVec.push_back(aString); 2084 else 2085 aRestVec.push_back(aString); 2086 } 2087 } 2088 2089 } 2090 2091 if (pOldChainNext) 2092 pDoc->Chain(rFmt, *pOldChainNext); 2093 2094 if (pOldChainPrev) 2095 pDoc->Chain(*pOldChainPrev, rFmt); 2096 2097 EndAction(); 2098 } 2099 2100 // --> OD 2009-07-13 #i73249# 2101 const String SwFEShell::GetObjTitle() const 2102 { 2103 String aTitle; 2104 2105 if ( Imp()->HasDrawView() ) 2106 { 2107 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 2108 if ( pMrkList->GetMarkCount() == 1 ) 2109 { 2110 const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 2111 const SwFrmFmt* pFmt = FindFrmFmt( pObj ); 2112 if ( pFmt->Which() == RES_FLYFRMFMT ) 2113 { 2114 aTitle = dynamic_cast<const SwFlyFrmFmt*>(pFmt)->GetObjTitle(); 2115 } 2116 else 2117 { 2118 aTitle = pObj->GetTitle(); 2119 } 2120 } 2121 } 2122 2123 return aTitle; 2124 } 2125 2126 void SwFEShell::SetObjTitle( const String& rTitle ) 2127 { 2128 if ( Imp()->HasDrawView() ) 2129 { 2130 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 2131 if ( pMrkList->GetMarkCount() == 1 ) 2132 { 2133 SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 2134 SwFrmFmt* pFmt = FindFrmFmt( pObj ); 2135 if ( pFmt->Which() == RES_FLYFRMFMT ) 2136 { 2137 GetDoc()->SetFlyFrmTitle( *(dynamic_cast<SwFlyFrmFmt*>(pFmt)), 2138 rTitle ); 2139 } 2140 else 2141 { 2142 pObj->SetTitle( rTitle ); 2143 } 2144 } 2145 } 2146 } 2147 2148 const String SwFEShell::GetObjDescription() const 2149 { 2150 String aDescription; 2151 2152 if ( Imp()->HasDrawView() ) 2153 { 2154 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 2155 if ( pMrkList->GetMarkCount() == 1 ) 2156 { 2157 const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 2158 const SwFrmFmt* pFmt = FindFrmFmt( pObj ); 2159 if ( pFmt->Which() == RES_FLYFRMFMT ) 2160 { 2161 aDescription = dynamic_cast<const SwFlyFrmFmt*>(pFmt)->GetObjDescription(); 2162 } 2163 else 2164 { 2165 aDescription = pObj->GetDescription(); 2166 } 2167 } 2168 } 2169 2170 return aDescription; 2171 } 2172 2173 void SwFEShell::SetObjDescription( const String& rDescription ) 2174 { 2175 if ( Imp()->HasDrawView() ) 2176 { 2177 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList(); 2178 if ( pMrkList->GetMarkCount() == 1 ) 2179 { 2180 SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj(); 2181 SwFrmFmt* pFmt = FindFrmFmt( pObj ); 2182 if ( pFmt->Which() == RES_FLYFRMFMT ) 2183 { 2184 GetDoc()->SetFlyFrmDescription( *(dynamic_cast<SwFlyFrmFmt*>(pFmt)), 2185 rDescription ); 2186 } 2187 else 2188 { 2189 pObj->SetDescription( rDescription ); 2190 } 2191 } 2192 } 2193 } 2194 2195 2196 void SwFEShell::AlignFormulaToBaseline( const uno::Reference < embed::XEmbeddedObject >& xObj, SwFlyFrm * pFly ) 2197 { 2198 #if OSL_DEBUG_LEVEL > 1 2199 SvGlobalName aCLSID( xObj->getClassID() ); 2200 const bool bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 ); 2201 ASSERT( bStarMath, "AlignFormulaToBaseline should only be called for Math objects" ); 2202 2203 if ( !bStarMath ) 2204 return; 2205 #endif 2206 2207 if (!pFly) 2208 pFly = FindFlyFrm( xObj ); 2209 ASSERT( pFly , "No fly frame!" ); 2210 SwFrmFmt * pFrmFmt = pFly ? pFly->GetFmt() : 0; 2211 2212 // baseline to baseline alignment should only be applied to formulas anchored as char 2213 if ( pFly && pFrmFmt && FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() ) 2214 { 2215 // get baseline from Math object 2216 uno::Any aBaseline; 2217 if( svt::EmbeddedObjectRef::TryRunningState( xObj ) ) 2218 { 2219 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY ); 2220 if ( xSet.is() ) 2221 { 2222 try 2223 { 2224 aBaseline = xSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BaseLine") ) ); 2225 } 2226 catch ( uno::Exception& ) 2227 { 2228 ASSERT( sal_False , "Baseline could not be retrieved from Starmath!" ); 2229 } 2230 } 2231 } 2232 2233 sal_Int32 nBaseline = ::comphelper::getINT32(aBaseline); 2234 const MapMode aSourceMapMode( MAP_100TH_MM ); 2235 const MapMode aTargetMapMode( MAP_TWIP ); 2236 nBaseline = OutputDevice::LogicToLogic( nBaseline, aSourceMapMode.GetMapUnit(), aTargetMapMode.GetMapUnit() ); 2237 2238 ASSERT( nBaseline > 0, "Wrong value of Baseline while retrieving from Starmath!" ); 2239 //nBaseline must be moved by aPrt position 2240 const SwFlyFrmFmt *pFlyFrmFmt = pFly->GetFmt(); 2241 ASSERT( pFlyFrmFmt, "fly frame format missing!" ); 2242 if ( pFlyFrmFmt ) 2243 nBaseline += pFlyFrmFmt->GetLastFlyFrmPrtRectPos().Y(); 2244 2245 const SwFmtVertOrient &rVert = pFrmFmt->GetVertOrient(); 2246 SwFmtVertOrient aVert( rVert ); 2247 aVert.SetPos( -nBaseline ); 2248 aVert.SetVertOrient( com::sun::star::text::VertOrientation::NONE ); 2249 2250 pFrmFmt->LockModify(); 2251 pFrmFmt->SetFmtAttr( aVert ); 2252 pFrmFmt->UnlockModify(); 2253 pFly->InvalidatePos(); 2254 } 2255 } 2256 2257 2258 void SwFEShell::AlignAllFormulasToBaseline() 2259 { 2260 StartAllAction(); 2261 2262 SwStartNode *pStNd; 2263 SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 ); 2264 while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) ) 2265 { 2266 ++aIdx; 2267 SwOLENode *pOleNode = dynamic_cast< SwOLENode * >( &aIdx.GetNode() ); 2268 if ( pOleNode ) 2269 { 2270 const uno::Reference < embed::XEmbeddedObject > & xObj( pOleNode->GetOLEObj().GetOleRef() ); 2271 if (xObj.is()) 2272 { 2273 SvGlobalName aCLSID( xObj->getClassID() ); 2274 if ( SotExchange::IsMath( aCLSID ) ) 2275 AlignFormulaToBaseline( xObj ); 2276 } 2277 } 2278 2279 aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 ); 2280 } 2281 2282 EndAllAction(); 2283 } 2284