summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/flylay.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/flylay.cxx')
-rw-r--r--sw/source/core/layout/flylay.cxx997
1 files changed, 997 insertions, 0 deletions
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
new file mode 100644
index 000000000000..bee3d6ae889d
--- /dev/null
+++ b/sw/source/core/layout/flylay.cxx
@@ -0,0 +1,997 @@
+/*************************************************************************
+ *
+ * $RCSfile: flylay.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "flyfrm.hxx"
+#include "ftnfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "errhdl.hxx"
+#include "hints.hxx"
+#include "pam.hxx"
+#include "sectfrm.hxx"
+
+
+#ifndef _SVDPAGE_HXX //autogen
+#include <svx/svdpage.hxx>
+#endif
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include <svx/ulspitem.hxx>
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include <fmtanchr.hxx>
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include <fmtornt.hxx>
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include <fmtfsize.hxx>
+#endif
+#include "ndole.hxx"
+#include "tabfrm.hxx"
+#include "flyfrms.hxx"
+
+/*************************************************************************
+|*
+|* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm()
+|*
+|* Ersterstellung MA 03. Dec. 92
+|* Letzte Aenderung MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+ SwFlyFrm( pFmt, pAnch ),
+ pPage( 0 )
+{
+}
+
+SwFlyFreeFrm::~SwFlyFreeFrm()
+{
+ //und Tschuess.
+ if( GetPage() )
+ {
+ if( GetFmt()->GetDoc()->IsInDtor() )
+ {
+ if ( IsFlyAtCntFrm() && GetPage()->GetSortedObjs() )
+ GetPage()->GetSortedObjs()->Remove( GetVirtDrawObj() );
+ }
+ else
+ {
+ SwRect aTmp( AddSpacesToFrm() );
+ SwFlyFreeFrm::NotifyBackground( GetPage(), aTmp, PREP_FLY_LEAVE );
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFlyFreeFrm::NotifyBackground()
+|*
+|* Beschreibung Benachrichtigt den Hintergrund (alle CntntFrms die
+|* gerade ueberlappt werden. Ausserdem wird das Window in einigen
+|* Faellen direkt invalidiert (vor allem dort, wo keine CntntFrms
+|* ueberlappt werden.
+|* Es werden auch die CntntFrms innerhalb von anderen Flys
+|* beruecksichtigt.
+|* Ersterstellung MA 03. Dec. 92
+|* Letzte Aenderung MA 26. Aug. 93
+|*
+|*************************************************************************/
+
+void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPage,
+ const SwRect& rRect, PrepareHint eHint )
+{
+ ::Notify_Background( GetVirtDrawObj(), pPage, rRect, eHint, TRUE );
+}
+
+/*************************************************************************
+|*
+|* SwFlyFreeFrm::MakeAll()
+|*
+|* Ersterstellung MA 18. Feb. 94
+|* Letzte Aenderung MA 03. Mar. 97
+|*
+|*************************************************************************/
+
+void SwFlyFreeFrm::MakeAll()
+{
+ if ( !GetAnchor() || IsLocked() || IsColLocked() || !GetPage() )
+ return;
+
+ Lock(); //Der Vorhang faellt
+
+ //uebernimmt im DTor die Benachrichtigung
+ const SwFlyNotify aNotify( this );
+
+ if ( IsClipped() )
+ bValidPos = bValidSize = bHeightClipped = bWidthClipped = FALSE;
+
+ while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly )
+ {
+ const SwFmtFrmSize *pSz;
+ { //Zusaetzlicher Scope, damit aAccess vor dem Check zerstoert wird!
+
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ pSz = &rAttrs.GetAttrSet().GetFrmSize();
+
+ //Nur einstellen wenn das Flag gesetzt ist!!
+ if ( !bValidSize )
+ {
+ bValidPrtArea = FALSE;
+ const long nOldWidth = Frm().Width();
+ const Size aTmp( CalcRel( *pSz ) );
+ const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
+ aFrm.Width( Max( aTmp.Width(), nMin ) );
+ if ( nOldWidth != Frm().Width() )
+ {
+ bValidPos = FALSE; //Clipping kann notwendig sein.
+//MA 03. Mar. 97: Wozu das? Stoert bei #37008#
+// if ( aFrm.Width() > nOldWidth )
+// aFrm.Height( aTmp.Height() );
+ }
+ }
+
+ if ( !bValidPrtArea )
+ MakePrtArea( rAttrs );
+
+ if ( !bValidSize || bFormatHeightOnly )
+ {
+ bValidSize = FALSE;
+ Format( &rAttrs );
+ bFormatHeightOnly = FALSE;
+ }
+
+ if ( !bValidPos )
+ {
+ const Point aOldPos( Frm().Pos() );
+ MakeFlyPos();
+ if( aOldPos == Frm().Pos() )
+ {
+ if( !bValidPos && GetAnchor()->IsInSct() &&
+ !GetAnchor()->FindSctFrm()->IsValid() )
+ bValidPos = TRUE;
+ }
+ else
+ bValidSize = FALSE;
+ }
+ }
+ if ( bValidPos && bValidSize )
+ CheckClip( *pSz );
+ }
+ Unlock();
+
+ ASSERT( bHeightClipped || (Frm().Height() > 0 && Prt().Height() > 0),
+ "SwFlyFreeFrm::Format(), flipping Fly." );
+}
+
+/*************************************************************************
+|*
+|* SwFlyFreeFrm::CheckClip()
+|*
+|* Ersterstellung MA 21. Feb. 94
+|* Letzte Aenderung MA 03. Mar. 97
+|*
+|*************************************************************************/
+
+void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz )
+{
+ //Jetzt ist es ggf. an der Zeit geignete Massnahmen zu ergreifen wenn
+ //der Fly nicht in seine Umgebung passt.
+ //Zuerst gibt der Fly seine Position auf. Dananch wird er zunaechst
+ //Formatiert. Erst wenn er auch durch die Aufgabe der Position nicht
+ //passt wird die Breite oder Hoehe aufgegeben - der Rahmen wird soweit
+ //wie notwendig zusammengequetscht.
+
+ const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
+ SwRect aClip, aTmpStretch;
+ ::CalcClipRect( pObj, aClip, TRUE );
+ ::CalcClipRect( pObj, aTmpStretch, FALSE );
+ aClip._Intersection( aTmpStretch );
+
+ const long nBot = Frm().Bottom();
+ const long nRig = Frm().Right();
+ const long nClipBot = aClip.Bottom();
+ const long nClipRig = aClip.Right();
+
+ const FASTBOOL bBot = nBot > nClipBot;
+ const FASTBOOL bRig = nRig > nClipRig;
+ if ( bBot || bRig )
+ {
+ FASTBOOL bAgain = FALSE;
+ if ( bBot )
+ {
+ const long nOld = Frm().Top();
+ Frm().Pos().Y() = Max( aClip.Top(), aClip.Bottom() - Frm().Height());
+ if ( Frm().Top() != nOld )
+ bAgain = TRUE;
+ bHeightClipped = TRUE;
+ }
+ if ( bRig )
+ {
+ const long nOld = Frm().Left();
+ Frm().Pos().X() = Max( aClip.Left(), aClip.Right() - Frm().Width() );
+ if ( Frm().Left() != nOld )
+ {
+ const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient();
+ // Links ausgerichtete duerfen nicht nach links verschoben werden,
+ // wenn sie einem anderen ausweichen.
+ if( rH.GetHoriOrient() == HORI_LEFT )
+ Frm().Pos().X() = nOld;
+ else
+ bAgain = TRUE;
+ }
+ bWidthClipped = TRUE;
+ }
+ if ( bAgain )
+ bValidSize = FALSE;
+ else
+ {
+ //Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche
+ //hinein, und eine Positionskorrektur ist nicht erlaubt bzw.
+ //moeglich oder noetig.
+
+ //Fuer Flys mit OLE-Objekten als Lower sorgen wir dafuer, dass
+ //immer proportional Resized wird.
+ Size aOldSize( Frm().SSize() );
+
+ //Zuerst wird das FrmRect eingestellt, und dann auf den Frm
+ //uebertragen.
+ SwRect aFrmRect( Frm() );
+
+ if ( bBot )
+ {
+ long nDiff = nClipBot;
+ nDiff -= aFrmRect.Top() - 1; //nDiff ist die verfuegbare Strecke.
+ nDiff = aFrmRect.Height() - nDiff;
+ aFrmRect.Height( aFrmRect.Height() - nDiff );
+ bHeightClipped = TRUE;
+ }
+ if ( bRig )
+ {
+ long nDiff = nClipRig;
+ nDiff -= aFrmRect.Left() - 1;//nDiff ist die verfuegbare Strecke.
+ nDiff = aFrmRect.Width() - nDiff;
+ aFrmRect.Width( aFrmRect.Width() - nDiff );
+ bWidthClipped = TRUE;
+ }
+
+ if ( Lower() && Lower()->IsNoTxtFrm() &&
+ ((SwCntntFrm*)Lower())->GetNode()->GetOLENode() )
+ {
+ //Wenn Breite und Hoehe angepasst wurden, so ist die
+ //groessere Veraenderung massgeblich.
+ if ( aFrmRect.Width() != aOldSize.Width() &&
+ aFrmRect.Height()!= aOldSize.Height() )
+ {
+ if ( (aOldSize.Width() - aFrmRect.Width()) >
+ (aOldSize.Height()- aFrmRect.Height()) )
+ aFrmRect.Height( aOldSize.Height() );
+ else
+ aFrmRect.Width( aOldSize.Width() );
+ }
+
+ //Breite angepasst? - Hoehe dann proportional verkleinern
+ if( aFrmRect.Width() != aOldSize.Width() )
+ aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() /
+ aOldSize.Width() );
+
+ //Hoehe angepasst? - Breite dann proportional verkleinern
+ if( aFrmRect.Height() != aOldSize.Height() )
+ aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() /
+ aOldSize.Height() );
+ }
+
+ //Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden
+ //die neuen Werte in die Attribute eingetragen, weil es sonst
+ //ziemlich fiese Oszillationen gibt.
+ const long nPrtHeightDiff = Frm().Height() - Prt().Height();
+ const long nPrtWidthDiff = Frm().Width() - Prt().Width();
+ Frm().Height( aFrmRect.Height() );
+ Frm().Width ( aFrmRect.Width() );
+ if ( Lower() && Lower()->IsColumnFrm() )
+ {
+ ColLock(); //Grow/Shrink locken.
+ const Size aOldSize( Prt().SSize() );
+ Prt().Height( Frm().Height() - nPrtHeightDiff );
+ Prt().Width ( Frm().Width() - nPrtWidthDiff );
+ ChgLowersProp( aOldSize );
+ SwFrm *pLow = Lower();
+ do
+ { pLow->Calc();
+ // auch den (Column)BodyFrm mitkalkulieren
+ ((SwLayoutFrm*)pLow)->Lower()->Calc();
+ pLow = pLow->GetNext();
+ } while ( pLow );
+ ::CalcCntnt( this );
+ ColUnlock();
+/* MA 02. Sep. 96: Wenn das Attribut gesetzt wird funktionieren Flys in Flys
+ * nicht (30095 30096)
+ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+ pFmt->LockModify();
+ SwFmtFrmSize aFrmSize( rSz );
+ if ( bRig )
+ aFrmSize.SetWidth( Frm().Width() );
+ if ( bBot )
+ {
+ aFrmSize.SetSizeType( ATT_FIX_SIZE );
+ aFrmSize.SetHeight( Frm().Height() );
+ bFixHeight = TRUE;
+ bMinHeight = FALSE;
+ }
+ pFmt->SetAttr( aFrmSize );
+ pFmt->UnlockModify();
+*/
+//Stattdessen:
+ if ( !bValidSize && !bWidthClipped )
+ bFormatHeightOnly = bValidSize = TRUE;
+ }
+ else
+ {
+ Prt().Height( Frm().Height() - nPrtHeightDiff );
+ Prt().Width ( Frm().Width() - nPrtWidthDiff );
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFlyLayFrm::SwFlyLayFrm()
+|*
+|* Ersterstellung MA 25. Aug. 92
+|* Letzte Aenderung MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+ SwFlyFreeFrm( pFmt, pAnch )
+{
+ bLayout = TRUE;
+}
+
+/*************************************************************************
+|*
+|* SwFlyLayFrm::Modify()
+|*
+|* Ersterstellung MA 08. Feb. 93
+|* Letzte Aenderung MA 28. Aug. 93
+|*
+|*************************************************************************/
+
+void SwFlyLayFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+ USHORT nWhich = pNew ? pNew->Which() : 0;
+
+ SwFmtAnchor *pAnch = 0;
+ if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
+ ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, FALSE,
+ (const SfxPoolItem**)&pAnch ))
+ ; // Beim GetItemState wird der AnkerPointer gesetzt !
+
+ else if( RES_ANCHOR == nWhich )
+ {
+ //Ankerwechsel, ich haenge mich selbst um.
+ //Es darf sich nicht um einen Wechsel des Ankertyps handeln,
+ //dies ist nur ueber die SwFEShell moeglich.
+ pAnch = (SwFmtAnchor*)pNew;
+ }
+
+ if( pAnch )
+ {
+ ASSERT( pAnch->GetAnchorId() ==
+ GetFmt()->GetAnchor().GetAnchorId(),
+ "8-) Unzulaessiger Wechsel des Ankertyps." );
+
+ //Abmelden, Seite besorgen, an den entsprechenden LayoutFrm
+ //haengen.
+ SwRect aOld( AddSpacesToFrm() );
+ SwPageFrm *pOldPage = GetPage();
+ GetAnchor()->RemoveFly( this );
+
+ if( FLY_PAGE == pAnch->GetAnchorId() )
+ {
+ USHORT nPgNum = pAnch->GetPageNum();
+ SwRootFrm *pRoot = FindRootFrm();
+ SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
+ for ( USHORT i = 1; (i <= nPgNum) && pPage; ++i,
+ pPage = (SwPageFrm*)pPage->GetNext() )
+ {
+ if ( i == nPgNum )
+ pPage->PlaceFly( this, 0, pAnch );
+ }
+ if( !pPage )
+ {
+ pRoot->SetAssertFlyPages();
+ pRoot->AssertFlyPages();
+ }
+ }
+ else
+ {
+ SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
+ SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )->
+ GetCntntNode()->GetFrm( 0, 0, FALSE );
+ if( pCntnt )
+ {
+ SwFlyFrm *pTmp = pCntnt->FindFlyFrm();
+ if( pTmp )
+ pTmp->AppendFly( this );
+ }
+ }
+ if ( pOldPage && pOldPage != GetPage() )
+ NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
+ SetCompletePaint();
+ InvalidateAll();
+ SetNotifyBack();
+ }
+ else
+ SwFlyFrm::Modify( pOld, pNew );
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::AppendFly()
+|*
+|* Ersterstellung MA 10. Oct. 92
+|* Letzte Aenderung MA 08. Jun. 96
+|*
+|*************************************************************************/
+
+void SwPageFrm::AppendFly( SwFlyFrm *pNew )
+{
+ if ( !pNew->GetVirtDrawObj()->IsInserted() )
+ FindRootFrm()->GetDrawPage()->InsertObject(
+ (SdrObject*)pNew->GetVirtDrawObj(),
+ pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
+
+ InvalidateSpelling();
+ InvalidateAutoCompleteWords();
+
+ if ( GetUpper() )
+ {
+ ((SwRootFrm*)GetUpper())->SetIdleFlags();
+ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+ }
+
+ const SdrObjectPtr pObj = pNew->GetVirtDrawObj();
+ ASSERT( pNew->GetAnchor(), "Fly without Anchor" );
+ SwFlyFrm *pFly = pNew->GetAnchor()->FindFlyFrm();
+ if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
+ {
+ UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1;
+ if ( pObj->GetPage() )
+ pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum);
+ else
+ pObj->SetOrdNum( nNewNum );
+ }
+
+ //Flys die im Cntnt sitzen beachten wir nicht weiter.
+ if ( pNew->IsFlyInCntFrm() )
+ {
+ InvalidateFlyInCnt();
+ return;
+ }
+ InvalidateFlyCntnt();
+
+ if ( !pSortedObjs )
+ pSortedObjs = new SwSortDrawObjs();
+ if ( !pSortedObjs->Insert( pObj ) )
+ ASSERT( FALSE, "Fly nicht in Sorted eingetragen." );
+
+ ((SwFlyFreeFrm*)pNew)->SetPage( this );
+ pNew->InvalidatePage( this );
+
+
+ //fix(3018): Kein pNew->Calc() oder sonstiges hier.
+ //Code enfernt in flylay.cxx Rev 1.51
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::RemoveFly()
+|*
+|* Ersterstellung MA 10. Oct. 92
+|* Letzte Aenderung MA 26. Aug. 96
+|*
+|*************************************************************************/
+
+void SwPageFrm::RemoveFly( SwFlyFrm *pToRemove )
+{
+ const UINT32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
+ FindRootFrm()->GetDrawPage()->RemoveObject( nOrdNum );
+ pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
+
+ if ( GetUpper() )
+ {
+ if ( !pToRemove->IsFlyInCntFrm() )
+ ((SwRootFrm*)GetUpper())->SetSuperfluous();
+ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+ }
+
+ //Flys die im Cntnt sitzen beachten wir nicht weiter.
+ if ( pToRemove->IsFlyInCntFrm() )
+ return;
+
+ //Collections noch nicht loeschen. Das passiert am Ende
+ //der Action im RemoveSuperfluous der Seite - angestossen von gleich-
+ //namiger Methode der Root.
+ //Die FlyColl kann bereits weg sein, weil der DTor der Seite
+ //gerade 'laeuft'
+ if ( pSortedObjs )
+ {
+ pSortedObjs->Remove( pToRemove->GetVirtDrawObj() );
+ if ( !pSortedObjs->Count() )
+ { DELETEZ( pSortedObjs );
+ }
+ }
+ ((SwFlyFreeFrm*)pToRemove)->SetPage( 0 );
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::MoveFly
+|*
+|* Ersterstellung MA 25. Jan. 97
+|* Letzte Aenderung MA 25. Jan. 97
+|*
+|*************************************************************************/
+
+void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest )
+{
+ //Invalidierungen
+ if ( GetUpper() )
+ {
+ ((SwRootFrm*)GetUpper())->SetIdleFlags();
+ if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() )
+ ((SwRootFrm*)GetUpper())->SetSuperfluous();
+ }
+ pDest->InvalidateSpelling();
+ pDest->InvalidateAutoCompleteWords();
+
+ if ( pToMove->IsFlyInCntFrm() )
+ {
+ pDest->InvalidateFlyInCnt();
+ return;
+ }
+
+ //Die FlyColl kann bereits weg sein, weil der DTor der Seite
+ //gerade 'laeuft'
+ const SdrObjectPtr pObj = pToMove->GetVirtDrawObj();
+ if ( pSortedObjs )
+ {
+ pSortedObjs->Remove( pObj );
+ if ( !pSortedObjs->Count() )
+ { DELETEZ( pSortedObjs );
+ }
+ }
+
+ //Anmelden
+ if ( !pDest->GetSortedObjs() )
+ pDest->pSortedObjs = new SwSortDrawObjs();
+ if ( !pDest->GetSortedObjs()->Insert( pObj ) )
+ ASSERT( FALSE, "Fly nicht in Sorted eingetragen." );
+
+ ((SwFlyFreeFrm*)pToMove)->SetPage( pDest );
+ pToMove->InvalidatePage( pDest );
+ pToMove->SetNotifyBack();
+ pDest->InvalidateFlyCntnt();
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::AppendDrawObject(), RemoveDrawObject()
+|*
+|* Ersterstellung MA 09. Jan. 95
+|* Letzte Aenderung MA 31. Jul. 96
+|*
+|*************************************************************************/
+
+void SwPageFrm::AppendDrawObj( SwDrawContact *pNew )
+{
+ if ( GetUpper() )
+ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+
+ const SdrObjectPtr pObj = pNew->GetMaster();
+ ASSERT( pNew->GetAnchor(), "Contact without Anchor" );
+ SwFlyFrm *pFly = pNew->GetAnchor()->FindFlyFrm();
+ if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
+ {
+ UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1;
+ if ( pObj->GetPage() )
+ pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum);
+ else
+ pObj->SetOrdNum( nNewNum );
+ }
+
+ if ( FLY_IN_CNTNT == pNew->GetFmt()->GetAnchor().GetAnchorId() )
+ return;
+
+ if ( !pSortedObjs )
+ pSortedObjs = new SwSortDrawObjs();
+ if ( !pSortedObjs->Insert( pObj ) )
+ {
+#ifndef PRODUCT
+ USHORT nIdx;
+ ASSERT( pSortedObjs->Seek_Entry( pObj, &nIdx ),
+ "Fly nicht in Sorted eingetragen." );
+#endif
+ }
+ pNew->ChgPage( this );
+}
+
+void SwPageFrm::RemoveDrawObj( SwDrawContact *pToRemove )
+{
+ //Auch Zeichengebundene muessen hier leider durchlaufen, weil beim
+ //setzen des Attributes zuerst das Attribut gesetzt und dann das Modify
+ //versendet wird.
+
+ //Die FlyColl kann bereits weg sein, weil der DTor der Seite
+ //gerade 'laeuft'
+ if ( pSortedObjs )
+ {
+ const SdrObjectPtr *pDel = pSortedObjs->GetData();
+ pSortedObjs->Remove( pToRemove->GetMaster() );
+ if ( !pSortedObjs->Count() )
+ {
+ DELETEZ( pSortedObjs );
+ }
+ if ( GetUpper() )
+ {
+ if ( FLY_IN_CNTNT != pToRemove->GetFmt()->GetAnchor().GetAnchorId() )
+ {
+ ((SwRootFrm*)GetUpper())->SetSuperfluous();
+ InvalidatePage();
+ }
+ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+ }
+ }
+ pToRemove->ChgPage( 0 );
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::PlaceFly
+|*
+|* Ersterstellung MA 08. Feb. 93
+|* Letzte Aenderung MA 27. Feb. 93
+|*
+|*************************************************************************/
+
+SwFrm *SwPageFrm::PlaceFly( SwFlyFrm *pFly, SwFrmFmt *pFmt,
+ const SwFmtAnchor *pAnch )
+{
+ //Der Fly will immer an der Seite direkt haengen.
+ ASSERT( pAnch->GetAnchorId() == FLY_PAGE, "Unerwartete AnchorId." );
+
+ //Wenn ein Fly uebergeben wurde, so benutzen wir diesen, ansonsten wird
+ //mit dem Format einer erzeugt.
+ if ( pFly )
+ SwFrm::AppendFly( pFly );
+ else
+ { ASSERT( pFmt, ":-( kein Format fuer Fly uebergeben." );
+ pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this );
+ SwFrm::AppendFly( pFly );
+ ::RegistFlys( this, pFly );
+ }
+ return pFly;
+}
+
+/*************************************************************************
+|*
+|* ::CalcClipRect
+|*
+|* Ersterstellung AMA 24. Sep. 96
+|* Letzte Aenderung MA 18. Dec. 96
+|*
+|*************************************************************************/
+
+BOOL CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, BOOL bMove )
+{
+ BOOL bRet = TRUE;
+ if ( pSdrObj->IsWriterFlyFrame() )
+ {
+ const SwFlyFrm *pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm();
+ if( pFly->IsFlyLayFrm() )
+ {
+#ifdef AMA_OUT_OF_FLY
+ const SwFrm *pClip = pFly->GetAnchor()->FindPageFrm();
+#else
+ const SwFrm *pClip = pFly->GetAnchor();
+#endif
+ pClip->Calc();
+
+ rRect = pClip->Frm();
+
+ //Vertikales clipping: Top und Bottom, ggf. an PrtArea
+ const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient();
+ if( rV.GetVertOrient() != VERT_NONE &&
+ rV.GetRelationOrient() == PRTAREA )
+ {
+ rRect.Top( pClip->Frm().Top() + pClip->Prt().Top() );
+ rRect.Bottom( pClip->Frm().Top() + pClip->Prt().Bottom() );
+ }
+ //Horizontales clipping: Left und Right, ggf. an PrtArea
+ const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
+ if( rH.GetHoriOrient() != HORI_NONE &&
+ rH.GetRelationOrient() == PRTAREA )
+ {
+ rRect.Left( pClip->Frm().Left() + pClip->Prt().Left() );
+ rRect.Right( pClip->Frm().Left() + pClip->Prt().Right() );
+ }
+ }
+ else if( pFly->IsFlyAtCntFrm() )
+ {
+ const SwFrm *pClip = pFly->GetAnchor();
+ const SwLayoutFrm *pUp = pClip->GetUpper();
+ const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0;
+ USHORT nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER |
+ FRM_FOOTER | FRM_FTN
+ : FRM_BODY | FRM_FLY | FRM_HEADER |
+ FRM_FOOTER | FRM_CELL| FRM_FTN;
+
+ while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() )
+ {
+ pUp = pUp->GetUpper();
+ if ( !pCell && pUp->IsCellFrm() )
+ pCell = pUp;
+ }
+ if ( bMove )
+ {
+ if ( pUp->IsRootFrm() )
+ {
+ rRect = pUp->Prt();
+ rRect += pUp->Frm().Pos();
+
+ const SwPageFrm *pPg = (SwPageFrm*)pUp->Lower();
+ if( !pPg->Lower() )
+ pPg = (SwPageFrm*)pPg->GetNext();
+ const SwFrm *pBody = pPg->FindBodyCont();
+ if ( pBody->GetPrev() )
+ pBody->GetPrev()->Calc();
+ pBody->Calc();
+ rRect.Top( pBody->Frm().Top() + pBody->Prt().Top() );
+
+ //Den Bottom setzen wir auf den unteren Rand der letzten Seite.
+ pPg = ((SwRootFrm*)pUp)->GetLastPage();
+ if ( !pPg->Lower() )
+ pPg = (SwPageFrm*)pPg->GetPrev();
+ if ( pPg )
+ {
+ pPg->Calc();
+ pBody = pPg->FindBodyCont();
+ if ( pBody->GetPrev() )
+ pBody->GetPrev()->Calc();
+ pBody->Calc();
+ rRect.Bottom( pBody->Frm().Top() + pBody->Prt().Bottom());
+ if( pFly->GetFmt()->GetDoc()->IsBrowseMode() )
+ {
+ // Hier wird folgende Situation abgefangen: Im Browse-
+ // Modus hat man mehrere Seiten, die aktuelle Seite
+ // waechst gerade, die letzte Seite hat dies noch nicht
+ // mitbekommen, dann koennte der von der letzten Seite
+ // gelieferte nBot zu klein sein, der Fly sich also
+ // zum Clippen/Moven genoetigt sehen, obgleich genug
+ // Platz vorhanden ist.
+ const SwPageFrm* pMyPg = pClip->FindPageFrm();
+ if( pMyPg != pPg && pMyPg &&
+ pMyPg->Frm().Bottom() > pPg->Frm().Top() )
+ {
+ pBody = pMyPg->FindBodyCont();
+ if ( pBody->GetPrev() )
+ pBody->GetPrev()->Calc();
+ pBody->Calc();
+ SwTwips nBot = pBody->Frm().Top() + pBody->Prt().Bottom();
+ if( rRect.Bottom() < nBot )
+ rRect.Bottom( nBot );
+ }
+ }
+ }
+ pUp = 0;
+ }
+ }
+ if ( pUp )
+ {
+ if ( !pUp->IsFlyFrm() ||
+ (!pUp->Lower() || !pUp->Lower()->IsColumnFrm()) )
+ pUp->Calc();
+ if ( pUp->GetType() & FRM_BODY )
+ {
+ const SwPageFrm *pPg;
+ if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) )
+ pUp = pPg->FindBodyCont();
+ rRect = pUp->GetUpper()->Frm();
+ rRect.Pos().Y() = pUp->Frm().Top() + pUp->Prt().Top();
+ rRect.SSize().Height() = pUp->Prt().Height();
+ }
+ else
+ {
+ if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) &&
+ !pUp->Frm().IsInside( pFly->Frm().Pos() ) )
+ {
+ if( pUp->IsFlyFrm() )
+ {
+ SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp;
+ while( pTmpFly->GetNextLink() )
+ {
+ pTmpFly = pTmpFly->GetNextLink();
+ if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) )
+ break;
+ }
+ pUp = pTmpFly;
+ }
+ else if( pUp->IsInFtn() )
+ {
+ const SwFtnFrm *pTmp = pUp->FindFtnFrm();
+ while( pTmp->GetFollow() )
+ {
+ pTmp = pTmp->GetFollow();
+ if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) )
+ break;
+ }
+ pUp = pTmp;
+ }
+ }
+ rRect = pUp->Prt();
+ rRect.Pos() += pUp->Frm().Pos();
+ if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) )
+ {
+ rRect.Left ( pUp->GetUpper()->Frm().Left() );
+ rRect.Width( pUp->GetUpper()->Frm().Width());
+ }
+ else if ( pUp->IsCellFrm() ) //MA_FLY_HEIGHT
+ {
+ const SwFrm *pTab = pUp->FindTabFrm();
+ long nBottom = pTab->GetUpper()->Frm().Top() +
+ pTab->GetUpper()->Prt().Bottom();
+ rRect.Bottom( nBottom );
+ }
+ }
+ }
+ if ( pCell )
+ {
+ //CellFrms koennen auch in 'unerlaubten' Bereichen stehen, dann
+ //darf der Fly das auch.
+ SwRect aTmp( pCell->Prt() );
+ aTmp += pCell->Frm().Pos();
+ rRect.Union( aTmp );
+ }
+ }
+ else
+ {
+ if( bMove )
+ {
+ const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))
+ ->GetFmt();
+ const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+ const SwRect &rTmp = pFly->Frm();
+ long nTmpH = rUL.GetLower() + rUL.GetUpper() + rTmp.Height();
+ rRect.Width( rTmp.Width() );
+ rRect.Height( rTmp.Height() + nTmpH - 1 );
+ rRect.Pos( ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(),
+ ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() - nTmpH + 1 );
+ }
+ else
+ {
+ //Sizeable ist er bis zur Grosse der PrtArea
+ // des Uppers seines Ankers.
+ const SwFrm *pUp = pFly->GetAnchor()->GetUpper();
+ pUp->Calc();
+ rRect = pUp->Prt();
+ rRect += pUp->Frm().Pos();
+ }
+ }
+ }
+ else
+ {
+ const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj);
+ const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt();
+ const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+ if ( FLY_IN_CNTNT == rAnch.GetAnchorId() )
+ {
+ if( bMove )
+ {
+ //Verschiebbar ist das Teil nur vertikal um seinen Ankerpunkt herum.
+ SwRect aSnapRect( pSdrObj->GetSnapRect() );
+ const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+ long nTmpH = pSdrObj->GetBoundRect().GetHeight()+rUL.GetLower()+rUL.GetUpper();
+ rRect.Width( aSnapRect.Width() );
+ rRect.Height( aSnapRect.Height() + nTmpH - 1 );
+ rRect.Pos( pSdrObj->GetAnchorPos().X(),
+ pSdrObj->GetAnchorPos().Y() - nTmpH + 1 );
+ }
+ else
+ {
+ //Sizeable ist er bis zur Grosse der PrtArea des Uppers
+ //seines Ankers.
+ const SwFrm *pFrm = pC->GetAnchor();
+ if( !pFrm )
+ {
+ ((SwDrawContact*)pC)->ConnectToLayout();
+ pFrm = pC->GetAnchor();
+ }
+ const SwFrm *pUp = pFrm->GetUpper();
+ pUp->Calc();
+ rRect = pUp->Prt();
+ rRect += pUp->Frm().Pos();
+ }
+ }
+ else
+ bRet = FALSE;
+ }
+ return bRet;
+}
+
+