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