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