/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include "hintids.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "doc.hxx" #include "viewsh.hxx" #include "layouter.hxx" #include "pagefrm.hxx" #include "rootfrm.hxx" #include "cntfrm.hxx" #include "pam.hxx" #include "frmatr.hxx" #include "viewimp.hxx" #include "viewopt.hxx" #include "errhdl.hxx" #include "dcontact.hxx" #include "dflyobj.hxx" #include "dview.hxx" #include "flyfrm.hxx" #include "frmtool.hxx" #include "frmfmt.hxx" #include "hints.hxx" #include "swregion.hxx" #include "tabfrm.hxx" #include "txtfrm.hxx" #include "ndnotxt.hxx" #include "notxtfrm.hxx" // GetGrfArea #include "flyfrms.hxx" #include "ndindex.hxx" // GetGrfArea #include "sectfrm.hxx" #include #include // FRound #include "switerator.hxx" #include using namespace ::com::sun::star; // OD 2004-03-23 #i26791 TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject); /************************************************************************* |* |* SwFlyFrm::SwFlyFrm() |* |* Ersterstellung MA 28. Sep. 92 |* Letzte Aenderung MA 09. Apr. 99 |* |*************************************************************************/ SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : SwLayoutFrm( pFmt, pSib ), SwAnchoredObject(), pPrevLink( 0 ), pNextLink( 0 ), bInCnt( sal_False ), bAtCnt( sal_False ), bLayout( sal_False ), bAutoPosition( sal_False ), bNoShrink( sal_False ), bLockDeleteContent( sal_False ) { nType = FRMC_FLY; bInvalid = bNotifyBack = sal_True; bLocked = bMinHeight = bHeightClipped = bWidthClipped = bFormatHeightOnly = sal_False; //Grosseneinstellung, Fixe groesse ist immer die Breite const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize(); sal_uInt16 nDir = ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue(); if( FRMDIR_ENVIRONMENT == nDir ) { bDerivedVert = 1; bDerivedR2L = 1; } else { bInvalidVert = 0; bDerivedVert = 0; bDerivedR2L = 0; if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir ) { //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin bVertLR = 0; bVertical = 0; } else { const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0; if( pSh && pSh->GetViewOptions()->getBrowseMode() ) { //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin bVertLR = 0; bVertical = 0; } else { bVertical = 1; //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin if ( FRMDIR_VERT_TOP_LEFT == nDir ) bVertLR = 1; else bVertLR = 0; } } bInvalidR2L = 0; if( FRMDIR_HORI_RIGHT_TOP == nDir ) bRightToLeft = 1; else bRightToLeft = 0; } Frm().Width( rFrmSize.GetWidth() ); Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() ); //Hoehe Fix oder Variabel oder was? if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE ) bMinHeight = sal_True; else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE ) bFixSize = sal_True; // insert columns, if necessary InsertColumns(); // initialize before inserting content as the content might contain other objects which need to be registered InitDrawObj( sal_False ); Chain( pAnch ); InsertCnt(); // apply dummy position which is far-away in order to avoid needless formattings Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH; } void SwFlyFrm::Chain( SwFrm* _pAnch ) { // Connect to chain neighboors. // No problem, if a neighboor doesn't exist - the construction of the // neighboor will make the connection const SwFmtChain& rChain = GetFmt()->GetChain(); if ( rChain.GetPrev() || rChain.GetNext() ) { if ( rChain.GetNext() ) { SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch ); if ( pFollow ) { ASSERT( !pFollow->GetPrevLink(), "wrong chain detected" ); if ( !pFollow->GetPrevLink() ) SwFlyFrm::ChainFrames( this, pFollow ); } } if ( rChain.GetPrev() ) { SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch ); if ( pMaster ) { ASSERT( !pMaster->GetNextLink(), "wrong chain detected" ); if ( !pMaster->GetNextLink() ) SwFlyFrm::ChainFrames( pMaster, this ); } } } } void SwFlyFrm::InsertCnt() { if ( !GetPrevLink() ) { const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt(); ASSERT( rCntnt.GetCntntIdx(), ":-( no content prepared." ); sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex(); // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this, GetFmt()->GetDoc(), nIndex ); //NoTxt haben immer eine FixHeight. if ( Lower() && Lower()->IsNoTxtFrm() ) { bFixSize = sal_True; bMinHeight = sal_False; } } } void SwFlyFrm::InsertColumns() { // Check, if column are allowed. // Columns are not allowed for fly frames, which represent graphics or embedded objects. const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt(); ASSERT( rCntnt.GetCntntIdx(), " - no content prepared." ); SwNodeIndex aFirstCntnt( *( rCntnt.GetCntntIdx() ), 1 ); if ( aFirstCntnt.GetNode().IsNoTxtNode() ) { return; } const SwFmtCol &rCol = GetFmt()->GetCol(); if ( rCol.GetNumCols() > 1 ) { //PrtArea ersteinmal so gross wie der Frm, damit die Spalten //vernuenftig eingesetzt werden koennen; das schaukelt sich dann //schon zurecht. Prt().Width( Frm().Width() ); Prt().Height( Frm().Height() ); const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein //Old-Wert hereingereicht wird. ChgColumns( aOld, rCol ); } } /************************************************************************* |* |* SwFlyFrm::~SwFlyFrm() |* |* Ersterstellung MA 28. Sep. 92 |* Letzte Aenderung MA 07. Jul. 95 |* |*************************************************************************/ SwFlyFrm::~SwFlyFrm() { // Accessible objects for fly frames will be destroyed in this destructor. // For frames bound as char or frames that don't have an anchor we have // to do that ourselves. For any other frame the call RemoveFly at the // anchor will do that. if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) ) { SwRootFrm *pRootFrm = getRootFrm(); if( pRootFrm && pRootFrm->IsAnyShellAccessible() ) { ViewShell *pVSh = pRootFrm->GetCurrShell(); if( pVSh && pVSh->Imp() ) { // Lowers aren't disposed already, so we have to do a recursive // dispose pVSh->Imp()->DisposeAccessibleFrm( this, sal_True ); } } } if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() ) { // OD 2004-01-19 #110582# Unchain(); // OD 2004-01-19 #110582# DeleteCnt(); //Tschuess sagen. if ( GetAnchorFrm() ) AnchorFrm()->RemoveFly( this ); } FinitDrawObj(); } // OD 2004-01-19 #110582# void SwFlyFrm::Unchain() { if ( GetPrevLink() ) UnchainFrames( GetPrevLink(), this ); if ( GetNextLink() ) UnchainFrames( this, GetNextLink() ); } // OD 2004-01-19 #110582# void SwFlyFrm::DeleteCnt() { // #110582#-2 if ( IsLockDeleteContent() ) return; SwFrm* pFrm = pLower; while ( pFrm ) { while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) { SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0]; if ( pAnchoredObj->ISA(SwFlyFrm) ) delete pAnchoredObj; else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) ) { // OD 23.06.2003 #108784# - consider 'virtual' drawing objects SdrObject* pObj = pAnchoredObj->DrawObj(); if ( pObj->ISA(SwDrawVirtObj) ) { SwDrawVirtObj* pDrawVirtObj = static_cast(pObj); pDrawVirtObj->RemoveFromWriterLayout(); pDrawVirtObj->RemoveFromDrawingPage(); } else { SwDrawContact* pContact = static_cast(::GetUserCall( pObj )); if ( pContact ) { pContact->DisconnectFromLayout(); } } } } pFrm->Remove(); delete pFrm; pFrm = pLower; } InvalidatePage(); } /************************************************************************* |* |* SwFlyFrm::InitDrawObj() |* |* Ersterstellung MA 02. Dec. 94 |* Letzte Aenderung MA 30. Nov. 95 |* |*************************************************************************/ sal_uInt32 SwFlyFrm::_GetOrdNumForNewRef( const SwFlyDrawContact* pContact ) { sal_uInt32 nOrdNum( 0L ); // search for another Writer fly frame registered at same frame format SwIterator aIter( *pContact->GetFmt() ); const SwFlyFrm* pFlyFrm( 0L ); for ( pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() ) { if ( pFlyFrm != this ) { break; } } if ( pFlyFrm ) { // another Writer fly frame found. Take its order number nOrdNum = pFlyFrm->GetVirtDrawObj()->GetOrdNum(); } else { // no other Writer fly frame found. Take order number of 'master' object // --> OD 2004-11-11 #i35748# - use method instead // of method to avoid a recalculation of the order number, // which isn't intended. nOrdNum = pContact->GetMaster()->GetOrdNumDirect(); // <-- } return nOrdNum; } SwVirtFlyDrawObj* SwFlyFrm::CreateNewRef( SwFlyDrawContact *pContact ) { SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *pContact->GetMaster(), this ); pDrawObj->SetModel( pContact->GetMaster()->GetModel() ); pDrawObj->SetUserCall( pContact ); //Der Reader erzeugt die Master und setzt diese, um die Z-Order zu //transportieren, in die Page ein. Beim erzeugen der ersten Referenz werden //die Master aus der Liste entfernt und fuehren von da an ein //Schattendasein. SdrPage* pPg( 0L ); if ( 0 != ( pPg = pContact->GetMaster()->GetPage() ) ) { const sal_uInt32 nOrdNum = pContact->GetMaster()->GetOrdNum(); pPg->ReplaceObject( pDrawObj, nOrdNum ); } // --> OD 2004-08-16 #i27030# - insert new instance // into drawing page with correct order number else { pContact->GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )-> InsertObject( pDrawObj, _GetOrdNumForNewRef( pContact ) ); } // <-- // --> OD 2004-12-13 #i38889# - assure, that new instance // is in a visible layer. pContact->MoveObjToVisibleLayer( pDrawObj ); // <-- return pDrawObj; } void SwFlyFrm::InitDrawObj( sal_Bool bNotify ) { //ContactObject aus dem Format suchen. Wenn bereits eines existiert, so //braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an //der Zeit das Contact zu erzeugen. IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess(); SwFlyDrawContact *pContact = SwIterator::FirstElement( *GetFmt() ); if ( !pContact ) { // --> OD 2005-08-08 #i52858# - method name changed pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(), pIDDMA->GetOrCreateDrawModel() ); // <-- } ASSERT( pContact, "InitDrawObj failed" ); // OD 2004-03-22 #i26791# SetDrawObj( *(CreateNewRef( pContact )) ); //Den richtigen Layer setzen. // OD 2004-01-19 #110582# SdrLayerID nHeavenId = pIDDMA->GetHeavenId(); SdrLayerID nHellId = pIDDMA->GetHellId(); // OD 2004-03-22 #i26791# GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue() ? nHeavenId : nHellId ); if ( bNotify ) NotifyDrawObj(); } /************************************************************************* |* |* SwFlyFrm::FinitDrawObj() |* |* Ersterstellung MA 12. Dec. 94 |* Letzte Aenderung MA 15. May. 95 |* |*************************************************************************/ void SwFlyFrm::FinitDrawObj() { if ( !GetVirtDrawObj() ) return; //Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist. if ( !GetFmt()->GetDoc()->IsInDtor() ) { ViewShell *p1St = getRootFrm()->GetCurrShell(); if ( p1St ) { ViewShell *pSh = p1St; do { //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das //Objekt bereits Removed wurde. if( pSh->HasDrawView() ) pSh->Imp()->GetDrawView()->UnmarkAll(); pSh = (ViewShell*)pSh->GetNext(); } while ( pSh != p1St ); } } //VirtObject mit in das Grab nehmen. Wenn das letzte VirObject //zerstoert wird, mussen das DrawObject und DrawContact ebenfalls //zerstoert werden. SwFlyDrawContact *pMyContact = 0; if ( GetFmt() ) { bool bContinue = true; SwIterator aFrmIter( *GetFmt() ); for ( SwFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() ) if ( pFrm != this ) { // don't delete Contact if there is still a Frm bContinue = false; break; } if ( bContinue ) // no Frm left, find Contact object to destroy pMyContact = SwIterator::FirstElement( *GetFmt() ); } // OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master' // to assure, that a doesn't delete the // Writer fly frame again. if ( pMyContact ) { pMyContact->GetMaster()->SetUserCall( 0 ); } GetVirtDrawObj()->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj delete GetVirtDrawObj(); //Meldet sich selbst beim Master ab. if ( pMyContact ) delete pMyContact; //zerstoert den Master selbst. } /************************************************************************* |* |* SwFlyFrm::ChainFrames() |* |* Ersterstellung MA 29. Oct. 97 |* Letzte Aenderung MA 20. Jan. 98 |* |*************************************************************************/ void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow ) { ASSERT( pMaster && pFollow, "uncomplete chain" ); ASSERT( !pMaster->GetNextLink(), "link can not be changed" ); ASSERT( !pFollow->GetPrevLink(), "link can not be changed" ); pMaster->pNextLink = pFollow; pFollow->pPrevLink = pMaster; if ( pMaster->ContainsCntnt() ) { //Damit ggf. ein Textfluss zustande kommt muss invalidiert werden. SwFrm *pInva = pMaster->FindLastLower(); SWRECTFN( pMaster ) const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)(); while ( pInva ) { if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 ) { pInva->InvalidateSize(); pInva->Prepare( PREP_CLEAR ); pInva = pInva->FindPrev(); } else pInva = 0; } } if ( pFollow->ContainsCntnt() ) { //Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow //hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein). SwFrm *pFrm = pFollow->ContainsCntnt(); ASSERT( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" ); pFrm->Cut(); delete pFrm; } // invalidate accessible relation set (accessibility wrapper) ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell(); if( pSh ) { SwRootFrm* pLayout = pMaster->getRootFrm(); if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow ); } } void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow ) { pMaster->pNextLink = 0; pFollow->pPrevLink = 0; if ( pFollow->ContainsCntnt() ) { //Der Master saugt den Inhalt vom Follow auf SwLayoutFrm *pUpper = pMaster; if ( pUpper->Lower()->IsColumnFrm() ) { pUpper = static_cast(pUpper->GetLastLower()); pUpper = static_cast(pUpper->Lower()); // der (Column)BodyFrm ASSERT( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" ); } SwFlyFrm *pFoll = pFollow; while ( pFoll ) { SwFrm *pTmp = ::SaveCntnt( pFoll ); if ( pTmp ) ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true ); pFoll->SetCompletePaint(); pFoll->InvalidateSize(); pFoll = pFoll->GetNextLink(); } } //Der Follow muss mit seinem eigenen Inhalt versorgt werden. const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt(); ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." ); sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex(); // Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower() : (SwLayoutFrm*)pFollow, pFollow->GetFmt()->GetDoc(), ++nIndex ); // invalidate accessible relation set (accessibility wrapper) ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell(); if( pSh ) { SwRootFrm* pLayout = pMaster->getRootFrm(); if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow ); } } /************************************************************************* |* |* SwFlyFrm::FindChainNeighbour() |* |* Ersterstellung MA 11. Nov. 97 |* Letzte Aenderung MA 09. Apr. 99 |* |*************************************************************************/ SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch ) { //Wir suchen denjenigen Fly, der in dem selben Bereich steht. //Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein. if ( !pAnch ) //Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor! pAnch = AnchorFrm(); SwLayoutFrm *pLay; if ( pAnch->IsInFly() ) pLay = pAnch->FindFlyFrm(); else { //FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung //zum Anker besteht. pLay = pAnch->GetUpper(); while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) ) pLay = pLay->GetUpper(); } SwIterator aIter( rChain ); SwFlyFrm *pFly = aIter.First(); if ( pLay ) { while ( pFly ) { if ( pFly->GetAnchorFrm() ) { if ( pFly->GetAnchorFrm()->IsInFly() ) { if ( pFly->AnchorFrm()->FindFlyFrm() == pLay ) break; } else if ( pLay == pFly->FindFooterOrHeader() ) break; } pFly = aIter.Next(); } } else if ( pFly ) { ASSERT( !aIter.Next(), "chain with more than one inkarnation" ); } return pFly; } /************************************************************************* |* |* SwFlyFrm::FindLastLower() |* |* Ersterstellung MA 29. Oct. 97 |* Letzte Aenderung MA 29. Oct. 97 |* |*************************************************************************/ SwFrm *SwFlyFrm::FindLastLower() { SwFrm *pRet = ContainsAny(); if ( pRet && pRet->IsInTab() ) pRet = pRet->FindTabFrm(); SwFrm *pNxt = pRet; while ( pNxt && IsAnLower( pNxt ) ) { pRet = pNxt; pNxt = pNxt->FindNext(); } return pRet; } /************************************************************************* |* |* SwFlyFrm::FrmSizeChg() |* |* Ersterstellung MA 17. Dec. 92 |* Letzte Aenderung MA 24. Jul. 96 |* |*************************************************************************/ sal_Bool SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize ) { sal_Bool bRet = sal_False; SwTwips nDiffHeight = Frm().Height(); if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ) bFixSize = bMinHeight = sal_False; else { if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE ) { bFixSize = sal_True; bMinHeight = sal_False; } else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE ) { bFixSize = sal_False; bMinHeight = sal_True; } nDiffHeight -= rFrmSize.GetHeight(); } //Wenn der Fly Spalten enthaehlt muessen der Fly und //die Spalten schon einmal auf die Wunschwerte gebracht //werden, sonst haben wir ein kleines Problem. if ( Lower() ) { if ( Lower()->IsColumnFrm() ) { const SwRect aOld( GetObjRectWithSpaces() ); const Size aOldSz( Prt().SSize() ); const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth(); aFrm.Height( aFrm.Height() - nDiffHeight ); aFrm.Width ( aFrm.Width() - nDiffWidth ); // --> OD 2006-08-16 #i68520# InvalidateObjRectWithSpaces(); // <-- aPrt.Height( aPrt.Height() - nDiffHeight ); aPrt.Width ( aPrt.Width() - nDiffWidth ); ChgLowersProp( aOldSz ); ::Notify( this, FindPageFrm(), aOld ); bValidPos = sal_False; bRet = sal_True; } else if ( Lower()->IsNoTxtFrm() ) { bFixSize = sal_True; bMinHeight = sal_False; } } return bRet; } /************************************************************************* |* |* SwFlyFrm::Modify() |* |* Ersterstellung MA 17. Dec. 92 |* Letzte Aenderung MA 17. Jan. 97 |* |*************************************************************************/ void SwFlyFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew ) { sal_uInt8 nInvFlags = 0; if( pNew && RES_ATTRSET_CHG == pNew->Which() ) { SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); while( sal_True ) { _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags, &aOldSet, &aNewSet ); if( aNIter.IsAtEnd() ) break; aNIter.NextItem(); aOIter.NextItem(); } if ( aOldSet.Count() || aNewSet.Count() ) SwLayoutFrm::Modify( &aOldSet, &aNewSet ); } else _UpdateAttr( pOld, pNew, nInvFlags ); if ( nInvFlags != 0 ) { _Invalidate(); if ( nInvFlags & 0x01 ) { _InvalidatePos(); // --> OD 2006-08-16 #i68520# InvalidateObjRectWithSpaces(); // <-- } if ( nInvFlags & 0x02 ) { _InvalidateSize(); // --> OD 2006-08-16 #i68520# InvalidateObjRectWithSpaces(); // <-- } if ( nInvFlags & 0x04 ) _InvalidatePrt(); if ( nInvFlags & 0x08 ) SetNotifyBack(); if ( nInvFlags & 0x10 ) SetCompletePaint(); if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() ) ClrContourCache( GetVirtDrawObj() ); SwRootFrm *pRoot; if ( nInvFlags & 0x20 && 0 != (pRoot = getRootFrm()) ) pRoot->InvalidateBrowseWidth(); // --> OD 2004-06-28 #i28701# if ( nInvFlags & 0x80 ) { // update sorted object lists, the Writer fly frame is registered at. UpdateObjInSortedList(); } // <-- // --> OD #i87645# - reset flags for the layout process (only if something has been invalidated) ResetLayoutProcessBools(); // <-- } } void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew, sal_uInt8 &rInvFlags, SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) { sal_Bool bClear = sal_True; const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; ViewShell *pSh = getRootFrm()->GetCurrShell(); switch( nWhich ) { case RES_VERT_ORIENT: case RES_HORI_ORIENT: // OD 22.09.2003 #i18732# - consider new option 'follow text flow' case RES_FOLLOW_TEXT_FLOW: { //Achtung! _immer_ Aktion in ChgRePos() mitpflegen. rInvFlags |= 0x09; } break; // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position' case RES_WRAP_INFLUENCE_ON_OBJPOS: { rInvFlags |= 0x89; } break; case RES_SURROUND: { // OD 2004-05-13 #i28701# - invalidate position on change of // wrapping style. //rInvFlags |= 0x40; rInvFlags |= 0x41; //Der Hintergrund muss benachrichtigt und Invalidiert werden. const SwRect aTmp( GetObjRectWithSpaces() ); NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG ); // Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine // vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() ) rInvFlags |= 0x09; //Ggf. die Kontur am Node loeschen. if ( Lower() && Lower()->IsNoTxtFrm() && !GetFmt()->GetSurround().IsContour() ) { SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode(); if ( pNd->HasContour() ) pNd->SetContour( 0 ); } // --> OD 2004-06-28 #i28701# - perform reorder of object lists // at anchor frame and at page frame. rInvFlags |= 0x80; } break; case RES_PROTECT: { const SvxProtectItem *pP = (SvxProtectItem*)pNew; GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() ); GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() ); if( pSh ) { SwRootFrm* pLayout = getRootFrm(); if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this ); } break; } case RES_COL: { ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew ); const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize(); if ( FrmSizeChg( rNew ) ) NotifyDrawObj(); rInvFlags |= 0x1A; break; } case RES_FRM_SIZE: case RES_FMT_CHG: { const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize(); if ( FrmSizeChg( rNew ) ) NotifyDrawObj(); rInvFlags |= 0x7F; if ( RES_FMT_CHG == nWhich ) { SwRect aNew( GetObjRectWithSpaces() ); SwRect aOld( aFrm ); const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace(); aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) ); aOld.SSize().Height()+= rUL.GetLower(); const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace(); aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) ); aOld.SSize().Width() += rLR.GetRight(); aNew.Union( aOld ); NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR ); //Dummer Fall. Bei der Zusweisung einer Vorlage k?nnen wir uns //nicht auf das alte Spaltenattribut verlassen. Da diese //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen, //bleibt uns nur einen temporaeres Attribut zu basteln. SwFmtCol aCol; if ( Lower() && Lower()->IsColumnFrm() ) { sal_uInt16 nCol = 0; SwFrm *pTmp = Lower(); do { ++nCol; pTmp = pTmp->GetNext(); } while ( pTmp ); aCol.Init( nCol, 0, 1000 ); } ChgColumns( aCol, GetFmt()->GetCol() ); } SwFmtURL aURL( GetFmt()->GetURL() ); if ( aURL.GetMap() ) { const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ? *(SwFmtFrmSize*)pNew : ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize(); //#35091# Kann beim Laden von Vorlagen mal 0 sein if ( rOld.GetWidth() && rOld.GetHeight() ) { Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() ); Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() ); aURL.GetMap()->Scale( aScaleX, aScaleY ); SwFrmFmt *pFmt = GetFmt(); pFmt->LockModify(); pFmt->SetFmtAttr( aURL ); pFmt->UnlockModify(); } } const SvxProtectItem &rP = GetFmt()->GetProtect(); GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() ); GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() ); if ( pSh ) pSh->InvalidateWindows( Frm() ); const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess(); const sal_uInt8 nId = GetFmt()->GetOpaque().GetValue() ? pIDDMA->GetHeavenId() : pIDDMA->GetHellId(); GetVirtDrawObj()->SetLayer( nId ); if ( Lower() ) { //Ggf. die Kontur am Node loeschen. if( Lower()->IsNoTxtFrm() && !GetFmt()->GetSurround().IsContour() ) { SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode(); if ( pNd->HasContour() ) pNd->SetContour( 0 ); } else if( !Lower()->IsColumnFrm() ) { SwFrm* pFrm = GetLastLower(); if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) pFrm->Prepare( PREP_ADJUST_FRM ); } } // --> OD 2004-06-28 #i28701# - perform reorder of object lists // at anchor frame and at page frame. rInvFlags |= 0x80; break; } case RES_UL_SPACE: case RES_LR_SPACE: { rInvFlags |= 0x41; if( pSh && pSh->GetViewOptions()->getBrowseMode() ) getRootFrm()->InvalidateBrowseWidth(); SwRect aNew( GetObjRectWithSpaces() ); SwRect aOld( aFrm ); if ( RES_UL_SPACE == nWhich ) { const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew; aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) ); aOld.SSize().Height()+= rUL.GetLower(); } else { const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew; aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) ); aOld.SSize().Width() += rLR.GetRight(); } aNew.Union( aOld ); NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR ); } break; case RES_BOX: case RES_SHADOW: rInvFlags |= 0x17; break; case RES_FRAMEDIR : SetDerivedVert( sal_False ); SetDerivedR2L( sal_False ); CheckDirChange(); break; case RES_OPAQUE: { if ( pSh ) pSh->InvalidateWindows( Frm() ); const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess(); const sal_uInt8 nId = ((SvxOpaqueItem*)pNew)->GetValue() ? pIDDMA->GetHeavenId() : pIDDMA->GetHellId(); GetVirtDrawObj()->SetLayer( nId ); if( pSh ) { SwRootFrm* pLayout = getRootFrm(); if( pLayout && pLayout->IsAnyShellAccessible() ) { pSh->Imp()->DisposeAccessibleFrm( this ); pSh->Imp()->AddAccessibleFrm( this ); } } // --> OD 2004-06-28 #i28701# - perform reorder of object lists // at anchor frame and at page frame. rInvFlags |= 0x80; } break; case RES_URL: //Das Interface arbeitet bei Textrahmen auf der Rahmengroesse, //die Map muss sich aber auf die FrmSize beziehen if ( (!Lower() || !Lower()->IsNoTxtFrm()) && ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() ) { const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize(); if ( rSz.GetHeight() != Frm().Height() || rSz.GetWidth() != Frm().Width() ) { SwFmtURL aURL( GetFmt()->GetURL() ); Fraction aScaleX( Frm().Width(), rSz.GetWidth() ); Fraction aScaleY( Frm().Height(), rSz.GetHeight() ); aURL.GetMap()->Scale( aScaleX, aScaleY ); SwFrmFmt *pFmt = GetFmt(); pFmt->LockModify(); pFmt->SetFmtAttr( aURL ); pFmt->UnlockModify(); } } /* Keine Invalidierung notwendig */ break; case RES_CHAIN: { SwFmtChain *pChain = (SwFmtChain*)pNew; if ( pChain->GetNext() ) { SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() ); if ( GetNextLink() && pFollow != GetNextLink() ) SwFlyFrm::UnchainFrames( this, GetNextLink()); if ( pFollow ) { if ( pFollow->GetPrevLink() && pFollow->GetPrevLink() != this ) SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(), pFollow ); if ( !GetNextLink() ) SwFlyFrm::ChainFrames( this, pFollow ); } } else if ( GetNextLink() ) SwFlyFrm::UnchainFrames( this, GetNextLink() ); if ( pChain->GetPrev() ) { SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() ); if ( GetPrevLink() && pMaster != GetPrevLink() ) SwFlyFrm::UnchainFrames( GetPrevLink(), this ); if ( pMaster ) { if ( pMaster->GetNextLink() && pMaster->GetNextLink() != this ) SwFlyFrm::UnchainFrames( pMaster, pMaster->GetNextLink() ); if ( !GetPrevLink() ) SwFlyFrm::ChainFrames( pMaster, this ); } } else if ( GetPrevLink() ) SwFlyFrm::UnchainFrames( GetPrevLink(), this ); } default: bClear = sal_False; } if ( bClear ) { if ( pOldSet || pNewSet ) { if ( pOldSet ) pOldSet->ClearItem( nWhich ); if ( pNewSet ) pNewSet->ClearItem( nWhich ); } else SwLayoutFrm::Modify( pOld, pNew ); } } /************************************************************************* |* |* SwFlyFrm::GetInfo() |* |* Beschreibung erfragt Informationen |* Ersterstellung JP 31.03.94 |* Letzte Aenderung JP 31.03.94 |* *************************************************************************/ // erfrage vom Modify Informationen sal_Bool SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const { if( RES_AUTOFMT_DOCNODE == rInfo.Which() ) return sal_False; // es gibt einen FlyFrm also wird er benutzt return sal_True; // weiter suchen } /************************************************************************* |* |* SwFlyFrm::_Invalidate() |* |* Ersterstellung MA 15. Oct. 92 |* Letzte Aenderung MA 26. Jun. 96 |* |*************************************************************************/ void SwFlyFrm::_Invalidate( SwPageFrm *pPage ) { InvalidatePage( pPage ); bNotifyBack = bInvalid = sal_True; SwFlyFrm *pFrm; if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) ) { //Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der //Spalten enthaehlt, sollte das Format von diesem ausgehen. if ( !pFrm->IsLocked() && !pFrm->IsColLocked() && pFrm->Lower() && pFrm->Lower()->IsColumnFrm() ) pFrm->InvalidateSize(); } // --> OD 2008-01-21 #i85216# // if vertical position is oriented at a layout frame inside a ghost section, // assure that the position is invalidated and that the information about // the vertical position oriented frame is cleared if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() ) { const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() ); if ( pSectFrm && pSectFrm->GetSection() == 0 ) { InvalidatePos(); ClearVertPosOrientFrm(); } } // <-- } /************************************************************************* |* |* SwFlyFrm::ChgRelPos() |* |* Beschreibung Aenderung der relativen Position, die Position wird |* damit automatisch Fix, das Attribut wird entprechend angepasst. |* Ersterstellung MA 25. Aug. 92 |* Letzte Aenderung MA 09. Aug. 95 |* |*************************************************************************/ void SwFlyFrm::ChgRelPos( const Point &rNewPos ) { if ( GetCurrRelPos() != rNewPos ) { SwFrmFmt *pFmt = GetFmt(); const bool bVert = GetAnchorFrm()->IsVertical(); const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y(); SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY; if( bVert ) nTmpY = -nTmpY; SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT); SwFmtVertOrient aVert( pFmt->GetVertOrient() ); SwTxtFrm *pAutoFrm = NULL; // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored // Writer fly frames const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId(); if ( eAnchorType == FLY_AT_PAGE ) { aVert.SetVertOrient( text::VertOrientation::NONE ); aVert.SetRelationOrient( text::RelOrientation::PAGE_FRAME ); } else if ( eAnchorType == FLY_AT_FLY ) { aVert.SetVertOrient( text::VertOrientation::NONE ); aVert.SetRelationOrient( text::RelOrientation::FRAME ); } // <-- else if ( IsFlyAtCntFrm() || text::VertOrientation::NONE != aVert.GetVertOrient() ) { if( text::RelOrientation::CHAR == aVert.GetRelationOrient() && IsAutoPos() ) { if( LONG_MAX != nNewY ) { aVert.SetVertOrient( text::VertOrientation::NONE ); xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex(); ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" ); pAutoFrm = (SwTxtFrm*)GetAnchorFrm(); while( pAutoFrm->GetFollow() && pAutoFrm->GetFollow()->GetOfst() <= nOfs ) { if( pAutoFrm == GetAnchorFrm() ) nTmpY += pAutoFrm->GetRelPos().Y(); nTmpY -= pAutoFrm->GetUpper()->Prt().Height(); pAutoFrm = pAutoFrm->GetFollow(); } nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY; } else aVert.SetVertOrient( text::VertOrientation::CHAR_BOTTOM ); } else { aVert.SetVertOrient( text::VertOrientation::NONE ); aVert.SetRelationOrient( text::RelOrientation::FRAME ); } } aVert.SetPos( nTmpY ); aSet.Put( aVert ); //Fuer Flys im Cnt ist die horizontale Ausrichtung uninteressant, //den sie ist stets 0. if ( !IsFlyInCntFrm() ) { const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X(); SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX; SwFmtHoriOrient aHori( pFmt->GetHoriOrient() ); // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored // Writer fly frames if ( eAnchorType == FLY_AT_PAGE ) { aHori.SetHoriOrient( text::HoriOrientation::NONE ); aHori.SetRelationOrient( text::RelOrientation::PAGE_FRAME ); aHori.SetPosToggle( sal_False ); } else if ( eAnchorType == FLY_AT_FLY ) { aHori.SetHoriOrient( text::HoriOrientation::NONE ); aHori.SetRelationOrient( text::RelOrientation::FRAME ); aHori.SetPosToggle( sal_False ); } // <-- else if ( IsFlyAtCntFrm() || text::HoriOrientation::NONE != aHori.GetHoriOrient() ) { aHori.SetHoriOrient( text::HoriOrientation::NONE ); if( text::RelOrientation::CHAR == aHori.GetRelationOrient() && IsAutoPos() ) { if( LONG_MAX != nNewX ) { if( !pAutoFrm ) { xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor() ->nContent.GetIndex(); ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected"); pAutoFrm = (SwTxtFrm*)GetAnchorFrm(); while( pAutoFrm->GetFollow() && pAutoFrm->GetFollow()->GetOfst() <= nOfs ) pAutoFrm = pAutoFrm->GetFollow(); } nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm); } } else aHori.SetRelationOrient( text::RelOrientation::FRAME ); aHori.SetPosToggle( sal_False ); } aHori.SetPos( nTmpX ); aSet.Put( aHori ); } SetCurrRelPos( rNewPos ); pFmt->GetDoc()->SetAttr( aSet, *pFmt ); } } /************************************************************************* |* |* SwFlyFrm::Format() |* |* Beschreibung: "Formatiert" den Frame; Frm und PrtArea. |* Die Fixsize wird hier nicht eingestellt. |* Ersterstellung MA 14. Jun. 93 |* Letzte Aenderung MA 13. Jun. 96 |* |*************************************************************************/ void SwFlyFrm::Format( const SwBorderAttrs *pAttrs ) { ASSERT( pAttrs, "FlyFrm::Format, pAttrs ist 0." ); ColLock(); if ( !bValidSize ) { if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH ) { //Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor) Frm().Pos().X() = Frm().Pos().Y() = 0; // --> OD 2006-08-16 #i68520# InvalidateObjRectWithSpaces(); // <-- } //Breite der Spalten pruefen und ggf. einstellen. if ( Lower() && Lower()->IsColumnFrm() ) AdjustColumns( 0, sal_False ); bValidSize = sal_True; const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine(); const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine(); const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize(); Size aRelSize( CalcRel( rFrmSz ) ); ASSERT( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." ); ASSERT( pAttrs->GetSize().Width() != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." ); SWRECTFN( this ) if( !HasFixSize() ) { SwTwips nRemaining = 0; long nMinHeight = 0; if( IsMinHeight() ) nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height(); if ( Lower() ) { if ( Lower()->IsColumnFrm() ) { FormatWidthCols( *pAttrs, nUL, nMinHeight ); nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)(); } else { SwFrm *pFrm = Lower(); while ( pFrm ) { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)(); if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) // Dieser TxtFrm waere gern ein bisschen groesser nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight() - (pFrm->Prt().*fnRect->fnGetHeight)(); else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() ) nRemaining += ((SwSectionFrm*)pFrm)->Undersize(); pFrm = pFrm->GetNext(); } // --> OD 2006-02-09 #130878# // Do not keep old height, if content has no height. // The old height could be wrong due to wrong layout cache // and isn't corrected in the further formatting, because // the fly frame doesn't become invalid anymore. // if( !nRemaining ) // nRemaining = nOldHeight - nUL; // <-- } if ( GetDrawObjs() ) { sal_uInt32 nCnt = GetDrawObjs()->Count(); SwTwips nTop = (Frm().*fnRect->fnGetTop)(); SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() - (Prt().*fnRect->fnGetHeight)(); for ( sal_uInt16 i = 0; i < nCnt; ++i ) { SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i]; if ( pAnchoredObj->ISA(SwFlyFrm) ) { SwFlyFrm* pFly = static_cast(pAnchoredObj); // OD 06.11.2003 #i22305# - consider // only Writer fly frames, which follow the text flow. if ( pFly->IsFlyLayFrm() && pFly->Frm().Top() != WEIT_WECH && pFly->GetFmt()->GetFollowTextFlow().GetValue() ) { SwTwips nDist = -(pFly->Frm().*fnRect-> fnBottomDist)( nTop ); if( nDist > nBorder + nRemaining ) nRemaining = nDist - nBorder; } } } } } if( IsMinHeight() && (nRemaining + nUL) < nMinHeight ) nRemaining = nMinHeight - nUL; //Weil das Grow/Shrink der Flys die Groessen nicht direkt //einstellt, sondern indirekt per Invalidate ein Format //ausloesst, muessen die Groessen hier direkt eingestellt //werden. Benachrichtung laeuft bereits mit. //Weil bereits haeufiger 0en per Attribut hereinkamen wehre //ich mich ab sofort dagegen. if ( nRemaining < MINFLY ) nRemaining = MINFLY; (Prt().*fnRect->fnSetHeight)( nRemaining ); nRemaining -= (Frm().*fnRect->fnGetHeight)(); (Frm().*fnRect->fnAddBottom)( nRemaining + nUL ); // --> OD 2006-08-16 #i68520# if ( nRemaining + nUL != 0 ) { InvalidateObjRectWithSpaces(); } // <-- bValidSize = sal_True; } else { bValidSize = sal_True; //Fixe Frms formatieren sich nicht. //Flys stellen ihre Groesse anhand des Attr ein. SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height(); nNewSize -= nUL; if( nNewSize < MINFLY ) nNewSize = MINFLY; (Prt().*fnRect->fnSetHeight)( nNewSize ); nNewSize += nUL - (Frm().*fnRect->fnGetHeight)(); (Frm().*fnRect->fnAddBottom)( nNewSize ); // --> OD 2006-08-16 #i68520# if ( nNewSize != 0 ) { InvalidateObjRectWithSpaces(); } // <-- } if ( !bFormatHeightOnly ) { ASSERT( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" ) SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width(); if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE ) { // #i9046# Autowidth for fly frames const SwTwips nAutoWidth = CalcAutoWidth(); if ( nAutoWidth ) { if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() ) nNewSize = Max( nNewSize - nLR, nAutoWidth ); else nNewSize = nAutoWidth; } } /*else nNewSize -= nLR;*/ else {//Bug 120881:For enlarging fixed size Pagenumber frame,kangjian if(nNewSize <= 500 && IsPageNumberingFrm()) nNewSize = nNewSize - nLR + 150; else nNewSize -= nLR; //Bug 120881(End) } if( nNewSize < MINFLY ) nNewSize = MINFLY; (Prt().*fnRect->fnSetWidth)( nNewSize ); nNewSize += nLR - (Frm().*fnRect->fnGetWidth)(); (Frm().*fnRect->fnAddRight)( nNewSize ); // --> OD 2006-08-16 #i68520# if ( nNewSize != 0 ) { InvalidateObjRectWithSpaces(); } // <-- } } ColUnlock(); } // OD 14.03.2003 #i11760# - change parameter : type ; // default value = false. // OD 14.03.2003 #i11760# - add new parameter with // default value = false. // OD 11.04.2003 #108824# - new parameter was used by method // to avoid follow formatting // for text frames. But, unformatted follows causes // problems in method , // which assumes that the follows are formatted. // Thus, no longer used by . //void CalcCntnt( SwLayoutFrm *pLay, sal_Bool bNoColl ) void CalcCntnt( SwLayoutFrm *pLay, bool bNoColl, bool bNoCalcFollow ) { SwSectionFrm* pSect; sal_Bool bCollect = sal_False; if( pLay->IsSctFrm() ) { pSect = (SwSectionFrm*)pLay; if( pSect->IsEndnAtEnd() && !bNoColl ) { bCollect = sal_True; SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect ); } pSect->CalcFtnCntnt(); } else pSect = NULL; SwFrm *pFrm = pLay->ContainsAny(); if ( !pFrm ) { if( pSect ) { if( pSect->HasFollow() ) pFrm = pSect->GetFollow()->ContainsAny(); if( !pFrm ) { if( pSect->IsEndnAtEnd() ) { if( bCollect ) pLay->GetFmt()->GetDoc()->GetLayouter()-> InsertEndnotes( pSect ); sal_Bool bLock = pSect->IsFtnLock(); pSect->SetFtnLock( sal_True ); pSect->CalcFtnCntnt(); pSect->CalcFtnCntnt(); pSect->SetFtnLock( bLock ); } return; } pFrm->_InvalidatePos(); } else return; } pFrm->InvalidatePage(); do { // local variables to avoid loops caused by anchored object positioning SwAnchoredObject* pAgainObj1 = 0; SwAnchoredObject* pAgainObj2 = 0; // FME 2007-08-30 #i81146# new loop control sal_uInt16 nLoopControlRuns = 0; const sal_uInt16 nLoopControlMax = 20; const SwFrm* pLoopControlCond = 0; SwFrm* pLast; do { pLast = pFrm; if( pFrm->IsVertical() ? ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() ) : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) ) { pFrm->Prepare( PREP_FIXSIZE_CHG ); pFrm->_InvalidateSize(); } if ( pFrm->IsTabFrm() ) { ((SwTabFrm*)pFrm)->bCalcLowers = sal_True; // OD 26.08.2003 #i18103# - lock move backward of follow table, // if no section content is formatted or follow table belongs // to the section, which content is formatted. if ( ((SwTabFrm*)pFrm)->IsFollow() && ( !pSect || pSect == pFrm->FindSctFrm() ) ) { ((SwTabFrm*)pFrm)->bLockBackMove = sal_True; } } // OD 14.03.2003 #i11760# - forbid format of follow, if requested. if ( bNoCalcFollow && pFrm->IsTxtFrm() ) static_cast(pFrm)->ForbidFollowFormat(); pFrm->Calc(); // OD 14.03.2003 #i11760# - reset control flag for follow format. if ( pFrm->IsTxtFrm() ) { static_cast(pFrm)->AllowFollowFormat(); } // #111937# The keep-attribute can cause the position // of the prev to be invalid: // OD 2004-03-15 #116560# - Do not consider invalid previous frame // due to its keep-attribute, if current frame is a follow or is locked. // --> OD 2005-03-08 #i44049# - do not consider invalid previous // frame due to its keep-attribute, if it can't move forward. // --> OD 2006-01-27 #i57765# - do not consider invalid previous // frame, if current frame has a column/page break before attribute. SwFrm* pTmpPrev = pFrm->FindPrev(); SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0; SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0; bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm && !pTmpFlowFrm->IsFollow() && !StackHack::IsLocked() && // #i76382# !pTmpFlowFrm->IsJoinLocked() && !pTmpPrev->GetValidPosFlag() && pLay->IsAnLower( pTmpPrev ) && pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) && pTmpPrevFlowFrm->IsKeepFwdMoveAllowed(); // <-- // format floating screen objects anchored to the frame. bool bRestartLayoutProcess = false; if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) ) { bool bAgain = false; SwPageFrm* pPageFrm = pFrm->FindPageFrm(); sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count(); for ( sal_uInt16 i = 0; i < nCnt; ++i ) { // --> OD 2004-07-01 #i28701# SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i]; // determine, if anchored object has to be formatted. if ( pAnchoredObj->PositionLocked() ) { continue; } // format anchored object if ( pAnchoredObj->IsFormatPossible() ) { // --> OD 2005-05-17 #i43737# - no invalidation of // anchored object needed - causes loops for as-character // anchored objects. //pAnchoredObj->InvalidateObjPos(); // <-- SwRect aRect( pAnchoredObj->GetObjRect() ); if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) ) { bRestartLayoutProcess = true; break; } // --> OD 2004-08-25 #i3317# - restart layout process, // if the position of the anchored object is locked now. if ( pAnchoredObj->PositionLocked() ) { bRestartLayoutProcess = true; break; } // <-- if ( aRect != pAnchoredObj->GetObjRect() ) { bAgain = true; if ( pAgainObj2 == pAnchoredObj ) { ASSERT( false, "::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" ); //Oszillation unterbinden. SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); SwFmtSurround aAttr( rFmt.GetSurround() ); if( SURROUND_THROUGHT != aAttr.GetSurround() ) { // Bei autopositionierten hilft manchmal nur // noch, auf Durchlauf zu schalten if ((rFmt.GetAnchor().GetAnchorId() == FLY_AT_CHAR) && (SURROUND_PARALLEL == aAttr.GetSurround())) { aAttr.SetSurround( SURROUND_THROUGHT ); } else { aAttr.SetSurround( SURROUND_PARALLEL ); } rFmt.LockModify(); rFmt.SetFmtAttr( aAttr ); rFmt.UnlockModify(); } } else { if ( pAgainObj1 == pAnchoredObj ) pAgainObj2 = pAnchoredObj; pAgainObj1 = pAnchoredObj; } } if ( !pFrm->GetDrawObjs() ) break; if ( pFrm->GetDrawObjs()->Count() < nCnt ) { --i; --nCnt; } } } // --> OD 2004-06-11 #i28701# - restart layout process, if // requested by floating screen object formatting if ( bRestartLayoutProcess ) { pFrm = pLay->ContainsAny(); pAgainObj1 = 0L; pAgainObj2 = 0L; continue; } // OD 2004-05-17 #i28701# - format anchor frame after its objects // are formatted, if the wrapping style influence has to be considered. if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) ) { pFrm->Calc(); } // <-- if ( bAgain ) { pFrm = pLay->ContainsCntnt(); if ( pFrm && pFrm->IsInTab() ) pFrm = pFrm->FindTabFrm(); if( pFrm && pFrm->IsInSct() ) { SwSectionFrm* pTmp = pFrm->FindSctFrm(); if( pTmp != pLay && pLay->IsAnLower( pTmp ) ) pFrm = pTmp; } if ( pFrm == pLoopControlCond ) ++nLoopControlRuns; else { nLoopControlRuns = 0; pLoopControlCond = pFrm; } if ( nLoopControlRuns < nLoopControlMax ) continue; #if OSL_DEBUG_LEVEL > 1 ASSERT( false, "LoopControl in CalcCntnt" ) #endif } } if ( pFrm->IsTabFrm() ) { if ( ((SwTabFrm*)pFrm)->IsFollow() ) ((SwTabFrm*)pFrm)->bLockBackMove = sal_False; } pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext(); if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect ) { // Es koennen hier leere SectionFrms herumspuken while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() ) pFrm = pFrm->FindNext(); // Wenn FindNext den Follow des urspruenglichen Bereichs liefert, // wollen wir mit dessen Inhalt weitermachen, solange dieser // zurueckfliesst. if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() || ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) ) { pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); if( pFrm ) pFrm->_InvalidatePos(); } } // Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste // CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in // pLay zu landen. Solange diese Frames in pLay landen, geht's weiter. } while ( pFrm && ( pLay->IsAnLower( pFrm ) || ( pSect && ( ( pSect->HasFollow() && ( pLay->IsAnLower( pLast ) || ( pLast->IsInSct() && pLast->FindSctFrm()->IsAnFollow(pSect) ) ) && pSect->GetFollow()->IsAnLower( pFrm ) ) || ( pFrm->IsInSct() && pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) ); if( pSect ) { if( bCollect ) { pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect); pSect->CalcFtnCntnt(); } if( pSect->HasFollow() ) { SwSectionFrm* pNxt = pSect->GetFollow(); while( pNxt && !pNxt->ContainsCntnt() ) pNxt = pNxt->GetFollow(); if( pNxt ) pNxt->CalcFtnCntnt(); } if( bCollect ) { pFrm = pLay->ContainsAny(); bCollect = sal_False; if( pFrm ) continue; } } break; } while( sal_True ); } /************************************************************************* |* |* SwFlyFrm::MakeFlyPos() |* |* Ersterstellung MA ?? |* Letzte Aenderung MA 14. Nov. 96 |* |*************************************************************************/ // OD 2004-03-23 #i26791# //void SwFlyFrm::MakeFlyPos() void SwFlyFrm::MakeObjPos() { if ( !bValidPos ) { bValidPos = sal_True; // OD 29.10.2003 #113049# - use new class to position object GetAnchorFrm()->Calc(); objectpositioning::SwToLayoutAnchoredObjectPosition aObjPositioning( *GetVirtDrawObj() ); aObjPositioning.CalcPosition(); // --> OD 2006-10-05 #i58280# // update relative position SetCurrRelPos( aObjPositioning.GetRelPos() ); // <-- SWRECTFN( GetAnchorFrm() ); aFrm.Pos( aObjPositioning.GetRelPos() ); aFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)(); // --> OD 2006-09-11 #i69335# InvalidateObjRectWithSpaces(); // <-- } } /************************************************************************* |* |* SwFlyFrm::MakePrtArea() |* |* Ersterstellung MA 23. Jun. 93 |* Letzte Aenderung MA 23. Jun. 93 |* |*************************************************************************/ void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs ) { if ( !bValidPrtArea ) { bValidPrtArea = sal_True; // OD 31.07.2003 #110978# - consider vertical layout SWRECTFN( this ) (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(), rAttrs.CalcRightLine() ); (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(), rAttrs.CalcBottomLine() ); } } /************************************************************************* |* |* SwFlyFrm::_Grow(), _Shrink() |* |* Ersterstellung MA 05. Oct. 92 |* Letzte Aenderung MA 05. Sep. 96 |* |*************************************************************************/ SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst ) { SWRECTFN( this ) if ( Lower() && !IsColLocked() && !HasFixSize() ) { SwTwips nSize = (Frm().*fnRect->fnGetHeight)(); if( nSize > 0 && nDist > ( LONG_MAX - nSize ) ) nDist = LONG_MAX - nSize; if ( nDist <= 0L ) return 0L; if ( Lower()->IsColumnFrm() ) { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber //das Wachstum (wg. des Ausgleichs). if ( !bTst ) { // --> OD 2004-06-09 #i28701# - unlock position of Writer fly frame UnlockPosition(); _InvalidatePos(); InvalidateSize(); } return 0L; } if ( !bTst ) { const SwRect aOld( GetObjRectWithSpaces() ); _InvalidateSize(); const sal_Bool bOldLock = bLocked; Unlock(); if ( IsFlyFreeFrm() ) { // --> OD 2004-11-12 #i37068# - no format of position here // and prevent move in method . // This is needed to prevent layout loop caused by nested // Writer fly frames - inner Writer fly frames format its // anchor, which grows/shrinks the outer Writer fly frame. // Note: position will be invalidated below. bValidPos = sal_True; // --> OD 2005-10-10 #i55416# // Suppress format of width for autowidth frame, because the // format of the width would call // for the lower frame, which initiated this grow. const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly; const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize(); if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE ) { bFormatHeightOnly = sal_True; } // <-- static_cast(this)->SetNoMoveOnCheckClip( true ); ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll(); static_cast(this)->SetNoMoveOnCheckClip( false ); // --> OD 2005-10-10 #i55416# if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE ) { bFormatHeightOnly = bOldFormatHeightOnly; } // <-- // <-- } else MakeAll(); _InvalidateSize(); InvalidatePos(); if ( bOldLock ) Lock(); const SwRect aNew( GetObjRectWithSpaces() ); if ( aOld != aNew ) ::Notify( this, FindPageFrm(), aOld ); return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)(); } return nDist; } return 0L; } SwTwips SwFlyFrm::_Shrink( SwTwips nDist, sal_Bool bTst ) { if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() ) { SWRECTFN( this ) SwTwips nHeight = (Frm().*fnRect->fnGetHeight)(); if ( nDist > nHeight ) nDist = nHeight; SwTwips nVal = nDist; if ( IsMinHeight() ) { const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize(); SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight(); nVal = Min( nDist, nHeight - nFmtHeight ); } if ( nVal <= 0L ) return 0L; if ( Lower()->IsColumnFrm() ) { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber //das Wachstum (wg. des Ausgleichs). if ( !bTst ) { SwRect aOld( GetObjRectWithSpaces() ); (Frm().*fnRect->fnSetHeight)( nHeight - nVal ); // --> OD 2006-08-16 #i68520# if ( nHeight - nVal != 0 ) { InvalidateObjRectWithSpaces(); } // <-- nHeight = (Prt().*fnRect->fnGetHeight)(); (Prt().*fnRect->fnSetHeight)( nHeight - nVal ); _InvalidatePos(); InvalidateSize(); ::Notify( this, FindPageFrm(), aOld ); NotifyDrawObj(); if ( GetAnchorFrm()->IsInFly() ) AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst ); } return 0L; } if ( !bTst ) { const SwRect aOld( GetObjRectWithSpaces() ); _InvalidateSize(); const sal_Bool bOldLocked = bLocked; Unlock(); if ( IsFlyFreeFrm() ) { // --> OD 2004-11-12 #i37068# - no format of position here // and prevent move in method . // This is needed to prevent layout loop caused by nested // Writer fly frames - inner Writer fly frames format its // anchor, which grows/shrinks the outer Writer fly frame. // Note: position will be invalidated below. bValidPos = sal_True; // --> OD 2005-10-10 #i55416# // Suppress format of width for autowidth frame, because the // format of the width would call // for the lower frame, which initiated this shrink. const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly; const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize(); if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE ) { bFormatHeightOnly = sal_True; } // <-- static_cast(this)->SetNoMoveOnCheckClip( true ); ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll(); static_cast(this)->SetNoMoveOnCheckClip( false ); // --> OD 2005-10-10 #i55416# if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE ) { bFormatHeightOnly = bOldFormatHeightOnly; } // <-- // <-- } else MakeAll(); _InvalidateSize(); InvalidatePos(); if ( bOldLocked ) Lock(); const SwRect aNew( GetObjRectWithSpaces() ); if ( aOld != aNew ) { ::Notify( this, FindPageFrm(), aOld ); if ( GetAnchorFrm()->IsInFly() ) AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst ); } return (aOld.*fnRect->fnGetHeight)() - (aNew.*fnRect->fnGetHeight)(); } return nVal; } return 0L; } /************************************************************************* |* |* SwFlyFrm::ChgSize() |* |* Ersterstellung MA 05. Oct. 92 |* Letzte Aenderung MA 04. Sep. 96 |* |*************************************************************************/ Size SwFlyFrm::ChgSize( const Size& aNewSize ) { // --> OD 2006-01-19 #i53298# // If the fly frame anchored at-paragraph or at-character contains an OLE // object, assure that the new size fits into the current clipping area // of the fly frame Size aAdjustedNewSize( aNewSize ); { if ( dynamic_cast(this) && Lower() && dynamic_cast(Lower()) && static_cast(Lower())->GetNode()->GetOLENode() ) { SwRect aClipRect; ::CalcClipRect( GetVirtDrawObj(), aClipRect, sal_False ); if ( aAdjustedNewSize.Width() > aClipRect.Width() ) { aAdjustedNewSize.setWidth( aClipRect.Width() ); } if ( aAdjustedNewSize.Height() > aClipRect.Height() ) { aAdjustedNewSize.setWidth( aClipRect.Height() ); } } } // <-- if ( aAdjustedNewSize != Frm().SSize() ) { SwFrmFmt *pFmt = GetFmt(); SwFmtFrmSize aSz( pFmt->GetFrmSize() ); aSz.SetWidth( aAdjustedNewSize.Width() ); // --> OD 2006-01-19 #i53298# - no tolerance any more. // If it reveals that the tolerance is still needed, then suppress a // call, if equals the current attribute. // if ( Abs(aAdjustedNewSize.Height() - aSz.GetHeight()) > 1 ) aSz.SetHeight( aAdjustedNewSize.Height() ); // <-- // uebers Doc fuers Undo! pFmt->GetDoc()->SetAttr( aSz, *pFmt ); return aSz.GetSize(); } else return Frm().SSize(); } /************************************************************************* |* |* SwFlyFrm::IsLowerOf() |* |* Ersterstellung MA 27. Dec. 93 |* Letzte Aenderung MA 27. Dec. 93 |* |*************************************************************************/ sal_Bool SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const { ASSERT( GetAnchorFrm(), "8-( Fly is lost in Space." ); const SwFrm* pFrm = GetAnchorFrm(); do { if ( pFrm == pUpperFrm ) return sal_True; pFrm = pFrm->IsFlyFrm() ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm() : pFrm->GetUpper(); } while ( pFrm ); return sal_False; } /************************************************************************* |* |* SwFlyFrm::Cut() |* |* Ersterstellung MA 23. Feb. 94 |* Letzte Aenderung MA 23. Feb. 94 |* |*************************************************************************/ void SwFlyFrm::Cut() { } /************************************************************************* |* |* SwFrm::AppendFly(), RemoveFly() |* |* Ersterstellung MA 25. Aug. 92 |* Letzte Aenderung MA 09. Jun. 95 |* |*************************************************************************/ void SwFrm::AppendFly( SwFlyFrm *pNew ) { if ( !pDrawObjs ) pDrawObjs = new SwSortedObjs(); pDrawObjs->Insert( *pNew ); pNew->ChgAnchorFrm( this ); SwPageFrm* pPage = FindPageFrm(); if ( pPage != NULL ) { pPage->AppendFlyToPage( pNew ); } } void SwFrm::RemoveFly( SwFlyFrm *pToRemove ) { //Bei der Seite Abmelden - kann schon passiert sein weil die Seite //bereits destruiert wurde. SwPageFrm *pPage = pToRemove->FindPageFrm(); if ( pPage && pPage->GetSortedObjs() ) { pPage->RemoveFlyFromPage( pToRemove ); } // --> OD 2008-05-19 #i73201# else { if ( pToRemove->IsAccessibleFrm() && pToRemove->GetFmt() && !pToRemove->IsFlyInCntFrm() ) { SwRootFrm *pRootFrm = getRootFrm(); if( pRootFrm && pRootFrm->IsAnyShellAccessible() ) { ViewShell *pVSh = pRootFrm->GetCurrShell(); if( pVSh && pVSh->Imp() ) { pVSh->Imp()->DisposeAccessibleFrm( pToRemove ); } } } } // <-- pDrawObjs->Remove( *pToRemove ); if ( !pDrawObjs->Count() ) DELETEZ( pDrawObjs ); pToRemove->ChgAnchorFrm( 0 ); if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT GetUpper()->InvalidateSize(); } /************************************************************************* |* |* SwFrm::AppendDrawObj(), RemoveDrawObj() |* |* --> OD 2004-07-06 #i28701# - new methods |* |*************************************************************************/ void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) { if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) { ASSERT( false, "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" ); return; } if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) && _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this ) { // perform disconnect from layout, if 'master' drawing object is appended // to a new frame. static_cast(::GetUserCall( _rNewObj.GetDrawObj() ))-> DisconnectFromLayout( false ); } if ( _rNewObj.GetAnchorFrm() != this ) { if ( !pDrawObjs ) pDrawObjs = new SwSortedObjs(); pDrawObjs->Insert( _rNewObj ); _rNewObj.ChgAnchorFrm( this ); } // --> OD 2010-09-14 #i113730# // Assure the control objects and group objects containing controls are on the control layer if ( ::CheckControlLayer( _rNewObj.DrawObj() ) ) { const IDocumentDrawModelAccess* pIDDMA = (IsFlyFrm()) ? static_cast(this)->GetFmt()-> getIDocumentDrawModelAccess() : GetUpper()->GetFmt()->getIDocumentDrawModelAccess(); const SdrLayerID aCurrentLayer(_rNewObj.DrawObj()->GetLayer()); const SdrLayerID aControlLayerID(pIDDMA->GetControlsId()); const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId()); if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID) { if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() || aCurrentLayer == pIDDMA->GetInvisibleHeavenId() ) { _rNewObj.DrawObj()->SetLayer(aInvisibleControlLayerID); } else { _rNewObj.DrawObj()->SetLayer(aControlLayerID); } } } // <-- // no direct positioning needed, but invalidate the drawing object position _rNewObj.InvalidateObjPos(); // register at page frame SwPageFrm* pPage = FindPageFrm(); if ( pPage ) { pPage->AppendDrawObjToPage( _rNewObj ); } // Notify accessible layout. ViewShell* pSh = getRootFrm()->GetCurrShell(); if( pSh ) { SwRootFrm* pLayout = getRootFrm(); if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() ); } } void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) { // Notify accessible layout. ViewShell* pSh = getRootFrm()->GetCurrShell(); if( pSh ) { SwRootFrm* pLayout = getRootFrm(); if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() ); } // deregister from page frame SwPageFrm* pPage = _rToRemoveObj.GetPageFrm(); if ( pPage && pPage->GetSortedObjs() ) pPage->RemoveDrawObjFromPage( _rToRemoveObj ); pDrawObjs->Remove( _rToRemoveObj ); if ( !pDrawObjs->Count() ) DELETEZ( pDrawObjs ); _rToRemoveObj.ChgAnchorFrm( 0 ); } /************************************************************************* |* |* SwFrm::InvalidateObjs() |* |* Ersterstellung MA 29. Nov. 96 |* Letzte Aenderung MA 29. Nov. 96 |* |*************************************************************************/ // --> OD 2004-07-01 #i28701# - change purpose of method and adjust its name void SwFrm::InvalidateObjs( const bool _bInvaPosOnly, const bool _bNoInvaOfAsCharAnchoredObjs ) { if ( GetDrawObjs() ) { // --> OD 2004-10-08 #i26945# - determine page the frame is on, // in order to check, if anchored object is registered at the same // page. const SwPageFrm* pPageFrm = FindPageFrm(); // <-- // --> OD 2004-07-01 #i28701# - re-factoring sal_uInt32 i = 0; for ( ; i < GetDrawObjs()->Count(); ++i ) { SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i]; if ( _bNoInvaOfAsCharAnchoredObjs && (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) ) { continue; } // --> OD 2004-10-08 #i26945# - no invalidation, if anchored object // isn't registered at the same page and instead is registered at // the page, where its anchor character text frame is on. if ( pAnchoredObj->GetPageFrm() && pAnchoredObj->GetPageFrm() != pPageFrm ) { SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm(); if ( pAnchorCharFrm && pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() ) { continue; } // --> OD 2004-11-24 #115759# - unlock its position, if anchored // object isn't registered at the page, where its anchor // character text frame is on, respectively if it has no // anchor character text frame. else { pAnchoredObj->UnlockPosition(); } // <-- } // <-- // --> OD 2005-07-18 #i51474# - reset flag, that anchored object // has cleared environment, and unlock its position, if the anchored // object is registered at the same page as the anchor frame is on. if ( pAnchoredObj->ClearedEnvironment() && pAnchoredObj->GetPageFrm() && pAnchoredObj->GetPageFrm() == pPageFrm ) { pAnchoredObj->UnlockPosition(); pAnchoredObj->SetClearedEnvironment( false ); } // <-- // distinguish between writer fly frames and drawing objects if ( pAnchoredObj->ISA(SwFlyFrm) ) { SwFlyFrm* pFly = static_cast(pAnchoredObj); pFly->_Invalidate(); pFly->_InvalidatePos(); if ( !_bInvaPosOnly ) pFly->_InvalidateSize(); } else { pAnchoredObj->InvalidateObjPos(); } // end of distinction between writer fly frames and drawing objects } // end of loop on objects, which are connected to the frame } } /************************************************************************* |* |* SwLayoutFrm::NotifyLowerObjs() |* |*************************************************************************/ // --> OD 2004-07-01 #i28701# - change purpose of method and its name // --> OD 2004-10-08 #i26945# - correct check, if anchored object is a lower // of the layout frame. E.g., anchor character text frame can be a follow text // frame. // --> OD 2005-03-11 #i44016# - add parameter <_bUnlockPosOfObjs> to // force an unlockposition call for the lower objects. void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs ) { // invalidate lower floating screen objects SwPageFrm* pPageFrm = FindPageFrm(); if ( pPageFrm && pPageFrm->GetSortedObjs() ) { SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs()); for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) { SwAnchoredObject* pObj = rObjs[i]; // --> OD 2004-10-08 #i26945# - check, if anchored object is a lower // of the layout frame is changed to check, if its anchor frame // is a lower of the layout frame. // determine the anchor frame - usually it's the anchor frame, // for at-character/as-character anchored objects the anchor character // text frame is taken. const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos(); // <-- if ( pObj->ISA(SwFlyFrm) ) { SwFlyFrm* pFly = static_cast(pObj); if ( pFly->Frm().Left() == WEIT_WECH ) continue; if ( pFly->IsAnLower( this ) ) continue; // --> OD 2004-10-08 #i26945# - use to check, if // fly frame is lower of layout frame resp. if fly frame is // at a different page registered as its anchor frame is on. const bool bLow = IsAnLower( pAnchorFrm ); if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm ) // <-- { pFly->_Invalidate( pPageFrm ); if ( !bLow || pFly->IsFlyAtCntFrm() ) { // --> OD 2005-03-11 #i44016# if ( _bUnlockPosOfObjs ) { pFly->UnlockPosition(); } // <-- pFly->_InvalidatePos(); } else pFly->_InvalidatePrt(); } } else { ASSERT( pObj->ISA(SwAnchoredDrawObject), " OD 2004-10-08 #i26945# - use to check, if // fly frame is lower of layout frame resp. if fly frame is // at a different page registered as its anchor frame is on. if ( IsAnLower( pAnchorFrm ) || pAnchorFrm->FindPageFrm() != pPageFrm ) // <-- { // --> OD 2005-03-11 #i44016# if ( _bUnlockPosOfObjs ) { pObj->UnlockPosition(); } // <-- pObj->InvalidateObjPos(); } } } } } /************************************************************************* |* |* SwFlyFrm::NotifyDrawObj() |* |* Ersterstellung OK 22. Nov. 94 |* Letzte Aenderung MA 10. Jan. 97 |* |*************************************************************************/ void SwFlyFrm::NotifyDrawObj() { SwVirtFlyDrawObj* pObj = GetVirtDrawObj(); pObj->SetRect(); pObj->SetRectsDirty(); pObj->SetChanged(); pObj->BroadcastObjectChange(); if ( GetFmt()->GetSurround().IsContour() ) ClrContourCache( pObj ); } /************************************************************************* |* |* SwFlyFrm::CalcRel() |* |* Ersterstellung MA 13. Jun. 96 |* Letzte Aenderung MA 10. Oct. 96 |* |*************************************************************************/ Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const { Size aRet( rSz.GetSize() ); const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper(); if( pRel ) // LAYER_IMPL { long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX; const ViewShell *pSh = getRootFrm()->GetCurrShell(); if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) && pSh && pSh->GetViewOptions()->getBrowseMode() && pSh->VisArea().HasArea() ) { nRelWidth = pSh->GetBrowseWidth(); nRelHeight = pSh->VisArea().Height(); Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); long nDiff = nRelWidth - pRel->Prt().Width(); if ( nDiff > 0 ) nRelWidth -= nDiff; nRelHeight -= 2*aBorder.Height(); nDiff = nRelHeight - pRel->Prt().Height(); if ( nDiff > 0 ) nRelHeight -= nDiff; } nRelWidth = Min( nRelWidth, pRel->Prt().Width() ); nRelHeight = Min( nRelHeight, pRel->Prt().Height() ); if( !pRel->IsPageFrm() ) { const SwPageFrm* pPage = FindPageFrm(); if( pPage ) { nRelWidth = Min( nRelWidth, pPage->Prt().Width() ); nRelHeight = Min( nRelHeight, pPage->Prt().Height() ); } } if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF ) aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100; if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF ) aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100; if ( rSz.GetWidthPercent() == 0xFF ) { aRet.Width() *= aRet.Height(); aRet.Width() /= rSz.GetHeight(); } else if ( rSz.GetHeightPercent() == 0xFF ) { aRet.Height() *= aRet.Width(); aRet.Height() /= rSz.GetWidth(); } } return aRet; } /************************************************************************* |* |* SwFlyFrm::CalcAutoWidth() |* |*************************************************************************/ SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm ) { SwTwips nRet = 0; SwTwips nMin = 0; const SwFrm* pFrm = rFrm.Lower(); // No autowidth defined for columned frames if ( !pFrm || pFrm->IsColumnFrm() ) return nRet; while ( pFrm ) { if ( pFrm->IsSctFrm() ) { nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm ); } if ( pFrm->IsTxtFrm() ) { nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent(); const SvxLRSpaceItem &rSpace = ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace(); if (!((SwTxtFrm*)pFrm)->IsLocked()) nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst(); } else if ( pFrm->IsTabFrm() ) { const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize(); if ( USHRT_MAX == rTblFmtSz.GetSize().Width() || text::HoriOrientation::NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() ) { const SwPageFrm* pPage = rFrm.FindPageFrm(); // auto width table nMin = pFrm->GetUpper()->IsVertical() ? pPage->Prt().Height() : pPage->Prt().Width(); } else { nMin = rTblFmtSz.GetSize().Width(); } } if ( nMin > nRet ) nRet = nMin; pFrm = pFrm->GetNext(); } return nRet; } SwTwips SwFlyFrm::CalcAutoWidth() const { return lcl_CalcAutoWidth( *this ); } /************************************************************************* |* |* SwFlyFrm::AddSpacesToFrm |* |* Ersterstellung MA 11. Nov. 96 |* Letzte Aenderung MA 10. Mar. 97 |* |*************************************************************************/ //SwRect SwFlyFrm::AddSpacesToFrm() const //{ // SwRect aRect( Frm() ); // const SvxULSpaceItem &rUL = GetFmt()->GetULSpace(); // const SvxLRSpaceItem &rLR = GetFmt()->GetLRSpace(); // aRect.Left( Max( aRect.Left() - long(rLR.GetLeft()), 0L ) ); // aRect.SSize().Width() += rLR.GetRight(); // aRect.Top( Max( aRect.Top() - long(rUL.GetUpper()), 0L ) ); // aRect.SSize().Height()+= rUL.GetLower(); // return aRect; //} /************************************************************************* |* |* SwFlyFrm::GetContour() |* |* Ersterstellung MA 09. Jan. 97 |* Letzte Aenderung MA 10. Jan. 97 |* |*************************************************************************/ /// OD 16.04.2003 #i13147# - If called for paint and the contains /// a graphic, load of intrinsic graphic has to be avoided. sal_Bool SwFlyFrm::GetContour( PolyPolygon& rContour, const sal_Bool _bForPaint ) const { sal_Bool bRet = sal_False; if( GetFmt()->GetSurround().IsContour() && Lower() && Lower()->IsNoTxtFrm() ) { SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode(); // OD 16.04.2003 #i13147# - determine instead of // in order to avoid load of graphic, if contains a graphic // node and method is called for paint. const GraphicObject* pGrfObj = NULL; sal_Bool bGrfObjCreated = sal_False; const SwGrfNode* pGrfNd = pNd->GetGrfNode(); if ( pGrfNd && _bForPaint ) { pGrfObj = &(pGrfNd->GetGrfObj()); } else { pGrfObj = new GraphicObject( pNd->GetGraphic() ); bGrfObjCreated = sal_True; } ASSERT( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at ." ); if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE ) { if( !pNd->HasContour() ) { // OD 16.04.2003 #i13147# - no for a graphic // during paint. Thus, return (value of should be ). if ( pGrfNd && _bForPaint ) { ASSERT( false, "SwFlyFrm::GetContour() - No Contour found at during paint." ); return bRet; } pNd->CreateContour(); } pNd->GetContour( rContour ); //Der Node haelt das Polygon passend zur Originalgroesse der Grafik //hier muss die Skalierung einkalkuliert werden. SwRect aClip; SwRect aOrig; Lower()->Calc(); ((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, sal_False ); // OD 16.04.2003 #i13147# - copy method code // in order to avoid that graphic has to be loaded for contour scale. //SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() ); { OutputDevice* pOutDev = Application::GetDefaultDevice(); const MapMode aDispMap( MAP_TWIP ); const MapMode aGrfMap( pGrfObj->GetPrefMapMode() ); const Size aGrfSize( pGrfObj->GetPrefSize() ); double fScaleX; double fScaleY; Size aOrgSize; Point aNewPoint; sal_Bool bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL; if ( bPixelMap ) aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap ); else aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap ); if ( aOrgSize.Width() && aOrgSize.Height() ) { fScaleX = (double) aOrig.Width() / aOrgSize.Width(); fScaleY = (double) aOrig.Height() / aOrgSize.Height(); for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ ) { Polygon& rPoly = rContour[ j ]; for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ ) { if ( bPixelMap ) aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap ); else aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap ); rPoly[ i ] = Point( FRound( aNewPoint.X() * fScaleX ), FRound( aNewPoint.Y() * fScaleY ) ); } } } } // OD 17.04.2003 #i13147# - destroy created . if ( bGrfObjCreated ) { delete pGrfObj; } rContour.Move( aOrig.Left(), aOrig.Top() ); if( !aClip.Width() ) aClip.Width( 1 ); if( !aClip.Height() ) aClip.Height( 1 ); rContour.Clip( aClip.SVRect() ); rContour.Optimize(POLY_OPTIMIZE_CLOSE); bRet = sal_True; } } return bRet; } // OD 2004-03-25 #i26791# const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const { return static_cast(GetDrawObj()); } SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() { return static_cast(DrawObj()); } // ============================================================================= // OD 2004-03-24 #i26791# - implementation of pure virtual method declared in // base class // ============================================================================= void SwFlyFrm::InvalidateObjPos() { InvalidatePos(); // --> OD 2006-08-10 #i68520# InvalidateObjRectWithSpaces(); // <-- } SwFrmFmt& SwFlyFrm::GetFrmFmt() { ASSERT( GetFmt(), " - missing frame format -> crash." ); return *GetFmt(); } const SwFrmFmt& SwFlyFrm::GetFrmFmt() const { ASSERT( GetFmt(), " - missing frame format -> crash." ); return *GetFmt(); } const SwRect SwFlyFrm::GetObjRect() const { return Frm(); } // --> OD 2006-10-05 #i70122# // for Writer fly frames the bounding rectangle equals the object rectangles const SwRect SwFlyFrm::GetObjBoundRect() const { return GetObjRect(); } // <-- // --> OD 2006-08-10 #i68520# bool SwFlyFrm::_SetObjTop( const SwTwips _nTop ) { const bool bChanged( Frm().Pos().Y() != _nTop ); Frm().Pos().Y() = _nTop; return bChanged; } bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft ) { const bool bChanged( Frm().Pos().X() != _nLeft ); Frm().Pos().X() = _nLeft; return bChanged; } // <-- /** method to assure that anchored object is registered at the correct page frame OD 2004-07-02 #i28701# @author OD */ void SwFlyFrm::RegisterAtCorrectPage() { // default behaviour is to do nothing. } /** method to determine, if a on the Writer fly frame is possible OD 2004-05-11 #i28701# @author OD */ bool SwFlyFrm::IsFormatPossible() const { return SwAnchoredObject::IsFormatPossible() && !IsLocked() && !IsColLocked(); } void SwFlyFrm::GetAnchoredObjects( std::list& aList, const SwFmt& rFmt ) { SwIterator aIter( rFmt ); for( SwFlyFrm* pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() ) aList.push_back( pFlyFrm ); } const SwFlyFrmFmt * SwFlyFrm::GetFmt() const { return static_cast< const SwFlyFrmFmt * >( GetDep() ); } SwFlyFrmFmt * SwFlyFrm::GetFmt() { return static_cast< SwFlyFrmFmt * >( GetDep() ); } //Bug 120881:Modify here for Directly Page Numbering sal_Bool SwFlyFrm::IsPageNumberingFrm() { if (!GetAnchorFrm())//Invalidate frame... return false; if (bInCnt || bLayout)//Incorrect anchor type... return false; if (!(GetAnchorFrm()->IsTxtFrm() && GetAnchorFrm()->GetUpper() && (GetAnchorFrm()->GetUpper()->FindFooterOrHeader())))//Not in header or footer frame return false; if (pNextLink || pPrevLink)//Linked... return false; SwFrmFmt* pFmt = NULL; if ((pFmt = GetFmt())) { if (pLower && pLower->GetNext() && pFmt->GetCol().GetNumCols()>1)//Has more than 1 column... return false; } if (!pLower)//Do not has even 1 child frame? return false; for (SwFrm* pIter = pLower;pIter!=NULL;pIter=pIter->GetNext()) { if (pIter->IsTxtFrm() && ((SwTxtFrm*)pIter)->HasPageNumberField()) { return true; } } return false; } //Bug 120881(End)