diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx')
-rw-r--r-- | binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx | 912 |
1 files changed, 912 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx new file mode 100644 index 000000000000..60173ace9e95 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx @@ -0,0 +1,912 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <hintids.hxx> + +#include <tools/bigint.hxx> +#include <bf_svx/protitem.hxx> +#include <fmtpdsc.hxx> +#include <pagedesc.hxx> + +#include <pagefrm.hxx> +#include <ftnfrm.hxx> + +#include <horiornt.hxx> + +#include <flyfrm.hxx> +#include <tabfrm.hxx> +#include <txtfrm.hxx> +#include <doc.hxx> +#include <pam.hxx> +#include <swtable.hxx> +#include <crstate.hxx> +#include <frmtool.hxx> +#include <hints.hxx> +#include <frmsh.hxx> +namespace binfilter { + + +//Fuer SwFlyFrm::GetCrsrOfst + + +/************************************************************************* +|* +|* SwLayoutFrm::GetCrsrOfst() +|* +|* Beschreibung: Sucht denjenigen CntntFrm, innerhalb dessen +|* PrtArea der Point liegt. +|* Ersterstellung MA 20. Jul. 92 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwPageFrm::GetCrsrOfst() +|* +|* Beschreibung: Sucht die Seite, innerhalb der der gesuchte Point +|* liegt. +|* Ersterstellung MA 20. Jul. 92 +|* Letzte Aenderung MA 18. Jul. 96 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwRootFrm::GetCrsrOfst() +|* +|* Beschreibung: Reicht Primaer den Aufruf an die erste Seite weiter. +|* Wenn der 'reingereichte Point veraendert wird, +|* so wird FALSE zurueckgegeben. +|* Ersterstellung MA 01. Jun. 92 +|* Letzte Aenderung MA 30. Nov. 94 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwCellFrm::GetCrsrOfst() +|* +|* Beschreibung Wenn es sich um eine Cntnt-tragende Cell handelt wird +|* der Crsr notfalls mit Gewalt in einen der CntntFrms +|* gesetzt. +|* In geschuetzte Zellen gibt es hier keinen Eingang. +|* Ersterstellung MA 04. Jun. 93 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwFlyFrm::GetCrsrOfst() +|* +|* Ersterstellung MA 15. Dec. 92 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ +//Problem: Wenn zwei Flys genau gleich gross sind und auf derselben +//Position stehen, so liegt jeder innerhalb des anderen. +//Da jeweils geprueft wird, ob der Point nicht zufaellig innerhalb eines +//anderen Flys liegt, der sich vollstaendig innerhalb des aktuellen befindet +//und ggf. ein rekursiver Aufruf erfolgt wuerde o.g. Situation zu einer +//endlosen Rekursion fuehren. +//Mit der Hilfsklasse SwCrsrOszControl unterbinden wir die Rekursion. Das +//GetCrsrOfst entscheidet sich bei einer Rekursion fuer denjenigen der +//am weitesten oben liegt. + + +/************************************************************************* +|* +|* Beschreibung Layoutabhaengiges Cursortravelling +|* Ersterstellung MA 23. Jul. 92 +|* Letzte Aenderung MA 06. Sep. 93 +|* +|*************************************************************************/ + + +/*N*/ const SwCntntFrm *lcl_GetNxtCnt( const SwCntntFrm* pCnt ) +/*N*/ { +/*N*/ return pCnt->GetNextCntntFrm(); +/*N*/ } + + +/*N*/ typedef const SwCntntFrm *(*GetNxtPrvCnt)( const SwCntntFrm* ); + +//Frame in wiederholter Headline? +/*N*/ FASTBOOL lcl_IsInRepeatedHeadline( const SwFrm *pFrm, +/*N*/ const SwTabFrm** ppTFrm = 0 ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 +/*N*/ } + + +//Ueberspringen geschuetzter Tabellenzellen. Optional auch +//Ueberspringen von wiederholten Headlines. +//MA 26. Jan. 98: Chg auch andere Geschuetzte Bereiche ueberspringen. +/*N*/ const SwCntntFrm * MA_FASTCALL lcl_MissProtectedFrames( const SwCntntFrm *pCnt, +/*N*/ GetNxtPrvCnt fnNxtPrv, +/*N*/ FASTBOOL bMissHeadline, +/*N*/ FASTBOOL bInReadOnly ) +/*N*/ { +/*N*/ if ( pCnt && pCnt->IsInTab() ) +/*N*/ { +/*N*/ BOOL bProtect = TRUE; +/*N*/ while ( pCnt && bProtect ) +/*N*/ { +/*N*/ const SwLayoutFrm *pCell = pCnt->GetUpper(); +/*N*/ while ( pCell && !pCell->IsCellFrm() ) +/*?*/ pCell = pCell->GetUpper(); +/*N*/ if ( !pCell || +/*N*/ ((bInReadOnly || !pCell->GetFmt()->GetProtect().IsCntntProtected()) && +/*N*/ (!bMissHeadline || !lcl_IsInRepeatedHeadline( pCell ) ))) +/*N*/ bProtect = FALSE; +/*N*/ else +/*?*/ pCnt = (*fnNxtPrv)( pCnt ); +/*N*/ } +/*N*/ } +/*N*/ else if ( !bInReadOnly ) +/*N*/ while ( pCnt && pCnt->IsProtected() ) +/*N*/ pCnt = (*fnNxtPrv)( pCnt ); +/*N*/ +/*N*/ return pCnt; +/*N*/ } + + + + +/************************************************************************* +|* +|* SwRootFrm::GetCurrPage() +|* +|* Beschreibung: Liefert die Nummer der aktuellen Seite. +|* Wenn die Methode einen PaM bekommt, so ist die aktuelle Seite +|* diejenige in der der PaM sitzt. Anderfalls ist die aktuelle +|* Seite die erste Seite innerhalb der VisibleArea. +|* Es wird nur auf den vorhandenen Seiten gearbeitet! +|* Ersterstellung MA 20. May. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwRootFrm::SetCurrPage() +|* +|* Beschreibung: Liefert einen PaM der am Anfang der gewuenschten +|* Seite sitzt. +|* Formatiert wird soweit notwendig +|* Liefert Null, wenn die Operation nicht moeglich ist. +|* Der PaM sitzt in der letzten Seite, wenn die Seitenzahl zu gross +|* gewaehlt wurde. +|* Ersterstellung MA 20. May. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwCntntFrm::StartxxPage(), EndxxPage() +|* +|* Beschreibung Cursor an Anfang/Ende der aktuellen/vorherigen/ +|* naechsten Seite. Alle sechs Methoden rufen GetFrmInPage() mit der +|* entsprechenden Parametrisierung. +|* Zwei Parameter steuern die Richtung: einer bestimmt die Seite, der +|* andere Anfang/Ende. +|* Fuer die Bestimmung der Seite und des Cntnt (Anfang/Ende) werden +|* die im folgenden definierten Funktionen benutzt. +|* Ersterstellung MA 15. Oct. 92 +|* Letzte Aenderung MA 28. Feb. 93 +|* +|*************************************************************************/ + + + + + +//Jetzt koennen auch die Funktionspointer initalisiert werden; +//sie sind in cshtyp.hxx declariert. + +//Liefert den ersten/den letzten Contentframe (gesteuert ueber +//den Parameter fnPosPage) in der +//aktuellen/vorhergehenden/folgenden Seite (gesteuert durch den +//Parameter fnWhichPage). + +/************************************************************************* +|* +|* SwLayoutFrm::GetCntntPos() +|* +|* Beschreibung Es wird der nachstliegende Cntnt zum uebergebenen +|* gesucht. Betrachtet werden die vorhergehende, die +|* aktuelle und die folgende Seite. +|* Wenn kein Inhalt gefunden wird, so wird der Bereich + * erweitert bis einer gefunden wird. +|* Zurueckgegeben wird die 'Semantisch richtige' Position +|* innerhalb der PrtArea des gefundenen CntntFrm +|* Ersterstellung MA 15. Jul. 92 +|* Letzte Aenderung MA 09. Jan. 97 +|* +|*************************************************************************/ +/*N*/ ULONG CalcDiff( const Point &rPt1, const Point &rPt2 ) +/*N*/ { +/*N*/ //Jetzt die Entfernung zwischen den beiden Punkten berechnen. +/*N*/ //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2 +/*N*/ sal_uInt32 dX = Max( rPt1.X(), rPt2.X() ) - +/*N*/ Min( rPt1.X(), rPt2.X() ), +/*N*/ dY = Max( rPt1.Y(), rPt2.Y() ) - +/*N*/ Min( rPt1.Y(), rPt2.Y() ); +/*N*/ BigInt dX1( dX ), dY1( dY ); +/*N*/ dX1 *= dX1; dY1 *= dY1; +/*N*/ return ::binfilter::SqRt( dX1 + dY1 ); +/*N*/ } + +// lcl_Inside ueberprueft, ob der Punkt innerhalb des Seitenteils liegt, in dem +// auch der CntntFrame liegt. Als Seitenteile gelten in diesem Zusammenhang +// Kopfzeile, Seitenbody, Fusszeile und FussnotenContainer. +// Dies dient dazu, dass ein CntntFrm, der im "richtigen" Seitenteil liegt, +// eher akzeptiert wird als ein anderer, der nicht dort liegt, auch wenn +// dessen Abstand zum Punkt geringer ist. + +/*N*/ const SwLayoutFrm* lcl_Inside( const SwCntntFrm *pCnt, Point& rPt ) +/*N*/ { +/*N*/ const SwLayoutFrm* pUp = pCnt->GetUpper(); +/*N*/ while( pUp ) +/*N*/ { +/*N*/ if( pUp->IsPageBodyFrm() || pUp->IsFooterFrm() || pUp->IsHeaderFrm() ) +/*N*/ { +/*N*/ if( rPt.Y() >= pUp->Frm().Top() && rPt.Y() <= pUp->Frm().Bottom() ) +/*?*/ return pUp; +/*N*/ return NULL; +/*N*/ } +/*N*/ if( pUp->IsFtnContFrm() ) +/*?*/ return pUp->Frm().IsInside( rPt ) ? pUp : NULL; +/*N*/ pUp = pUp->GetUpper(); +/*N*/ } +/*?*/ return NULL; +/*N*/ } + +//Fuer MSC keine Optimierung mit e (enable register...) hier, sonst gibts +//einen Bug (ID: 2857) +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("e",off) +/*N*/ #endif + +/*N*/ const SwCntntFrm *SwLayoutFrm::GetCntntPos( Point& rPoint, +/*N*/ const BOOL bDontLeave, +/*N*/ const BOOL bBodyOnly, +/*N*/ const BOOL bCalc, +/*N*/ const SwCrsrMoveState *pCMS, +/*N*/ const BOOL bDefaultExpand ) const +/*N*/ { +/*N*/ //Ersten CntntFrm ermitteln. +/*N*/ const SwLayoutFrm *pStart = (!bDontLeave && bDefaultExpand && GetPrev()) ? +/*N*/ (SwLayoutFrm*)GetPrev() : this; +/*N*/ const SwCntntFrm *pCntnt = pStart->ContainsCntnt(); +/*N*/ +/*N*/ if ( !pCntnt && (GetPrev() && !bDontLeave) ) +/*N*/ pCntnt = ContainsCntnt(); +/*N*/ +/*N*/ if ( bBodyOnly && pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ +/*N*/ const SwCntntFrm *pActual= pCntnt; +/*N*/ const SwLayoutFrm *pInside = NULL; +/*N*/ USHORT nMaxPage = GetPhyPageNum() + (bDefaultExpand ? 1 : 0); +/*N*/ Point aPoint = rPoint; +/*N*/ ULONG nDistance = ULONG_MAX; +/*N*/ +/*N*/ while ( TRUE ) //Sicherheitsschleifchen, damit immer einer gefunden wird. +/*N*/ { +/*N*/ while ( pCntnt && +/*N*/ ((!bDontLeave || IsAnLower( pCntnt )) && +/*N*/ (pCntnt->GetPhyPageNum() <= nMaxPage)) ) +/*N*/ { +/*N*/ if ( ( bCalc || pCntnt->Frm().Width() ) && +/*N*/ ( !bBodyOnly || pCntnt->IsInDocBody() ) ) +/*N*/ { +/*N*/ //Wenn der Cntnt in einem geschuetzen Bereich (Zelle, Ftn, Section) +/*N*/ //liegt, wird der nachste Cntnt der nicht geschuetzt ist gesucht. +/*N*/ const SwCntntFrm *pComp = pCntnt; +/*N*/ pCntnt = ::binfilter::lcl_MissProtectedFrames( pCntnt, lcl_GetNxtCnt, FALSE, +/*N*/ pCMS ? pCMS->bSetInReadOnly : FALSE ); +/*N*/ if ( pComp != pCntnt ) +/*N*/ continue; +/*N*/ +/*N*/ if ( !pCntnt->IsTxtFrm() || !((SwTxtFrm*)pCntnt)->IsHiddenNow() ) +/*N*/ { +/*N*/ if ( bCalc ) +/*N*/ pCntnt->Calc(); +/*N*/ +/*N*/ SwRect aCntFrm( pCntnt->UnionFrm() ); +/*N*/ if ( aCntFrm.IsInside( rPoint ) ) +/*N*/ { +/*N*/ pActual = pCntnt; +/*N*/ aPoint = rPoint; +/*N*/ break; +/*N*/ } +/*N*/ //Die Strecke von rPoint zum dichtesten Punkt von pCntnt wird +/*N*/ //jetzt berechnet. +/*N*/ Point aCntntPoint( rPoint ); +/*N*/ +/*N*/ //Erst die Vertikale Position einstellen +/*N*/ if ( aCntFrm.Top() > aCntntPoint.Y() ) +/*N*/ aCntntPoint.Y() = aCntFrm.Top(); +/*N*/ else if ( aCntFrm.Bottom() < aCntntPoint.Y() ) +/*N*/ aCntntPoint.Y() = aCntFrm.Bottom(); +/*N*/ +/*N*/ //Jetzt die Horizontale Position +/*N*/ if ( aCntFrm.Left() > aCntntPoint.X() ) +/*N*/ aCntntPoint.X() = aCntFrm.Left(); +/*N*/ else if ( aCntFrm.Right() < aCntntPoint.X() ) +/*N*/ aCntntPoint.X() = aCntFrm.Right(); +/*N*/ +/*N*/ // pInside ist ein Seitenbereich, in dem der Punkt liegt, +/*N*/ // sobald pInside!=0 ist, werden nur noch Frames akzeptiert, +/*N*/ // die innerhalb liegen. +/*N*/ if( !pInside || ( pInside->IsAnLower( pCntnt ) && +/*N*/ ( !pCntnt->IsInFtn() || pInside->IsFtnContFrm() ) ) ) +/*N*/ { +/*N*/ const ULONG nDiff = ::binfilter::CalcDiff( aCntntPoint, rPoint ); +/*N*/ BOOL bBetter = nDiff < nDistance; // Dichter dran +/*N*/ if( !pInside ) +/*N*/ { +/*N*/ pInside = lcl_Inside( pCntnt, rPoint ); +/*N*/ if( pInside ) // Im "richtigen" Seitenteil +/*N*/ bBetter = TRUE; +/*N*/ } +/*N*/ if( bBetter ) +/*N*/ { +/*N*/ aPoint = aCntntPoint; +/*N*/ nDistance = nDiff; +/*N*/ pActual = pCntnt; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ if ( bBodyOnly ) +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ if ( !pActual ) +/*N*/ { //Wenn noch keiner gefunden wurde muss der Suchbereich erweitert +/*N*/ //werden, irgenwann muessen wir einen Finden! +/*N*/ //MA 09. Jan. 97: Opt fuer viele leere Seiten, wenn wir nur im +/*N*/ //Body suchen, koennen wir den Suchbereich gleich in einem +/*N*/ //Schritt hinreichend erweitern. +/*N*/ if ( bBodyOnly ) +/*N*/ { +/*N*/ while ( !pCntnt && pStart->GetPrev() ) +/*N*/ { +/*N*/ ++nMaxPage; +/*N*/ if( !pStart->GetPrev()->IsLayoutFrm() ) +/*N*/ return 0; +/*N*/ pStart = (SwLayoutFrm*)pStart->GetPrev(); +/*N*/ pCntnt = pStart->IsInDocBody() +/*N*/ ? pStart->ContainsCntnt() +/*N*/ : pStart->FindPageFrm()->FindFirstBodyCntnt(); +/*N*/ } +/*N*/ if ( !pCntnt ) //irgendwann muessen wir mit irgendeinem Anfangen! +/*N*/ { +/*N*/ pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt(); +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ if ( !pCntnt ) +/*N*/ return 0; //Es gibt noch keine Dokumentinhalt! +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ++nMaxPage; +/*N*/ if ( pStart->GetPrev() ) +/*N*/ { +/*N*/ if( !pStart->GetPrev()->IsLayoutFrm() ) +/*N*/ return 0; +/*N*/ pStart = (SwLayoutFrm*)pStart->GetPrev(); +/*N*/ pCntnt = pStart->ContainsCntnt(); +/*N*/ } +/*N*/ else //irgendwann muessen wir mit irgendeinem Anfangen! +/*N*/ pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt(); +/*N*/ } +/*N*/ pActual = pCntnt; +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ ASSERT( pActual, "Keinen Cntnt gefunden." ); +/*N*/ if ( bBodyOnly ) +/*N*/ ASSERT( pActual->IsInDocBody(), "Cnt nicht im Body." ); +/*N*/ #endif +/*N*/ +/*N*/ //Spezialfall fuer das selektieren von Tabellen, nicht in wiederholte +/*N*/ //TblHedlines. +/*N*/ if ( pActual->IsInTab() && pCMS && pCMS->eState == MV_TBLSEL ) +/*N*/ { +/*N*/ const SwTabFrm *pTab = pActual->FindTabFrm(); +/*N*/ if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() && +/*N*/ ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pActual ) ) +/*N*/ { +/*N*/ ((SwCrsrMoveState*)pCMS)->bStop = TRUE; +/*N*/ return 0; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Jetzt noch eine kleine Korrektur beim ersten/letzten +/*N*/ Size aActualSize( pActual->Prt().SSize() ); +/*N*/ if ( aActualSize.Height() > pActual->GetUpper()->Prt().Height() ) +/*N*/ aActualSize.Height() = pActual->GetUpper()->Prt().Height(); +/*N*/ +/*N*/ SWRECTFN( pActual ) +/*N*/ if ( !pActual->GetPrev() && +/*N*/ (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtTop)(), +/*N*/ bVert ? rPoint.X() : rPoint.Y() ) > 0 ) +/*N*/ { +/*N*/ aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Top(); +/*N*/ aPoint.X() = pActual->Frm().Left() + +/*N*/ ( pActual->IsRightToLeft() || bVert ? +/*N*/ pActual->Prt().Right() : +/*N*/ pActual->Prt().Left() ); +/*N*/ } +/*N*/ else if ( !pActual->GetNext() && +/*N*/ (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtBottom)(), +/*N*/ bVert ? rPoint.X() : rPoint.Y() ) < 0 ) +/*N*/ { +/*N*/ aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Bottom(); +/*N*/ aPoint.X() = pActual->Frm().Left() + +/*N*/ ( pActual->IsRightToLeft() || bVert ? +/*N*/ pActual->Prt().Left() : +/*N*/ pActual->Prt().Right() ); +/*N*/ } +/*N*/ +/*N*/ //Und den Point in die PrtArea bringen +/*N*/ if ( bCalc ) +/*N*/ pActual->Calc(); +/*N*/ const SwRect aRect( pActual->Frm().Pos() + pActual->Prt().Pos(), +/*N*/ aActualSize ); +/*N*/ if ( aPoint.Y() < aRect.Top() ) +/*N*/ aPoint.Y() = aRect.Top(); +/*N*/ else if ( aPoint.Y() > aRect.Bottom() ) +/*N*/ aPoint.Y() = aRect.Bottom(); +/*N*/ if ( aPoint.X() < aRect.Left() ) +/*N*/ aPoint.X() = aRect.Left(); +/*N*/ else if ( aPoint.X() > aRect.Right() ) +/*N*/ aPoint.X() = aRect.Right(); +/*N*/ rPoint = aPoint; +/*N*/ return pActual; +/*N*/ } + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("",on) +/*N*/ #endif + +/************************************************************************* +|* +|* SwPageFrm::GetCntntPosition() +|* +|* Beschreibung Analog zu SwLayoutFrm::GetCntntPos(). +|* Spezialisiert fuer Felder in Rahmen. +|* +|* Ersterstellung MA 22. Mar. 95 +|* Letzte Aenderung MA 07. Nov. 95 +|* +|*************************************************************************/ +/*N*/ void SwPageFrm::GetCntntPosition( const Point &rPt, SwPosition &rPos ) const +/*N*/ { +/*N*/ //Ersten CntntFrm ermitteln. +/*N*/ const SwCntntFrm *pCntnt = ContainsCntnt(); +/*N*/ if ( pCntnt ) +/*N*/ { +/*N*/ //Einen weiter zurueck schauen (falls moeglich). +/*N*/ const SwCntntFrm *pTmp = pCntnt->GetPrevCntntFrm(); +/*N*/ while ( pTmp && !pTmp->IsInDocBody() ) +/*?*/ pTmp = pTmp->GetPrevCntntFrm(); +/*N*/ if ( pTmp ) +/*?*/ pCntnt = pTmp; +/*N*/ } +/*N*/ else +/*?*/ pCntnt = GetUpper()->ContainsCntnt(); +/*N*/ +/*N*/ const SwCntntFrm *pAct = pCntnt; +/*N*/ Point aAct = rPt; +/*N*/ ULONG nDist = ULONG_MAX; +/*N*/ +/*N*/ while ( pCntnt ) +/*N*/ { +/*N*/ SwRect aCntFrm( pCntnt->UnionFrm() ); +/*N*/ if ( aCntFrm.IsInside( rPt ) ) +/*N*/ { +/*N*/ //dichter gehts nimmer. +/*?*/ pAct = pCntnt; +/*?*/ break; +/*N*/ } +/*N*/ +/*N*/ //Die Strecke von rPt zum dichtesten Punkt von pCntnt berechnen. +/*N*/ Point aPoint( rPt ); +/*N*/ +/*N*/ //Erst die vertikale Position einstellen +/*N*/ if ( aCntFrm.Top() > rPt.Y() ) +/*N*/ aPoint.Y() = aCntFrm.Top(); +/*N*/ else if ( aCntFrm.Bottom() < rPt.Y() ) +/*N*/ aPoint.Y() = aCntFrm.Bottom(); +/*N*/ +/*N*/ //Jetzt die horizontale Position +/*N*/ if ( aCntFrm.Left() > rPt.X() ) +/*N*/ aPoint.X() = aCntFrm.Left(); +/*N*/ else if ( aCntFrm.Right() < rPt.X() ) +/*N*/ aPoint.X() = aCntFrm.Right(); +/*N*/ +/*N*/ const ULONG nDiff = ::binfilter::CalcDiff( aPoint, rPt ); +/*N*/ if ( nDiff < nDist ) +/*N*/ { +/*N*/ aAct = aPoint; +/*N*/ nDist = nDiff; +/*N*/ pAct = pCntnt; +/*N*/ } +/*N*/ else if ( aCntFrm.Top() > Frm().Bottom() ) +/*N*/ //Dichter wirds im Sinne der Felder nicht mehr! +/*N*/ break; +/*N*/ +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ +/*N*/ //Und den Point in die PrtArea bringen +/*N*/ const SwRect aRect( pAct->Frm().Pos() + pAct->Prt().Pos(), pAct->Prt().SSize() ); +/*N*/ if ( aAct.Y() < aRect.Top() ) +/*N*/ aAct.Y() = aRect.Top(); +/*N*/ else if ( aAct.Y() > aRect.Bottom() ) +/*N*/ aAct.Y() = aRect.Bottom(); +/*N*/ if ( aAct.X() < aRect.Left() ) +/*?*/ aAct.X() = aRect.Left(); +/*N*/ else if ( aAct.X() > aRect.Right() ) +/*N*/ aAct.X() = aRect.Right(); +/*N*/ +/*N*/ if( !pAct->IsValid() ) +/*N*/ { +/*N*/ // CntntFrm nicht formatiert -> immer auf Node-Anfang +/*?*/ SwCntntNode* pCNd = (SwCntntNode*)pAct->GetNode(); +/*?*/ ASSERT( pCNd, "Wo ist mein CntntNode?" ); +/*?*/ rPos.nNode = *pCNd; +/*?*/ rPos.nContent.Assign( pCNd, 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwCrsrMoveState aTmpState( MV_SETONLYTEXT ); +/*N*/ pAct->GetCrsrOfst( &rPos, aAct, &aTmpState ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::GetNextPrevCntntPos() +|* +|* Beschreibung Es wird der naechstliegende Cntnt zum uebergebenen +|* Point gesucht. Es wird nur im BodyText gesucht. +|* Ersterstellung MA 15. Jul. 92 +|* Letzte Aenderung JP 11.10.2001 +|* +|*************************************************************************/ + +//!!!!! Es wird nur der vertikal naechstliegende gesucht. +//JP 11.10.2001: only in tables we try to find the right column - Bug 72294 + +/************************************************************************* +|* +|* SwRootFrm::GetPagePos() +|* +|* Beschreibung: Liefert die absolute Dokumentpositon der gewuenschten +|* Seite. +|* Formatiert wird nur soweit notwendig und nur dann wenn bFormat=TRUE +|* Liefert Null, wenn die Operation nicht moeglich ist. +|* Die Pos ist die der letzten Seite, wenn die Seitenzahl zu gross +|* gewaehlt wurde. +|* Ersterstellung MA 01. Jun. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ + +/** get page frame by phyiscal page number + + OD 14.01.2003 #103492# + + @return pointer to the page frame with the given physical page number +*/ + +/************************************************************************* +|* +|* SwRootFrm::IsDummyPage(USHORT) +|* +|* Description: Returns TRUE, when the given physical pagenumber does't exist +|* or this page is an empty page. +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwFrm::IsProtected() +|* +|* Beschreibung Ist der Frm bzw. die Section in der er steht +|* geschuetzt? +|* Auch Fly in Fly in ... und Fussnoten +|* +|* Ersterstellung MA 28. Jul. 93 +|* Letzte Aenderung MA 06. Nov. 97 +|* +|*************************************************************************/ +/*N*/ BOOL SwFrm::IsProtected() const +/*N*/ { +/*N*/ //Der Frm kann in Rahmen, Zellen oder Bereichen geschuetzt sein. +/*N*/ //Geht auch FlyFrms rekursiv hoch. Geht auch von Fussnoten zum Anker. +/*N*/ const SwFrm *pFrm = this; +/*N*/ do +/*N*/ { +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ { +/*N*/ if ( ((SwCntntFrm*)pFrm)->GetNode() && +/*N*/ ((SwCntntFrm*)pFrm)->GetNode()->IsInProtectSect() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( ((SwLayoutFrm*)pFrm)->GetFmt() && +/*N*/ ((SwLayoutFrm*)pFrm)->GetFmt()-> +/*N*/ GetProtect().IsCntntProtected() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ if ( pFrm->IsFlyFrm() ) +/*N*/ { +/*N*/ //Der Schutz des Inhaltes kann bei Verkettung vom Master der Kette +/*N*/ //vorgegeben werden. +/*N*/ if ( ((SwFlyFrm*)pFrm)->GetPrevLink() ) +/*N*/ { +/*N*/ SwFlyFrm *pMaster = (SwFlyFrm*)pFrm; +/*N*/ do +/*N*/ { pMaster = pMaster->GetPrevLink(); +/*N*/ } while ( pMaster->GetPrevLink() ); +/*N*/ if ( pMaster->IsProtected() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ pFrm = ((SwFlyFrm*)pFrm)->GetAnchor(); +/*N*/ } +/*N*/ else if ( pFrm->IsFtnFrm() ) +/*N*/ pFrm = ((SwFtnFrm*)pFrm)->GetRef(); +/*N*/ else +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ +/*N*/ } while ( pFrm ); +/*N*/ +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetPhyPageNum() +|* Beschreibung: Liefert die physikalische Seitennummer +|* +|* Ersterstellung OK 06.07.93 08:35 +|* Letzte Aenderung MA 30. Nov. 94 +|* +|*************************************************************************/ +/*N*/ USHORT SwFrm::GetPhyPageNum() const +/*N*/ { +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ return pPage ? pPage->GetPhyPageNum() : 0; +/*N*/ } + +/*-----------------26.02.01 11:25------------------- + * SwFrm::WannaRightPage() + * decides if the page want to be a rightpage or not. + * If the first content of the page has a page descriptor, + * we take the follow of the page descriptor of the last not empty page. + * If this descriptor allows only right(left) pages and the page + * isn't an empty page then it wanna be such right(left) page. + * If the descriptor allows right and left pages, we look for a number offset + * in the first content. If there is one, odd number results right pages, + * even number results left pages. + * If there is no number offset, we take the physical page number instead, + * but a previous empty page don't count. + * --------------------------------------------------*/ + +/*N*/ BOOL SwFrm::WannaRightPage() const +/*N*/ { +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( !pPage || !pPage->GetUpper() ) +/*?*/ return TRUE; +/*N*/ +/*N*/ const SwFrm *pFlow = pPage->FindFirstBodyCntnt(); +/*N*/ SwPageDesc *pDesc = 0; +/*N*/ USHORT nPgNum = 0; +/*N*/ if ( pFlow ) +/*N*/ { +/*N*/ if ( pFlow->IsInTab() ) +/*N*/ pFlow = pFlow->FindTabFrm(); +/*N*/ const SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow ); +/*N*/ if ( !pTmp->IsFollow() ) +/*N*/ { +/*N*/ const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc(); +/*N*/ pDesc = (SwPageDesc*)rPgDesc.GetPageDesc(); +/*N*/ nPgNum = rPgDesc.GetNumOffset(); +/*N*/ } +/*N*/ } +/*N*/ if ( !pDesc ) +/*N*/ { +/*N*/ SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev(); +/*N*/ if( pPrv && pPrv->IsEmptyPage() ) +/*N*/ pPrv = (SwPageFrm*)pPrv->GetPrev(); +/*N*/ if( pPrv ) +/*N*/ pDesc = pPrv->GetPageDesc()->GetFollow(); +/*N*/ else +/*N*/ { +/*N*/ const SwDoc* pDoc = pPage->GetFmt()->GetDoc(); +/*N*/ pDesc = (SwPageDesc*)&pDoc->GetPageDesc( 0 ); +/*N*/ } +/*N*/ } +/*N*/ ASSERT( pDesc, "No pagedescriptor" ); +/*N*/ BOOL bOdd; +/*N*/ if( nPgNum ) +/*N*/ bOdd = nPgNum % 2 ? TRUE : FALSE; +/*N*/ else +/*N*/ { +/*N*/ bOdd = pPage->OnRightPage(); +/*N*/ if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() ) +/*N*/ bOdd = !bOdd; +/*N*/ } +/*N*/ if( !pPage->IsEmptyPage() ) +/*N*/ { +/*N*/ if( !pDesc->GetRightFmt() ) +/*N*/ bOdd = FALSE; +/*N*/ else if( !pDesc->GetLeftFmt() ) +/*N*/ bOdd = TRUE; +/*N*/ } +/*N*/ return bOdd; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetVirtPageNum() +|* Beschreibung: Liefert die virtuelle Seitennummer mit Offset +|* +|* Ersterstellung OK 06.07.93 08:35 +|* Letzte Aenderung MA 30. Nov. 94 +|* +|*************************************************************************/ +/*N*/ USHORT SwFrm::GetVirtPageNum() const +/*N*/ { +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( !pPage || !pPage->GetUpper() ) +/*?*/ return 0; +/*N*/ +/*N*/ USHORT nPhyPage = pPage->GetPhyPageNum(); +/*N*/ if ( !((SwRootFrm*)pPage->GetUpper())->IsVirtPageNum() ) +/*N*/ return nPhyPage; +/*N*/ +/*N*/ //Den am naechsten stehenden Absatz mit virtueller Seitennummer suchen. +/*N*/ //Da das rueckwaertsuchen insgesamt sehr viel Zeit verschlingt suchen +/*N*/ //wir jetzt gezielt ueber die Abhaengigkeiten. +/*N*/ //von den PageDescs bekommen wir die Attribute, von den Attributen +/*N*/ //wiederum bekommen wir die Absaetze. +/*N*/ const SwPageFrm *pVirtPage = 0; +/*N*/ const SwFrm *pFrm = 0; +/*N*/ const SfxItemPool &rPool = pPage->GetFmt()->GetDoc()->GetAttrPool(); +/*N*/ const SfxPoolItem* pItem; +/*N*/ USHORT nMaxItems = rPool.GetItemCount( RES_PAGEDESC ); +/*N*/ for( USHORT n = 0; n < nMaxItems; ++n ) +/*N*/ { +/*N*/ if( 0 == (pItem = rPool.GetItem( RES_PAGEDESC, n ) )) +/*N*/ continue; +/*N*/ +/*N*/ const SwFmtPageDesc *pDesc = (SwFmtPageDesc*)pItem; +/*N*/ if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() ) +/*N*/ { +/*N*/ const SwModify *pMod = pDesc->GetDefinedIn(); +/*N*/ SwVirtPageNumInfo aInfo( pPage ); +/*N*/ pMod->GetInfo( aInfo ); +/*N*/ if ( aInfo.GetPage() ) +/*N*/ { +/*N*/ if( !pVirtPage || ( pVirtPage && aInfo.GetPage()-> +/*N*/ GetPhyPageNum() > pVirtPage->GetPhyPageNum() ) ) +/*N*/ { +/*N*/ pVirtPage = aInfo.GetPage(); +/*N*/ pFrm = aInfo.GetFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pFrm ) +/*N*/ return nPhyPage - pFrm->GetPhyPageNum() + +/*N*/ pFrm->GetAttrSet()->GetPageDesc().GetNumOffset(); +/*N*/ return nPhyPage; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::MakeTblCrsrs() +|* +|* Ersterstellung MA 14. May. 93 +|* Letzte Aenderung MA 02. Feb. 94 +|* +|*************************************************************************/ +//Ermitteln und einstellen derjenigen Zellen die von der Selektion +//eingeschlossen sind. + + + +/************************************************************************* +|* +|* SwRootFrm::CalcFrmRects +|* +|* Ersterstellung MA 24. Aug. 92 +|* Letzte Aenderung MA 24. Aug. 93 +|* +|*************************************************************************/ + +/* + * nun koennen folgende Situationen auftreten: + * 1. Start und Ende liegen in einer Bildschirm - Zeile und im + * gleichen Node + * -> aus Start und End ein Rectangle, dann Ok + * 2. Start und Ende liegen in einem Frame (dadurch im gleichen Node!) + * -> Start nach rechts, End nach links erweitern, + * und bei mehr als 2 Bildschirm - Zeilen, das dazwischen + * liegende berechnen + * 3. Start und Ende liegen in verschiedenen Frames + * -> Start nach rechts erweitern, bis Frame-Ende Rect berechnen + * Ende nach links erweitern, bis Frame-Start Rect berechnen + * und bei mehr als 2 Frames von allen dazwischen liegenden + * Frames die PrtArea dazu. + * 4. Wenn es sich um eine Tabellenselektion handelt wird fuer jeden + * PaM im Ring der CellFrm besorgt, dessen PrtArea wird zu den + * Rechtecken addiert. + * + * Grosser Umbau wg. der FlyFrm; denn diese muessen ausgespart werden. + * Ausnahmen: - Der Fly in dem die Selektion stattfindet (wenn sie in einem Fly + * stattfindet). + * - Die Flys, die vom Text unterlaufen werden. + * Arbeitsweise: Zuerst wird eine SwRegion mit der Root initialisiert. + * Aus der Region werden die zu invertierenden Bereiche + * ausgestantzt. Die Region wird Komprimiert und letztlich + * invertiert. Damit liegen dann die zu invertierenden + * Rechtecke vor. + * Am Ende werden die Flys aus der Region ausgestanzt. + */ + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |