| /************************************************************** |
| * |
| * 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 <com/sun/star/embed/EmbedStates.hpp> |
| #include <ndole.hxx> |
| #include <docary.hxx> |
| #include <svl/itemiter.hxx> |
| #include <fmtfsize.hxx> |
| #include <fmthdft.hxx> |
| #include <fmtclds.hxx> |
| #include <fmtanchr.hxx> |
| #include <fmtpdsc.hxx> |
| #include <fmtfordr.hxx> |
| #include <fmtfld.hxx> |
| #include <fmtornt.hxx> |
| #include <fmtsrnd.hxx> |
| #include <ftninfo.hxx> |
| #include <tgrditem.hxx> |
| #include <viewopt.hxx> |
| #include <docsh.hxx> |
| |
| #include "viewimp.hxx" |
| #include "viewopt.hxx" |
| #include "pagefrm.hxx" |
| #include "rootfrm.hxx" |
| #include "cntfrm.hxx" |
| #include "flyfrm.hxx" |
| #include "doc.hxx" |
| #include "fesh.hxx" |
| #include "dview.hxx" |
| #include "dflyobj.hxx" |
| #include "dcontact.hxx" |
| #include "frmtool.hxx" |
| #include "fldbas.hxx" |
| #include "hints.hxx" |
| #include "errhdl.hxx" |
| #include "swtable.hxx" |
| |
| #include "ftnidx.hxx" |
| #include "bodyfrm.hxx" |
| #include "ftnfrm.hxx" |
| #include "tabfrm.hxx" |
| #include "txtfrm.hxx" |
| #include "layact.hxx" |
| #include "flyfrms.hxx" |
| #include "htmltbl.hxx" |
| #include "pagedesc.hxx" |
| #include "poolfmt.hxx" |
| #include <editeng/frmdiritem.hxx> |
| #include <swfntcch.hxx> // SwFontAccess |
| #include <sortedobjs.hxx> |
| #include <switerator.hxx> |
| #include <vcl/svapp.hxx> |
| |
| using namespace ::com::sun::star; |
| |
| |
| /************************************************************************* |
| |* |
| |* SwBodyFrm::SwBodyFrm() |
| |* |
| |* Ersterstellung MA ?? |
| |* Letzte Aenderung MA 01. Aug. 93 |
| |* |
| |*************************************************************************/ |
| SwBodyFrm::SwBodyFrm( SwFrmFmt *pFmt, SwFrm* pSib ): |
| SwLayoutFrm( pFmt, pSib ) |
| { |
| nType = FRMC_BODY; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwBodyFrm::Format() |
| |* |
| |* Ersterstellung MA 30. May. 94 |
| |* Letzte Aenderung MA 20. Jan. 99 |
| |* |
| |*************************************************************************/ |
| void SwBodyFrm::Format( const SwBorderAttrs * ) |
| { |
| //Formatieren des Body ist zu einfach, deshalb bekommt er ein eigenes |
| //Format; Umrandungen und dergl. sind hier nicht zu beruecksichtigen. |
| //Breite ist die der PrtArea des Uppers, Hoehe ist die Hoehe der PrtArea |
| //des Uppers abzueglich der Nachbarn (Wird eigentlich eingestellt aber |
| //Vorsicht ist die Mutter der Robustheit). |
| //Die PrtArea ist stets so gross wie der Frm itself. |
| |
| if ( !bValidSize ) |
| { |
| SwTwips nHeight = GetUpper()->Prt().Height(); |
| SwTwips nWidth = GetUpper()->Prt().Width(); |
| const SwFrm *pFrm = GetUpper()->Lower(); |
| do |
| { |
| if ( pFrm != this ) |
| { |
| if( pFrm->IsVertical() ) |
| nWidth -= pFrm->Frm().Width(); |
| else |
| nHeight -= pFrm->Frm().Height(); |
| } |
| pFrm = pFrm->GetNext(); |
| } while ( pFrm ); |
| if ( nHeight < 0 ) |
| nHeight = 0; |
| Frm().Height( nHeight ); |
| //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin |
| if( IsVertical() && !IsVertLR() && !IsReverse() && nWidth != Frm().Width() ) |
| Frm().Pos().X() += Frm().Width() - nWidth; |
| Frm().Width( nWidth ); |
| } |
| |
| sal_Bool bNoGrid = sal_True; |
| if( GetUpper()->IsPageFrm() && ((SwPageFrm*)GetUpper())->HasGrid() ) |
| { |
| GETGRID( ((SwPageFrm*)GetUpper()) ) |
| if( pGrid ) |
| { |
| bNoGrid = sal_False; |
| long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight(); |
| SWRECTFN( this ) |
| long nSize = (Frm().*fnRect->fnGetWidth)(); |
| long nBorder = 0; |
| if( GRID_LINES_CHARS == pGrid->GetGridType() ) |
| { |
| //for textgrid refactor |
| SwDoc *pDoc = GetFmt()->GetDoc(); |
| nBorder = nSize % (GETGRIDWIDTH(pGrid, pDoc)); |
| nSize -= nBorder; |
| nBorder /= 2; |
| } |
| (Prt().*fnRect->fnSetPosX)( nBorder ); |
| (Prt().*fnRect->fnSetWidth)( nSize ); |
| |
| // Height of body frame: |
| nBorder = (Frm().*fnRect->fnGetHeight)(); |
| |
| // Number of possible lines in area of body frame: |
| long nNumberOfLines = nBorder / nSum; |
| if( nNumberOfLines > pGrid->GetLines() ) |
| nNumberOfLines = pGrid->GetLines(); |
| |
| // Space required for nNumberOfLines lines: |
| nSize = nNumberOfLines * nSum; |
| nBorder -= nSize; |
| nBorder /= 2; |
| |
| // #i21774# Footnotes and centering the grid does not work together: |
| const bool bAdjust = 0 == ((SwPageFrm*)GetUpper())->GetFmt()->GetDoc()-> |
| GetFtnIdxs().Count(); |
| |
| (Prt().*fnRect->fnSetPosY)( bAdjust ? nBorder : 0 ); |
| (Prt().*fnRect->fnSetHeight)( nSize ); |
| } |
| } |
| if( bNoGrid ) |
| { |
| Prt().Pos().X() = Prt().Pos().Y() = 0; |
| Prt().Height( Frm().Height() ); |
| Prt().Width( Frm().Width() ); |
| } |
| bValidSize = bValidPrtArea = sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::SwPageFrm(), ~SwPageFrm() |
| |* |
| |* Ersterstellung MA 20. Oct. 92 |
| |* Letzte Aenderung MA 08. Dec. 97 |
| |* |
| |*************************************************************************/ |
| SwPageFrm::SwPageFrm( SwFrmFmt *pFmt, SwFrm* pSib, SwPageDesc *pPgDsc ) : |
| SwFtnBossFrm( pFmt, pSib ), |
| pSortedObjs( 0 ), |
| pDesc( pPgDsc ), |
| nPhyPageNum( 0 ), |
| // OD 2004-05-17 #i28701# |
| mbLayoutInProgress( false ) |
| { |
| SetDerivedVert( sal_False ); |
| SetDerivedR2L( sal_False ); |
| if( pDesc ) |
| { |
| bHasGrid = sal_True; |
| GETGRID( this ) |
| if( !pGrid ) |
| bHasGrid = sal_False; |
| } |
| else |
| bHasGrid = sal_False; |
| SetMaxFtnHeight( pPgDsc->GetFtnInfo().GetHeight() ? |
| pPgDsc->GetFtnInfo().GetHeight() : LONG_MAX ), |
| nType = FRMC_PAGE; |
| bInvalidLayout = bInvalidCntnt = bInvalidSpelling = bInvalidSmartTags = bInvalidAutoCmplWrds = bInvalidWordCount = sal_True; |
| bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt = bFtnPage = bEndNotePage = sal_False; |
| |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); |
| if ( bBrowseMode ) |
| { |
| Frm().Height( 0 ); |
| long nWidth = pSh->VisArea().Width(); |
| if ( !nWidth ) |
| nWidth = 5000L; //aendert sich sowieso |
| Frm().Width ( nWidth ); |
| } |
| else |
| Frm().SSize( pFmt->GetFrmSize().GetSize() ); |
| |
| //Body-Bereich erzeugen und einsetzen, aber nur wenn ich nicht gerade |
| //eine Leerseite bin. |
| SwDoc *pDoc = pFmt->GetDoc(); |
| if ( sal_False == (bEmptyPage = pFmt == pDoc->GetEmptyPageFmt()) ) |
| { |
| bEmptyPage = sal_False; |
| Calc(); //Damit die PrtArea stimmt. |
| SwBodyFrm *pBodyFrm = new SwBodyFrm( pDoc->GetDfltFrmFmt(), this ); |
| pBodyFrm->ChgSize( Prt().SSize() ); |
| pBodyFrm->Paste( this ); |
| pBodyFrm->Calc(); //Damit die Spalten korrekt |
| //eingesetzt werden koennen. |
| pBodyFrm->InvalidatePos(); |
| |
| if ( bBrowseMode ) |
| _InvalidateSize(); //Alles nur gelogen |
| |
| //Header/Footer einsetzen, nur rufen wenn aktiv. |
| if ( pFmt->GetHeader().IsActive() ) |
| PrepareHeader(); |
| if ( pFmt->GetFooter().IsActive() ) |
| PrepareFooter(); |
| |
| const SwFmtCol &rCol = pFmt->GetCol(); |
| if ( rCol.GetNumCols() > 1 ) |
| { |
| const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass ein |
| //Old-Wert hereingereicht wird. |
| pBodyFrm->ChgColumns( aOld, rCol ); |
| } |
| } |
| } |
| |
| SwPageFrm::~SwPageFrm() |
| { |
| //FlyContainer entleeren, delete der Flys uebernimmt der Anchor |
| //(Basisklasse SwFrm) |
| if ( pSortedObjs ) |
| { |
| //Objekte koennen (warum auch immer) auch an Seiten verankert sein, |
| //die vor Ihren Ankern stehen. Dann wuerde auf bereits freigegebenen |
| //Speicher zugegriffen. |
| for ( sal_uInt16 i = 0; i < pSortedObjs->Count(); ++i ) |
| { |
| SwAnchoredObject* pAnchoredObj = (*pSortedObjs)[i]; |
| pAnchoredObj->SetPageFrm( 0L ); |
| } |
| delete pSortedObjs; |
| pSortedObjs = 0; //Auf 0 setzen, sonst rauchts beim Abmdelden von Flys! |
| } |
| |
| //Damit der Zugriff auf zerstoerte Seiten verhindert werden kann. |
| if ( !IsEmptyPage() ) //#59184# sollte fuer Leerseiten unnoetig sein. |
| { |
| SwDoc *pDoc = GetFmt()->GetDoc(); |
| if( pDoc && !pDoc->IsInDtor() ) |
| { |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if ( pSh ) |
| { |
| SwViewImp *pImp = pSh->Imp(); |
| pImp->SetFirstVisPageInvalid(); |
| if ( pImp->IsAction() ) |
| pImp->GetLayAction().SetAgain(); |
| // OD 12.02.2003 #i9719#, #105645# - retouche area of page |
| // including border and shadow area. |
| const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT); |
| SwRect aRetoucheRect; |
| SwPageFrm::GetBorderAndShadowBoundRect( Frm(), pSh, aRetoucheRect, bRightSidebar ); |
| pSh->AddPaintRect( aRetoucheRect ); |
| } |
| } |
| } |
| } |
| |
| |
| void SwPageFrm::CheckGrid( sal_Bool bInvalidate ) |
| { |
| sal_Bool bOld = bHasGrid; |
| bHasGrid = sal_True; |
| GETGRID( this ) |
| bHasGrid = 0 != pGrid; |
| if( bInvalidate || bOld != bHasGrid ) |
| { |
| SwLayoutFrm* pBody = FindBodyCont(); |
| if( pBody ) |
| { |
| pBody->InvalidatePrt(); |
| SwCntntFrm* pFrm = pBody->ContainsCntnt(); |
| while( pBody->IsAnLower( pFrm ) ) |
| { |
| ((SwTxtFrm*)pFrm)->Prepare( PREP_CLEAR ); |
| pFrm = pFrm->GetNextCntntFrm(); |
| } |
| } |
| SetCompletePaint(); |
| } |
| } |
| |
| |
| void SwPageFrm::CheckDirection( sal_Bool bVert ) |
| { |
| sal_uInt16 nDir = |
| ((SvxFrameDirectionItem&)GetFmt()->GetFmtAttr( RES_FRAMEDIR )).GetValue(); |
| if( bVert ) |
| { |
| 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()->GetCurrShell(); |
| 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_RIGHT == nDir) |
| bVertLR = 0; |
| else if(FRMDIR_VERT_TOP_LEFT==nDir) |
| bVertLR = 1; |
| } |
| } |
| |
| bReverse = 0; |
| bInvalidVert = 0; |
| } |
| else |
| { |
| if( FRMDIR_HORI_RIGHT_TOP == nDir ) |
| bRightToLeft = 1; |
| else |
| bRightToLeft = 0; |
| bInvalidR2L = 0; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::PreparePage() |
| |* |
| |* Beschreibung Erzeugt die Spezifischen Flys zur Seite und formatiert |
| |* generischen Cntnt |
| |* Ersterstellung MA 20. Oct. 92 |
| |* Letzte Aenderung MA 09. Nov. 95 |
| |* |
| |*************************************************************************/ |
| void MA_FASTCALL lcl_FormatLay( SwLayoutFrm *pLay ) |
| { |
| //Alle LayoutFrms - nicht aber Tables, Flys o.ae. - formatieren. |
| |
| SwFrm *pTmp = pLay->Lower(); |
| //Erst die untergeordneten |
| while ( pTmp ) |
| { |
| if ( pTmp->GetType() & 0x00FF ) |
| ::lcl_FormatLay( (SwLayoutFrm*)pTmp ); |
| pTmp = pTmp->GetNext(); |
| } |
| pLay->Calc(); |
| } |
| |
| void MA_FASTCALL lcl_MakeObjs( const SwSpzFrmFmts &rTbl, SwPageFrm *pPage ) |
| { |
| //Anlegen bzw. registrieren von Flys und Drawobjekten. |
| //Die Formate stehen in der SpzTbl (vom Dokument). |
| //Flys werden angelegt, DrawObjekte werden bei der Seite angemeldet. |
| |
| for ( sal_uInt16 i = 0; i < rTbl.Count(); ++i ) |
| { |
| SdrObject *pSdrObj; |
| SwFrmFmt *pFmt = rTbl[i]; |
| const SwFmtAnchor &rAnch = pFmt->GetAnchor(); |
| if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() ) |
| { |
| if( rAnch.GetCntntAnchor() ) |
| { |
| if (FLY_AT_PAGE == rAnch.GetAnchorId()) |
| { |
| SwFmtAnchor aAnch( rAnch ); |
| aAnch.SetAnchor( 0 ); |
| pFmt->SetFmtAttr( aAnch ); |
| } |
| else |
| continue; |
| } |
| |
| //Wird ein Rahmen oder ein SdrObject beschrieben? |
| sal_Bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which(); |
| pSdrObj = 0; |
| if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) ) |
| { |
| ASSERT( sal_False, "DrawObject not found." ); |
| pFmt->GetDoc()->DelFrmFmt( pFmt ); |
| --i; |
| continue; |
| } |
| //Das Objekt kann noch an einer anderen Seite verankert sein. |
| //Z.B. beim Einfuegen einer neuen Seite aufgrund eines |
| //Pagedescriptor-Wechsels. Das Objekt muss dann umgehaengt |
| //werden. |
| //Fuer bestimmte Faelle ist das Objekt bereits an der richtigen |
| //Seite verankert. Das wird hier automatisch erledigt und braucht |
| //- wenngleich performater machbar - nicht extra codiert werden. |
| SwPageFrm *pPg = pPage->IsEmptyPage() ? (SwPageFrm*)pPage->GetNext() : pPage; |
| if ( bSdrObj ) |
| { |
| // OD 23.06.2003 #108784# - consider 'virtual' drawing objects |
| SwDrawContact *pContact = |
| static_cast<SwDrawContact*>(::GetUserCall(pSdrObj)); |
| if ( pSdrObj->ISA(SwDrawVirtObj) ) |
| { |
| SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj); |
| if ( pContact ) |
| { |
| pDrawVirtObj->RemoveFromWriterLayout(); |
| pDrawVirtObj->RemoveFromDrawingPage(); |
| pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) ); |
| } |
| } |
| else |
| { |
| if ( pContact->GetAnchorFrm() ) |
| pContact->DisconnectFromLayout( false ); |
| pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) ); |
| } |
| } |
| else |
| { |
| SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt ); |
| SwFlyFrm *pFly = aIter.First(); |
| if ( pFly) |
| { |
| if( pFly->GetAnchorFrm() ) |
| pFly->AnchorFrm()->RemoveFly( pFly ); |
| } |
| else |
| pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg, pPg ); |
| pPg->AppendFly( pFly ); |
| ::RegistFlys( pPg, pFly ); |
| } |
| } |
| } |
| } |
| |
| void SwPageFrm::PreparePage( sal_Bool bFtn ) |
| { |
| SetFtnPage( bFtn ); |
| |
| // --> OD 2008-01-30 #i82258# |
| // Due to made change on OOo 2.0 code line, method <::lcl_FormatLay(..)> has |
| // the side effect, that the content of page header and footer are formatted. |
| // For this formatting it is needed that the anchored objects are registered |
| // at the <SwPageFrm> instance. |
| // Thus, first calling <::RegistFlys(..)>, then call <::lcl_FormatLay(..)> |
| ::RegistFlys( this, this ); |
| |
| if ( Lower() ) |
| { |
| ::lcl_FormatLay( this ); |
| } |
| // <-- |
| |
| //Flys und DrawObjekte die noch am Dokument bereitstehen. |
| //Fussnotenseiten tragen keine Seitengebundenen Flys! |
| //Es kann Flys und Objekte geben, die auf Leerseiten (Seitennummernmaessig) |
| //stehen wollen, diese werden jedoch von den Leerseiten ignoriert; |
| //sie werden von den Folgeseiten aufgenommen. |
| if ( !bFtn && !IsEmptyPage() ) |
| { |
| SwDoc *pDoc = GetFmt()->GetDoc(); |
| |
| if ( GetPrev() && ((SwPageFrm*)GetPrev())->IsEmptyPage() ) |
| lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), (SwPageFrm*)GetPrev() ); |
| lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), this ); |
| |
| //Kopf-/Fusszeilen) formatieren. |
| SwLayoutFrm *pLow = (SwLayoutFrm*)Lower(); |
| while ( pLow ) |
| { |
| if ( pLow->GetType() & (FRMTYPE_HEADER|FRMTYPE_FOOTER) ) |
| { |
| SwCntntFrm *pCntnt = pLow->ContainsCntnt(); |
| while ( pCntnt && pLow->IsAnLower( pCntnt ) ) |
| { |
| pCntnt->OptCalc(); //Nicht die Vorgaenger |
| pCntnt = pCntnt->GetNextCntntFrm(); |
| } |
| } |
| pLow = (SwLayoutFrm*)pLow->GetNext(); |
| } |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::Modify() |
| |* |
| |* Ersterstellung MA 20. Oct. 92 |
| |* Letzte Aenderung MA 03. Mar. 96 |
| |* |
| |*************************************************************************/ |
| void SwPageFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew ) |
| { |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if ( pSh ) |
| pSh->SetFirstVisPageInvalid(); |
| 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 ) |
| { |
| InvalidatePage( this ); |
| if ( nInvFlags & 0x01 ) |
| _InvalidatePrt(); |
| if ( nInvFlags & 0x02 ) |
| SetCompletePaint(); |
| if ( nInvFlags & 0x04 && GetNext() ) |
| GetNext()->InvalidatePos(); |
| if ( nInvFlags & 0x08 ) |
| PrepareHeader(); |
| if ( nInvFlags & 0x10 ) |
| PrepareFooter(); |
| if ( nInvFlags & 0x20 ) |
| CheckGrid( nInvFlags & 0x40 ); |
| } |
| } |
| |
| void SwPageFrm::_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; |
| switch( nWhich ) |
| { |
| case RES_FMT_CHG: |
| { |
| //Wenn sich das FrmFmt aendert kann hier einiges passieren. |
| //Abgesehen von den Grossenverhaeltnissen sind noch andere |
| //Dinge betroffen. |
| //1. Spaltigkeit. |
| ASSERT( pOld && pNew, "FMT_CHG Missing Format." ); |
| const SwFmt* pOldFmt = ((SwFmtChg*)pOld)->pChangedFmt; |
| const SwFmt* pNewFmt = ((SwFmtChg*)pNew)->pChangedFmt; |
| ASSERT( pOldFmt && pNewFmt, "FMT_CHG Missing Format." ); |
| |
| const SwFmtCol &rOldCol = pOldFmt->GetCol(); |
| const SwFmtCol &rNewCol = pNewFmt->GetCol(); |
| if( rOldCol != rNewCol ) |
| { |
| SwLayoutFrm *pB = FindBodyCont(); |
| ASSERT( pB, "Seite ohne Body." ); |
| pB->ChgColumns( rOldCol, rNewCol ); |
| rInvFlags |= 0x20; |
| } |
| |
| //2. Kopf- und Fusszeilen. |
| const SwFmtHeader &rOldH = pOldFmt->GetHeader(); |
| const SwFmtHeader &rNewH = pNewFmt->GetHeader(); |
| if( rOldH != rNewH ) |
| rInvFlags |= 0x08; |
| |
| const SwFmtFooter &rOldF = pOldFmt->GetFooter(); |
| const SwFmtFooter &rNewF = pNewFmt->GetFooter(); |
| if( rOldF != rNewF ) |
| rInvFlags |= 0x10; |
| CheckDirChange(); |
| } |
| /* kein break hier */ |
| case RES_FRM_SIZE: |
| { |
| const SwRect aOldPageFrmRect( Frm() ); |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if( pSh && pSh->GetViewOptions()->getBrowseMode() ) |
| { |
| bValidSize = sal_False; |
| // OD 28.10.2002 #97265# - Don't call <SwPageFrm::MakeAll()> |
| // Calculation of the page is not necessary, because its size is |
| // is invalidated here and further invalidation is done in the |
| // calling method <SwPageFrm::Modify(..)> and probably by calling |
| // <SwLayoutFrm::Modify(..)> at the end. |
| // It can also causes inconsistences, because the lowers are |
| // adjusted, but not calculated, and a <SwPageFrm::MakeAll()> of |
| // a next page is called. This is performed on the switch to the |
| // online layout. |
| //MakeAll(); |
| } |
| else |
| { |
| const SwFmtFrmSize &rSz = nWhich == RES_FMT_CHG ? |
| ((SwFmtChg*)pNew)->pChangedFmt->GetFrmSize() : |
| (const SwFmtFrmSize&)*pNew; |
| |
| Frm().Height( Max( rSz.GetHeight(), long(MINLAY) ) ); |
| Frm().Width ( Max( rSz.GetWidth(), long(MINLAY) ) ); |
| |
| // PAGES01 |
| if ( GetUpper() ) |
| static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 ); |
| } |
| //Window aufraeumen. |
| if( pSh && pSh->GetWin() && aOldPageFrmRect.HasArea() ) |
| { |
| // OD 12.02.2003 #i9719#, #105645# - consider border and shadow of |
| // page frame for determine 'old' rectangle - it's used for invalidating. |
| const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT); |
| SwRect aOldRectWithBorderAndShadow; |
| SwPageFrm::GetBorderAndShadowBoundRect( aOldPageFrmRect, pSh, aOldRectWithBorderAndShadow, bRightSidebar ); |
| pSh->InvalidateWindows( aOldRectWithBorderAndShadow ); |
| } |
| rInvFlags |= 0x03; |
| if ( aOldPageFrmRect.Height() != Frm().Height() ) |
| rInvFlags |= 0x04; |
| } |
| break; |
| |
| case RES_COL: |
| { |
| SwLayoutFrm *pB = FindBodyCont(); |
| ASSERT( pB, "Seite ohne Body." ); |
| pB->ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew ); |
| rInvFlags |= 0x22; |
| } |
| break; |
| |
| case RES_HEADER: |
| rInvFlags |= 0x08; |
| break; |
| |
| case RES_FOOTER: |
| rInvFlags |= 0x10; |
| break; |
| case RES_TEXTGRID: |
| rInvFlags |= 0x60; |
| break; |
| |
| case RES_PAGEDESC_FTNINFO: |
| //Die derzeit einzig sichere Methode: |
| ((SwRootFrm*)GetUpper())->SetSuperfluous(); |
| SetMaxFtnHeight( pDesc->GetFtnInfo().GetHeight() ); |
| if ( !GetMaxFtnHeight() ) |
| SetMaxFtnHeight( LONG_MAX ); |
| SetColMaxFtnHeight(); |
| //Hier wird die Seite ggf. zerstoert! |
| ((SwRootFrm*)GetUpper())->RemoveFtns( 0, sal_False, sal_True ); |
| break; |
| case RES_FRAMEDIR : |
| CheckDirChange(); |
| break; |
| |
| default: |
| bClear = sal_False; |
| } |
| if ( bClear ) |
| { |
| if ( pOldSet || pNewSet ) |
| { |
| if ( pOldSet ) |
| pOldSet->ClearItem( nWhich ); |
| if ( pNewSet ) |
| pNewSet->ClearItem( nWhich ); |
| } |
| else |
| SwLayoutFrm::Modify( pOld, pNew ); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::GetInfo() |
| |* |
| |* Beschreibung erfragt Informationen |
| |* Ersterstellung JP 31.03.94 |
| |* Letzte Aenderung JP 31.03.94 |
| |* |
| *************************************************************************/ |
| // erfrage vom Modify Informationen |
| sal_Bool SwPageFrm::GetInfo( SfxPoolItem & rInfo ) const |
| { |
| if( RES_AUTOFMT_DOCNODE == rInfo.Which() ) |
| { |
| // es gibt einen PageFrm also wird er benutzt |
| return sal_False; |
| } |
| return sal_True; // weiter suchen |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::SetPageDesc() |
| |* |
| |* Ersterstellung MA 02. Nov. 94 |
| |* Letzte Aenderung MA 02. Nov. 94 |
| |* |
| |*************************************************************************/ |
| void SwPageFrm::SetPageDesc( SwPageDesc *pNew, SwFrmFmt *pFmt ) |
| { |
| pDesc = pNew; |
| if ( pFmt ) |
| SetFrmFmt( pFmt ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::FindPageDesc() |
| |* |
| |* Beschreibung Der richtige PageDesc wird bestimmt: |
| |* 0. Vom Dokument bei Fussnotenseiten und Endnotenseiten |
| |* 1. vom ersten BodyCntnt unterhalb der Seite. |
| |* 2. vom PageDesc der vorstehenden Seite. |
| |* 3. bei Leerseiten vom PageDesc der vorigen Seite. |
| |* 3.1 vom PageDesc der folgenden Seite wenn es keinen Vorgaenger gibt. |
| |* 4. es ist der Default-PageDesc sonst. |
| |* 5. Im BrowseMode ist der Pagedesc immer der vom ersten Absatz im |
| |* Dokument oder Standard (der 0-te) wenn der erste Absatz keinen |
| |* wuenscht. |
| |* (6. Im HTML-Mode ist der Pagedesc immer die HTML-Seitenvorlage.) |
| |* Ersterstellung MA 15. Feb. 93 |
| |* Letzte Aenderung MA 17. Jun. 99 |
| |* |
| |*************************************************************************/ |
| SwPageDesc *SwPageFrm::FindPageDesc() |
| { |
| //0. |
| if ( IsFtnPage() ) |
| { |
| SwDoc *pDoc = GetFmt()->GetDoc(); |
| if ( IsEndNotePage() ) |
| return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc ); |
| else |
| return pDoc->GetFtnInfo().GetPageDesc( *pDoc ); |
| } |
| |
| //6. |
| //if ( GetFmt()->GetDoc()->IsHTMLMode() ) |
| // return GetFmt()->GetDoc()->GetPageDescFromPool( RES_POOLPAGE_HTML ); |
| |
| SwPageDesc *pRet = 0; |
| |
| //5. |
| const ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if( pSh && pSh->GetViewOptions()->getBrowseMode() ) |
| { |
| SwCntntFrm *pFrm = GetUpper()->ContainsCntnt(); |
| while ( !pFrm->IsInDocBody() ) |
| pFrm = pFrm->GetNextCntntFrm(); |
| SwFrm *pFlow = pFrm; |
| if ( pFlow->IsInTab() ) |
| pFlow = pFlow->FindTabFrm(); |
| pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc(); |
| if ( !pRet ) |
| pRet = &GetFmt()->GetDoc()->_GetPageDesc( 0 ); |
| return pRet; |
| } |
| |
| SwFrm *pFlow = FindFirstBodyCntnt(); |
| if ( pFlow && pFlow->IsInTab() ) |
| pFlow = pFlow->FindTabFrm(); |
| |
| //1. |
| if ( pFlow ) |
| { |
| SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow ); |
| if ( !pTmp->IsFollow() ) |
| pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc(); |
| } |
| |
| //3. und 3.1 |
| if ( !pRet && IsEmptyPage() ) |
| // FME 2008-03-03 #i81544# lijian/fme: an empty page should have |
| // the same page description as its prev, just like after construction |
| // of the empty page. |
| pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc() : |
| GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0; |
| |
| //2. |
| if ( !pRet ) |
| pRet = GetPrev() ? |
| ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0; |
| |
| //4. |
| if ( !pRet ) |
| pRet = (SwPageDesc*)&(const_cast<const SwDoc *>(GetFmt()->GetDoc()) |
| ->GetPageDesc( 0 )); |
| |
| |
| ASSERT( pRet, "Kein Descriptor gefunden." ); |
| return pRet; |
| } |
| |
| //Wenn der RootFrm seine Groesse aendert muss benachrichtigt werden. |
| void AdjustSizeChgNotify( SwRootFrm *pRoot ) |
| { |
| const sal_Bool bOld = pRoot->IsSuperfluous(); |
| pRoot->bCheckSuperfluous = sal_False; |
| ViewShell *pSh = pRoot->GetCurrShell(); |
| if ( pSh ) |
| { |
| do |
| { |
| if( pRoot == pSh->GetLayout() ) |
| { |
| pSh->SizeChgNotify(); |
| pSh->Imp()->NotifySizeChg( pRoot->Frm().SSize() ); |
| } |
| pSh = (ViewShell*)pSh->GetNext(); |
| } while ( pSh != pRoot->GetCurrShell() ); |
| } |
| pRoot->bCheckSuperfluous = bOld; |
| } |
| |
| |
| inline void SetLastPage( SwPageFrm *pPage ) |
| { |
| ((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::Cut() |
| |* |
| |* Ersterstellung MA 23. Feb. 94 |
| |* Letzte Aenderung MA 22. Jun. 95 |
| |* |
| |*************************************************************************/ |
| void SwPageFrm::Cut() |
| { |
| // PAGES01 |
| //AdjustRootSize( CHG_CUTPAGE, 0 ); |
| |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if ( !IsEmptyPage() ) |
| { |
| if ( GetNext() ) |
| GetNext()->InvalidatePos(); |
| |
| //Flys deren Anker auf anderen Seiten stehen umhaengen. |
| //DrawObjecte spielen hier keine Rolle. |
| if ( GetSortedObjs() ) |
| { |
| for ( int i = 0; GetSortedObjs() && |
| (sal_uInt16)i < GetSortedObjs()->Count(); ++i ) |
| { |
| // --> OD 2004-06-29 #i28701# |
| SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i]; |
| |
| if ( pAnchoredObj->ISA(SwFlyAtCntFrm) ) |
| { |
| SwFlyFrm* pFly = static_cast<SwFlyAtCntFrm*>(pAnchoredObj); |
| SwPageFrm *pAnchPage = pFly->GetAnchorFrm() ? |
| pFly->AnchorFrm()->FindPageFrm() : 0; |
| if ( pAnchPage && (pAnchPage != this) ) |
| { |
| MoveFly( pFly, pAnchPage ); |
| --i; |
| pFly->InvalidateSize(); |
| pFly->_InvalidatePos(); |
| } |
| } |
| // <-- |
| } |
| } |
| //Window aufraeumen |
| if ( pSh && pSh->GetWin() ) |
| pSh->InvalidateWindows( Frm() ); |
| } |
| |
| // die Seitennummer der Root runterzaehlen. |
| ((SwRootFrm*)GetUpper())->DecrPhyPageNums(); |
| SwPageFrm *pPg = (SwPageFrm*)GetNext(); |
| if ( pPg ) |
| { |
| while ( pPg ) |
| { |
| pPg->DecrPhyPageNum(); //inline --nPhyPageNum |
| pPg = (SwPageFrm*)pPg->GetNext(); |
| } |
| } |
| else |
| ::SetLastPage( (SwPageFrm*)GetPrev() ); |
| |
| SwFrm* pRootFrm = GetUpper(); |
| |
| // Alle Verbindungen kappen. |
| Remove(); |
| |
| // PAGES01 |
| if ( pRootFrm ) |
| static_cast<SwRootFrm*>(pRootFrm)->CheckViewLayout( 0, 0 ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::Paste() |
| |* |
| |* Ersterstellung MA 23. Feb. 94 |
| |* Letzte Aenderung MA 07. Dec. 94 |
| |* |
| |*************************************************************************/ |
| void SwPageFrm::Paste( SwFrm* pParent, SwFrm* pSibling ) |
| { |
| ASSERT( pParent->IsRootFrm(), "Parent ist keine Root." ); |
| ASSERT( pParent, "Kein Parent fuer Paste." ); |
| ASSERT( pParent != this, "Bin selbst der Parent." ); |
| ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); |
| ASSERT( !GetPrev() && !GetNext() && !GetUpper(), |
| "Bin noch irgendwo angemeldet." ); |
| |
| //In den Baum einhaengen. |
| InsertBefore( (SwLayoutFrm*)pParent, pSibling ); |
| |
| // die Seitennummer am Root hochzaehlen. |
| ((SwRootFrm*)GetUpper())->IncrPhyPageNums(); |
| if( GetPrev() ) |
| SetPhyPageNum( ((SwPageFrm*)GetPrev())->GetPhyPageNum() + 1 ); |
| else |
| SetPhyPageNum( 1 ); |
| SwPageFrm *pPg = (SwPageFrm*)GetNext(); |
| if ( pPg ) |
| { |
| while ( pPg ) |
| { |
| pPg->IncrPhyPageNum(); //inline ++nPhyPageNum |
| pPg->_InvalidatePos(); |
| pPg->InvalidateLayout(); |
| pPg = (SwPageFrm*)pPg->GetNext(); |
| } |
| } |
| else |
| ::SetLastPage( this ); |
| |
| if( Frm().Width() != pParent->Prt().Width() ) |
| _InvalidateSize(); |
| |
| InvalidatePos(); |
| |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if ( pSh ) |
| pSh->SetFirstVisPageInvalid(); |
| // PAGES01 |
| getRootFrm()->CheckViewLayout( 0, 0 ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::PrepareRegisterChg() |
| |* |
| |* Ersterstellung AMA 22. Jul. 96 |
| |* Letzte Aenderung AMA 22. Jul. 96 |
| |* |
| |*************************************************************************/ |
| void lcl_PrepFlyInCntRegister( SwCntntFrm *pFrm ) |
| { |
| pFrm->Prepare( PREP_REGISTER ); |
| if( pFrm->GetDrawObjs() ) |
| { |
| for( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) |
| { |
| // --> OD 2004-06-29 #i28701# |
| SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i]; |
| if ( pAnchoredObj->ISA(SwFlyInCntFrm) ) |
| { |
| SwFlyFrm* pFly = static_cast<SwFlyInCntFrm*>(pAnchoredObj); |
| SwCntntFrm *pCnt = pFly->ContainsCntnt(); |
| while ( pCnt ) |
| { |
| lcl_PrepFlyInCntRegister( pCnt ); |
| pCnt = pCnt->GetNextCntntFrm(); |
| } |
| } |
| // <-- |
| } |
| } |
| } |
| |
| void SwPageFrm::PrepareRegisterChg() |
| { |
| SwCntntFrm *pFrm = FindFirstBodyCntnt(); |
| while( pFrm ) |
| { |
| lcl_PrepFlyInCntRegister( pFrm ); |
| pFrm = pFrm->GetNextCntntFrm(); |
| if( !IsAnLower( pFrm ) ) |
| break; |
| } |
| if( GetSortedObjs() ) |
| { |
| for( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i ) |
| { |
| // --> OD 2004-06-29 #i28701# |
| SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i]; |
| if ( pAnchoredObj->ISA(SwFlyFrm) ) |
| { |
| SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj); |
| pFrm = pFly->ContainsCntnt(); |
| while ( pFrm ) |
| { |
| ::lcl_PrepFlyInCntRegister( pFrm ); |
| pFrm = pFrm->GetNextCntntFrm(); |
| } |
| } |
| } |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwFrm::CheckPageDescs() |
| |* |
| |* Beschreibung Prueft alle Seiten ab der uebergebenen, daraufhin, |
| |* ob sie das richtige FrmFmt verwenden. Wenn 'falsche' Seiten |
| |* aufgespuehrt werden, so wird versucht die Situation moeglichst |
| |* einfache zu bereinigen. |
| |* |
| |* Ersterstellung MA 10. Feb. 93 |
| |* Letzte Aenderung MA 18. Apr. 96 |
| |* |
| |*************************************************************************/ |
| void SwFrm::CheckPageDescs( SwPageFrm *pStart, sal_Bool bNotifyFields ) |
| { |
| ASSERT( pStart, "Keine Startpage." ); |
| |
| ViewShell *pSh = pStart->getRootFrm()->GetCurrShell(); |
| SwViewImp *pImp = pSh ? pSh->Imp() : 0; |
| |
| if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() ) |
| { |
| pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() ); |
| return; |
| } |
| |
| //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos |
| //die Seitenposition an, _ab_ der invalidiert werden soll. |
| SwTwips nDocPos = LONG_MAX; |
| |
| SwRootFrm *pRoot = (SwRootFrm*)pStart->GetUpper(); |
| SwDoc* pDoc = pStart->GetFmt()->GetDoc(); |
| const sal_Bool bFtns = 0 != pDoc->GetFtnIdxs().Count(); |
| |
| SwPageFrm *pPage = pStart; |
| if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() ) |
| pPage = (SwPageFrm*)pPage->GetPrev(); |
| while ( pPage ) |
| { |
| //gewuenschten PageDesc und FrmFmt festellen. |
| SwPageDesc *pDesc = pPage->FindPageDesc(); |
| sal_Bool bCheckEmpty = pPage->IsEmptyPage(); |
| sal_Bool bActOdd = pPage->OnRightPage(); |
| sal_Bool bOdd = pPage->WannaRightPage(); |
| SwFrmFmt *pFmtWish = bOdd ? pDesc->GetRightFmt() |
| : pDesc->GetLeftFmt(); |
| |
| if ( bActOdd != bOdd || |
| pDesc != pPage->GetPageDesc() || //falscher Desc |
| ( pFmtWish != pPage->GetFmt() && //falsches Format und |
| ( !pPage->IsEmptyPage() || pFmtWish ) //nicht Leerseite |
| ) |
| ) |
| { |
| //Wenn wir schon ein Seite veraendern muessen kann das eine |
| //Weile dauern, deshalb hier den WaitCrsr pruefen. |
| if( pImp ) |
| pImp->CheckWaitCrsr(); |
| |
| //Ab hier muessen die Felder invalidiert werden! |
| if ( nDocPos == LONG_MAX ) |
| nDocPos = pPage->GetPrev() ? |
| pPage->GetPrev()->Frm().Top() : pPage->Frm().Top(); |
| |
| //Faelle: |
| //1. Wir haben eine EmptyPage und wollen eine "Normalseite". |
| // ->EmptyPage wegwerfen und weiter mit der naechsten. |
| //2. Wir haben eine EmptyPage und wollen eine EmptyPage mit |
| // anderem Descriptor. |
| // ->Descriptor austauschen. |
| //3. Wir haben eine "Normalseite" und wollen eine EmptyPage. |
| // ->Emptypage einfuegen, nicht aber wenn die Vorseite |
| // bereits eine EmptyPage ist -> 6. |
| //4. Wir haben eine "Normalseite" und wollen eine "Normalseite" |
| // mit anderem Descriptor |
| // ->Descriptor und Format austauschen |
| //5. Wir haben eine "Normalseite" und wollen eine "Normalseite" |
| // mit anderem Format |
| // ->Format austauschen. |
| //6. Wir haben kein Wunschformat erhalten, also nehmen wir das |
| // 'andere' Format (rechts/links) des PageDesc. |
| |
| if ( pPage->IsEmptyPage() && ( pFmtWish || //1. |
| ( !bOdd && !pPage->GetPrev() ) ) ) |
| { |
| SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext(); |
| pPage->Cut(); |
| delete pPage; |
| if ( pStart == pPage ) |
| pStart = pTmp; |
| pPage = pTmp; |
| continue; |
| } |
| else if ( pPage->IsEmptyPage() && !pFmtWish && //2. |
| pDesc != pPage->GetPageDesc() ) |
| { |
| pPage->SetPageDesc( pDesc, 0 ); |
| } |
| else if ( !pPage->IsEmptyPage() && //3. |
| bActOdd != bOdd && |
| ( ( !pPage->GetPrev() && !bOdd ) || |
| ( pPage->GetPrev() && |
| !((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() ) |
| ) |
| ) |
| { |
| if ( pPage->GetPrev() ) |
| pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc(); |
| SwPageFrm *pTmp = new SwPageFrm( pDoc->GetEmptyPageFmt(),pRoot,pDesc); |
| pTmp->Paste( pRoot, pPage ); |
| pTmp->PreparePage( sal_False ); |
| pPage = pTmp; |
| } |
| else if ( pPage->GetPageDesc() != pDesc ) //4. |
| { |
| SwPageDesc *pOld = pPage->GetPageDesc(); |
| pPage->SetPageDesc( pDesc, pFmtWish ); |
| if ( bFtns ) |
| { |
| //Wenn sich bestimmte Werte der FtnInfo veraendert haben |
| //muss etwas passieren. Wir versuchen den Schaden zu |
| //begrenzen. |
| //Wenn die Seiten keinen FtnCont hat, ist zwar theoretisches |
| //ein Problem denkbar, aber das ignorieren wir mit aller Kraft. |
| //Bei Aenderungen hoffen wir mal, dass eine Invalidierung |
| //ausreicht, denn alles andere wuerde viel Kraft kosten. |
| SwFtnContFrm *pCont = pPage->FindFtnCont(); |
| if ( pCont && !(pOld->GetFtnInfo() == pDesc->GetFtnInfo()) ) |
| pCont->_InvalidateAll(); |
| } |
| } |
| else if ( pFmtWish && pPage->GetFmt() != pFmtWish ) //5. |
| { |
| pPage->SetFrmFmt( pFmtWish ); |
| } |
| else if ( !pFmtWish ) //6. |
| { |
| //Format mit verdrehter Logic besorgen. |
| pFmtWish = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt(); |
| if ( pPage->GetFmt() != pFmtWish ) |
| pPage->SetFrmFmt( pFmtWish ); |
| } |
| #ifdef DBG_UTIL |
| else |
| { |
| ASSERT( sal_False, "CheckPageDescs, missing solution" ); |
| } |
| #endif |
| } |
| if ( bCheckEmpty ) |
| { |
| //Es kann noch sein, dass die Leerseite schlicht ueberflussig ist. |
| //Obiger Algorithmus kann dies leider nicht feststellen. |
| //Eigentlich muesste die Leerseite einfach praeventiv entfernt |
| //werden; sie wuerde ja ggf. wieder eingefuegt. |
| //Die EmptyPage ist genau dann ueberfluessig, wenn die Folgeseite |
| //auch ohne sie auskommt. Dazu muessen wir uns die Verhaeltnisse |
| //genauer ansehen. Wir bestimmen den PageDesc und die virtuelle |
| //Seitennummer manuell. |
| SwPageFrm *pPg = (SwPageFrm*)pPage->GetNext(); |
| if( !pPg || pPage->OnRightPage() == pPg->WannaRightPage() ) |
| { |
| //Die Folgeseite hat kein Problem ein FrmFmt zu finden oder keinen |
| //Nachfolger, also ist die Leerseite ueberfluessig. |
| SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext(); |
| pPage->Cut(); |
| delete pPage; |
| if ( pStart == pPage ) |
| pStart = pTmp; |
| pPage = pTmp; |
| continue; |
| } |
| } |
| pPage = (SwPageFrm*)pPage->GetNext(); |
| } |
| |
| pRoot->SetAssertFlyPages(); |
| pRoot->AssertPageFlys( pStart ); |
| |
| if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFlds()) ) |
| { |
| SwDocPosUpdate aMsgHnt( nDocPos ); |
| pDoc->UpdatePageFlds( &aMsgHnt ); |
| } |
| |
| #ifdef DBG_UTIL |
| //Ein paar Pruefungen muessen schon erlaubt sein. |
| |
| //1. Keine zwei EmptyPages hintereinander. |
| //2. Alle PageDescs richtig? |
| sal_Bool bEmpty = sal_False; |
| SwPageFrm *pPg = pStart; |
| while ( pPg ) |
| { |
| if ( pPg->IsEmptyPage() ) |
| { |
| if ( bEmpty ) |
| { |
| ASSERT( sal_False, "Doppelte Leerseiten." ); |
| break; //Einmal reicht. |
| } |
| bEmpty = sal_True; |
| } |
| else |
| bEmpty = sal_False; |
| |
| //MA 21. Jun. 95: Kann zu testzwecken 'rein, ist aber bei zyklen durchaus |
| //moeglich: Ein paar Seiten, auf der ersten 'erste Seite' anwenden, |
| //rechte als folge der ersten, linke als folge der rechten, rechte als |
| //folge der linken. |
| // ASSERT( pPg->GetPageDesc() == pPg->FindPageDesc(), |
| // "Seite mit falschem Descriptor." ); |
| |
| pPg = (SwPageFrm*)pPg->GetNext(); |
| } |
| #endif |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwFrm::InsertPage() |
| |* |
| |* Beschreibung |
| |* Ersterstellung MA 10. Feb. 93 |
| |* Letzte Aenderung MA 27. Jul. 93 |
| |* |
| |*************************************************************************/ |
| SwPageFrm *SwFrm::InsertPage( SwPageFrm *pPrevPage, sal_Bool bFtn ) |
| { |
| SwRootFrm *pRoot = (SwRootFrm*)pPrevPage->GetUpper(); |
| SwPageFrm *pSibling = (SwPageFrm*)pRoot->GetLower(); |
| SwPageDesc *pDesc = pSibling->GetPageDesc(); |
| |
| pSibling = (SwPageFrm*)pPrevPage->GetNext(); |
| //Rechte (ungerade) oder linke (gerade) Seite einfuegen? |
| sal_Bool bNextOdd = !pPrevPage->OnRightPage(); |
| sal_Bool bWishedOdd = bNextOdd; |
| |
| //Welcher PageDesc gilt? |
| //Bei CntntFrm der aus dem Format wenn einer angegeben ist, |
| //der Follow vom bereits in der PrevPage gueltigen sonst. |
| pDesc = 0; |
| if ( IsFlowFrm() && !SwFlowFrm::CastFlowFrm( this )->IsFollow() ) |
| { SwFmtPageDesc &rDesc = (SwFmtPageDesc&)GetAttrSet()->GetPageDesc(); |
| pDesc = rDesc.GetPageDesc(); |
| if ( rDesc.GetNumOffset() ) |
| { |
| bWishedOdd = rDesc.GetNumOffset() % 2 ? sal_True : sal_False; |
| //Die Gelegenheit nutzen wir um das Flag an der Root zu pflegen. |
| pRoot->SetVirtPageNum( sal_True ); |
| } |
| } |
| if ( !pDesc ) |
| pDesc = pPrevPage->GetPageDesc()->GetFollow(); |
| |
| ASSERT( pDesc, "Missing PageDesc" ); |
| if( !(bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ) |
| bWishedOdd = !bWishedOdd; |
| |
| SwDoc *pDoc = pPrevPage->GetFmt()->GetDoc(); |
| SwFrmFmt *pFmt; |
| sal_Bool bCheckPages = sal_False; |
| //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben eine |
| //Leerseite einfuegen. |
| if( bWishedOdd != bNextOdd ) |
| { pFmt = pDoc->GetEmptyPageFmt(); |
| SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc(); |
| SwPageFrm *pPage = new SwPageFrm( pFmt, pRoot, pTmpDesc ); |
| pPage->Paste( pRoot, pSibling ); |
| pPage->PreparePage( bFtn ); |
| //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten |
| //Es sei denn, es ist eine Fussnotenseite |
| if ( pSibling && !pSibling->IsFtnPage() && |
| !pSibling->FindFirstBodyCntnt() ) |
| { |
| SwPageFrm *pDel = pSibling; |
| pSibling = (SwPageFrm*)pSibling->GetNext(); |
| if ( pDoc->GetFtnIdxs().Count() ) |
| pRoot->RemoveFtns( pDel, sal_True ); |
| pDel->Cut(); |
| delete pDel; |
| } |
| else |
| bCheckPages = sal_True; |
| } |
| pFmt = bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt(); |
| ASSERT( pFmt, "Descriptor without format." ); |
| SwPageFrm *pPage = new SwPageFrm( pFmt, pRoot, pDesc ); |
| pPage->Paste( pRoot, pSibling ); |
| pPage->PreparePage( bFtn ); |
| //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten |
| //Es sei denn es ist eine Fussnotenseite. |
| if ( pSibling && !pSibling->IsFtnPage() && |
| !pSibling->FindFirstBodyCntnt() ) |
| { |
| SwPageFrm *pDel = pSibling; |
| pSibling = (SwPageFrm*)pSibling->GetNext(); |
| if ( pDoc->GetFtnIdxs().Count() ) |
| pRoot->RemoveFtns( pDel, sal_True ); |
| pDel->Cut(); |
| delete pDel; |
| } |
| else |
| bCheckPages = sal_True; |
| |
| if ( pSibling ) |
| { |
| if ( bCheckPages ) |
| { |
| CheckPageDescs( pSibling, sal_False ); |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| SwViewImp *pImp = pSh ? pSh->Imp() : 0; |
| if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() ) |
| { |
| const sal_uInt16 nNum = pImp->GetLayAction().GetCheckPageNum(); |
| if ( nNum == pPrevPage->GetPhyPageNum() + 1 ) |
| pImp->GetLayAction().SetCheckPageNumDirect( |
| pSibling->GetPhyPageNum() ); |
| return pPage; |
| } |
| } |
| else |
| pRoot->AssertPageFlys( pSibling ); |
| } |
| |
| //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos |
| //die Seitenposition an, _ab_ der invalidiert werden soll. |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if ( !pSh || !pSh->Imp()->IsUpdateExpFlds() ) |
| { |
| SwDocPosUpdate aMsgHnt( pPrevPage->Frm().Top() ); |
| pDoc->UpdatePageFlds( &aMsgHnt ); |
| } |
| return pPage; |
| } |
| |
| sw::sidebarwindows::SidebarPosition SwPageFrm::SidebarPosition() const |
| { |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if( !pSh || pSh->GetViewOptions()->getBrowseMode() ) |
| { |
| return sw::sidebarwindows::SIDEBAR_RIGHT; |
| } |
| else |
| { |
| const bool bLTR = getRootFrm()->IsLeftToRightViewLayout(); |
| const bool bBookMode = pSh->GetViewOptions()->IsViewLayoutBookMode(); |
| const bool bRightSidebar = bLTR ? (!bBookMode || OnRightPage()) : (bBookMode && !OnRightPage()); |
| |
| return bRightSidebar |
| ? sw::sidebarwindows::SIDEBAR_RIGHT |
| : sw::sidebarwindows::SIDEBAR_LEFT; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::GrowFrm() |
| |* |
| |* Ersterstellung MA 30. Jul. 92 |
| |* Letzte Aenderung MA 05. May. 94 |
| |* |
| |*************************************************************************/ |
| |
| SwTwips SwRootFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool ) |
| { |
| if ( !bTst ) |
| Frm().SSize().Height() += nDist; |
| return nDist; |
| } |
| /************************************************************************* |
| |* |
| |* SwRootFrm::ShrinkFrm() |
| |* |
| |* Ersterstellung MA 30. Jul. 92 |
| |* Letzte Aenderung MA 05. May. 94 |
| |* |
| |*************************************************************************/ |
| SwTwips SwRootFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool ) |
| { |
| ASSERT( nDist >= 0, "nDist < 0." ); |
| ASSERT( nDist <= Frm().Height(), "nDist > als aktuelle Groesse." ); |
| |
| if ( !bTst ) |
| Frm().SSize().Height() -= nDist; |
| return nDist; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::RemoveSuperfluous() |
| |* |
| |* Beschreibung: Entfernung von ueberfluessigen Seiten. |
| |* Arbeitet nur wenn das Flag bCheckSuperfluous gesetzt ist. |
| |* Definition: Eine Seite ist genau dann leer, wenn der |
| |* Body-Textbereich keinen CntntFrm enthaelt, aber nicht, wenn noch |
| |* mindestens ein Fly an der Seite klebt. |
| |* Die Seite ist auch dann nicht leer, wenn sie noch eine |
| |* Fussnote enthaelt. |
| |* Es muss zweimal angesetzt werden um leeren Seiten aufzuspueren: |
| |* - einmal fuer die Endnotenseiten. |
| |* - und einmal fuer die Seiten des Bodytextes. |
| |* |
| |* Ersterstellung MA 20. May. 92 |
| |* Letzte Aenderung MA 10. Jan. 95 |
| |* |
| |*************************************************************************/ |
| void SwRootFrm::RemoveSuperfluous() |
| { |
| if ( !IsSuperfluous() ) |
| return; |
| bCheckSuperfluous = sal_False; |
| |
| SwPageFrm *pPage = GetLastPage(); |
| long nDocPos = LONG_MAX; |
| |
| //Jetzt wird fuer die jeweils letzte Seite geprueft ob sie leer ist |
| //bei der ersten nicht leeren Seite wird die Schleife beendet. |
| do |
| { |
| bool bExistEssentialObjs = ( 0 != pPage->GetSortedObjs() ); |
| if ( bExistEssentialObjs ) |
| { |
| //Nur weil die Seite Flys hat sind wir noch lange nicht fertig, |
| //denn wenn alle Flys an generischem Inhalt haengen, so ist sie |
| //trotzdem ueberfluessig (Ueberpruefung auf DocBody sollte reichen). |
| // OD 19.06.2003 #108784# - consider that drawing objects in |
| // header/footer are supported now. |
| bool bOnlySuperfluosObjs = true; |
| SwSortedObjs &rObjs = *pPage->GetSortedObjs(); |
| for ( sal_uInt16 i = 0; bOnlySuperfluosObjs && i < rObjs.Count(); ++i ) |
| { |
| // --> OD 2004-06-29 #i28701# |
| SwAnchoredObject* pAnchoredObj = rObjs[i]; |
| // OD 2004-01-19 #110582# - do not consider hidden objects |
| if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId( |
| pAnchoredObj->GetDrawObj()->GetLayer() ) && |
| !pAnchoredObj->GetAnchorFrm()->FindFooterOrHeader() ) |
| { |
| bOnlySuperfluosObjs = false; |
| } |
| // <-- |
| } |
| bExistEssentialObjs = !bOnlySuperfluosObjs; |
| } |
| |
| // OD 19.06.2003 #108784# - optimization: check first, if essential objects |
| // exists. |
| const SwLayoutFrm* pBody = 0; |
| if ( bExistEssentialObjs || |
| pPage->FindFtnCont() || |
| ( 0 != ( pBody = pPage->FindBodyCont() ) && |
| ( pBody->ContainsCntnt() || |
| // --> FME 2005-05-18 #i47580# |
| // Do not delete page if there's an empty tabframe |
| // left. I think it might be correct to use ContainsAny() |
| // instead of ContainsCntnt() to cover the empty-table-case, |
| // but I'm not fully sure, since ContainsAny() also returns |
| // SectionFrames. Therefore I prefer to do it the safe way: |
| ( pBody->Lower() && pBody->Lower()->IsTabFrm() ) ) ) ) |
| // <-- |
| { |
| if ( pPage->IsFtnPage() ) |
| { |
| while ( pPage->IsFtnPage() ) |
| { |
| pPage = (SwPageFrm*)pPage->GetPrev(); |
| ASSERT( pPage, "Nur noch Endnotenseiten uebrig." ); |
| } |
| continue; |
| } |
| else |
| pPage = 0; |
| } |
| |
| if ( pPage ) |
| { |
| SwPageFrm *pEmpty = pPage; |
| pPage = (SwPageFrm*)pPage->GetPrev(); |
| if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() ) |
| RemoveFtns( pEmpty, sal_True ); |
| pEmpty->Cut(); |
| delete pEmpty; |
| nDocPos = pPage ? pPage->Frm().Top() : 0; |
| } |
| } while ( pPage ); |
| |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| if ( nDocPos != LONG_MAX && |
| (!pSh || !pSh->Imp()->IsUpdateExpFlds()) ) |
| { |
| SwDocPosUpdate aMsgHnt( nDocPos ); |
| GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt ); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::AssertFlyPages() |
| |* |
| |* Beschreibung Stellt sicher, dass genuegend Seiten vorhanden |
| |* sind, damit alle Seitengebundenen Rahmen und DrawObject |
| |* untergebracht sind. |
| |* |
| |* Ersterstellung MA 27. Jul. 93 |
| |* Letzte Aenderung MA 24. Apr. 97 |
| |* |
| |*************************************************************************/ |
| void SwRootFrm::AssertFlyPages() |
| { |
| if ( !IsAssertFlyPages() ) |
| return; |
| bAssertFlyPages = sal_False; |
| |
| SwDoc *pDoc = GetFmt()->GetDoc(); |
| const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts(); |
| |
| //Auf welche Seite will der 'letzte' Fly? |
| sal_uInt16 nMaxPg = 0; |
| sal_uInt16 i; |
| |
| for ( i = 0; i < pTbl->Count(); ++i ) |
| { |
| const SwFmtAnchor &rAnch = (*pTbl)[i]->GetAnchor(); |
| if ( !rAnch.GetCntntAnchor() && nMaxPg < rAnch.GetPageNum() ) |
| nMaxPg = rAnch.GetPageNum(); |
| } |
| //Wieviele Seiten haben wir derzeit? |
| SwPageFrm *pPage = (SwPageFrm*)Lower(); |
| while ( pPage && pPage->GetNext() && |
| !((SwPageFrm*)pPage->GetNext())->IsFtnPage() ) |
| { |
| pPage = (SwPageFrm*)pPage->GetNext(); |
| } |
| |
| if ( nMaxPg > pPage->GetPhyPageNum() ) |
| { |
| //Die Seiten werden ausgehend von der letzten Seite konsequent |
| //nach den Regeln der PageDescs weitergefuehrt. |
| sal_Bool bOdd = pPage->GetPhyPageNum() % 2 ? sal_True : sal_False; |
| SwPageDesc *pDesc = pPage->GetPageDesc(); |
| SwFrm *pSibling = pPage->GetNext(); |
| for ( i = pPage->GetPhyPageNum(); i < nMaxPg; ++i ) |
| { |
| if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ) |
| { |
| //Leerseite einfuegen, die Flys werden aber erst von |
| //der naechsten Seite aufgenommen! |
| pPage = new SwPageFrm( pDoc->GetEmptyPageFmt(), this, pDesc ); |
| pPage->Paste( this, pSibling ); |
| pPage->PreparePage( sal_False ); |
| bOdd = bOdd ? sal_False : sal_True; |
| ++i; |
| } |
| pPage = new |
| SwPageFrm( (bOdd ? pDesc->GetRightFmt() : |
| pDesc->GetLeftFmt()), this, pDesc ); |
| pPage->Paste( this, pSibling ); |
| pPage->PreparePage( sal_False ); |
| bOdd = bOdd ? sal_False : sal_True; |
| pDesc = pDesc->GetFollow(); |
| } |
| //Jetzt koennen die Endnotenseiten natuerlich wieder krumm sein; |
| //in diesem Fall werden sie vernichtet. |
| if ( pDoc->GetFtnIdxs().Count() ) |
| { |
| pPage = (SwPageFrm*)Lower(); |
| while ( pPage && !pPage->IsFtnPage() ) |
| pPage = (SwPageFrm*)pPage->GetNext(); |
| |
| if ( pPage ) |
| { |
| SwPageDesc *pTmpDesc = pPage->FindPageDesc(); |
| bOdd = pPage->OnRightPage(); |
| if ( pPage->GetFmt() != |
| (bOdd ? pTmpDesc->GetRightFmt() : pTmpDesc->GetLeftFmt()) ) |
| RemoveFtns( pPage, sal_False, sal_True ); |
| } |
| } |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::AssertPageFlys() |
| |* |
| |* Beschreibung Stellt sicher, dass ab der uebergebenen Seite |
| |* auf allen Seiten die Seitengebunden Objecte auf der richtigen |
| |* Seite (Seitennummer stehen). |
| |* |
| |* Ersterstellung MA 02. Nov. 94 |
| |* Letzte Aenderung MA 10. Aug. 95 |
| |* |
| |*************************************************************************/ |
| void SwRootFrm::AssertPageFlys( SwPageFrm *pPage ) |
| { |
| while ( pPage ) |
| { |
| if ( pPage->GetSortedObjs() ) |
| { |
| pPage->GetSortedObjs(); |
| for ( int i = 0; |
| pPage->GetSortedObjs() && sal_uInt16(i) < pPage->GetSortedObjs()->Count(); |
| ++i) |
| { |
| // --> OD 2004-06-29 #i28701# |
| SwFrmFmt& rFmt = (*pPage->GetSortedObjs())[i]->GetFrmFmt(); |
| const SwFmtAnchor &rAnch = rFmt.GetAnchor(); |
| const sal_uInt16 nPg = rAnch.GetPageNum(); |
| if ((rAnch.GetAnchorId() == FLY_AT_PAGE) && |
| nPg != pPage->GetPhyPageNum() ) |
| { |
| //Das er auf der falschen Seite steht muss noch nichts |
| //heissen, wenn er eigentlich auf der Vorseite |
| //stehen will und diese eine EmptyPage ist. |
| if( nPg && !(pPage->GetPhyPageNum()-1 == nPg && |
| ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage()) ) |
| { |
| //Umhaengen kann er sich selbst, indem wir ihm |
| //einfach ein Modify mit seinem AnkerAttr schicken. |
| #ifndef DBG_UTIL |
| rFmt.NotifyClients( 0, (SwFmtAnchor*)&rAnch ); |
| #else |
| const sal_uInt32 nCnt = pPage->GetSortedObjs()->Count(); |
| rFmt.NotifyClients( 0, (SwFmtAnchor*)&rAnch ); |
| ASSERT( !pPage->GetSortedObjs() || |
| nCnt != pPage->GetSortedObjs()->Count(), |
| "Object couldn't be reattached!" ); |
| #endif |
| --i; |
| } |
| } |
| } |
| } |
| pPage = (SwPageFrm*)pPage->GetNext(); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::ChgSize() |
| |* |
| |* Ersterstellung MA 24. Jul. 92 |
| |* Letzte Aenderung MA 13. Aug. 93 |
| |* |
| |*************************************************************************/ |
| Size SwRootFrm::ChgSize( const Size& aNewSize ) |
| { |
| Frm().SSize() = aNewSize; |
| _InvalidatePrt(); |
| bFixSize = sal_False; |
| return Frm().SSize(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::MakeAll() |
| |* |
| |* Ersterstellung MA 17. Nov. 92 |
| |* Letzte Aenderung MA 19. Apr. 93 |
| |* |
| |*************************************************************************/ |
| void SwRootFrm::MakeAll() |
| { |
| if ( !bValidPos ) |
| { bValidPos = sal_True; |
| aFrm.Pos().X() = aFrm.Pos().Y() = DOCUMENTBORDER; |
| } |
| if ( !bValidPrtArea ) |
| { bValidPrtArea = sal_True; |
| aPrt.Pos().X() = aPrt.Pos().Y() = 0; |
| aPrt.SSize( aFrm.SSize() ); |
| } |
| if ( !bValidSize ) |
| //SSize wird von den Seiten (Cut/Paste) eingestellt. |
| bValidSize = sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::ImplInvalidateBrowseWidth() |
| |* |
| |* Ersterstellung MA 08. Jun. 96 |
| |* Letzte Aenderung MA 08. Jun. 96 |
| |* |
| |*************************************************************************/ |
| void SwRootFrm::ImplInvalidateBrowseWidth() |
| { |
| bBrowseWidthValid = sal_False; |
| SwFrm *pPg = Lower(); |
| while ( pPg ) |
| { |
| pPg->InvalidateSize(); |
| pPg = pPg->GetNext(); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::ImplCalcBrowseWidth() |
| |* |
| |* Ersterstellung MA 07. Jun. 96 |
| |* Letzte Aenderung MA 13. Jun. 96 |
| |* |
| |*************************************************************************/ |
| void SwRootFrm::ImplCalcBrowseWidth() |
| { |
| ASSERT( GetCurrShell() && GetCurrShell()->GetViewOptions()->getBrowseMode(), |
| "CalcBrowseWidth and not in BrowseView" ) |
| |
| //Die (minimale) Breite wird von Rahmen, Tabellen und Zeichenobjekten |
| //bestimmt. Die Breite wird nicht anhand ihrer aktuellen Groessen bestimmt, |
| //sondern anhand der Attribute. Es interessiert also nicht wie breit sie |
| //sind, sondern wie breit sie sein wollen. |
| //Rahmen und Zeichenobjekte innerhalb ander Objekte (Rahmen, Tabellen) |
| //Zaehlen nicht. |
| //Seitenraender und Spalten werden hier nicht beruecksichtigt. |
| |
| SwFrm *pFrm = ContainsCntnt(); |
| while ( pFrm && !pFrm->IsInDocBody() ) |
| pFrm = ((SwCntntFrm*)pFrm)->GetNextCntntFrm(); |
| if ( !pFrm ) |
| return; |
| |
| bBrowseWidthValid = sal_True; |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| nBrowseWidth = pSh |
| ? MINLAY + 2 * pSh->GetOut()-> |
| PixelToLogic( pSh->GetBrowseBorder() ).Width() |
| : 5000; |
| do |
| { |
| if ( pFrm->IsInTab() ) |
| pFrm = pFrm->FindTabFrm(); |
| |
| if ( pFrm->IsTabFrm() && |
| !((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize().GetWidthPercent() ) |
| { |
| SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); |
| const SwBorderAttrs &rAttrs = *aAccess.Get(); |
| const SwFmtHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient(); |
| long nWidth = rAttrs.GetSize().Width(); |
| if ( nWidth < USHRT_MAX-2000 && //-2000, weil bei Randeinstellung per |
| //Zuppeln das USHRT_MAX verlorengeht! |
| text::HoriOrientation::FULL != rHori.GetHoriOrient() ) |
| { |
| const SwHTMLTableLayout *pLayoutInfo = |
| ((const SwTabFrm *)pFrm)->GetTable() |
| ->GetHTMLTableLayout(); |
| if ( pLayoutInfo ) |
| nWidth = Min( nWidth, pLayoutInfo->GetBrowseWidthMin() ); |
| |
| switch ( rHori.GetHoriOrient() ) |
| { |
| case text::HoriOrientation::NONE: |
| // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)> |
| nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ); |
| break; |
| case text::HoriOrientation::LEFT_AND_WIDTH: |
| nWidth += rAttrs.CalcLeft( pFrm ); |
| break; |
| default: |
| break; |
| |
| } |
| nBrowseWidth = Max( nBrowseWidth, nWidth ); |
| } |
| } |
| else if ( pFrm->GetDrawObjs() ) |
| { |
| for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) |
| { |
| // --> OD 2004-06-29 #i28701# |
| SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i]; |
| const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); |
| const sal_Bool bFly = pAnchoredObj->ISA(SwFlyFrm); |
| if ((bFly && (WEIT_WECH == pAnchoredObj->GetObjRect().Width())) |
| || rFmt.GetFrmSize().GetWidthPercent()) |
| { |
| continue; |
| } |
| |
| long nWidth = 0; |
| switch ( rFmt.GetAnchor().GetAnchorId() ) |
| { |
| case FLY_AS_CHAR: |
| nWidth = bFly ? rFmt.GetFrmSize().GetWidth() : |
| pAnchoredObj->GetObjRect().Width(); |
| break; |
| case FLY_AT_PARA: |
| { |
| // --> FME 2004-09-13 #i33170# |
| // Reactivated old code because |
| // nWidth = pAnchoredObj->GetObjRect().Right() |
| // gives wrong results for objects that are still |
| // at position WEIT_WECH. |
| if ( bFly ) |
| { |
| nWidth = rFmt.GetFrmSize().GetWidth(); |
| const SwFmtHoriOrient &rHori = rFmt.GetHoriOrient(); |
| switch ( rHori.GetHoriOrient() ) |
| { |
| case text::HoriOrientation::NONE: |
| nWidth += rHori.GetPos(); |
| break; |
| case text::HoriOrientation::INSIDE: |
| case text::HoriOrientation::LEFT: |
| if ( text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ) |
| nWidth += pFrm->Prt().Left(); |
| break; |
| default: |
| break; |
| } |
| } |
| else |
| //Fuer Zeichenobjekte ist die Auswahl sehr klein, |
| //weil sie keine Attribute haben, also durch ihre |
| //aktuelle Groesse bestimmt werden. |
| nWidth = pAnchoredObj->GetObjRect().Right() - |
| pAnchoredObj->GetDrawObj()->GetAnchorPos().X(); |
| // <-- |
| } |
| break; |
| default: /* do nothing */; |
| } |
| nBrowseWidth = Max( nBrowseWidth, nWidth ); |
| } |
| } |
| pFrm = pFrm->FindNextCnt(); |
| } while ( pFrm ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwRootFrm::StartAllAction() |
| |* |
| |* Ersterstellung MA 08. Mar. 98 |
| |* Letzte Aenderung MA 08. Mar. 98 |
| |* |
| |*************************************************************************/ |
| |
| void SwRootFrm::StartAllAction() |
| { |
| ViewShell *pSh = GetCurrShell(); |
| if ( pSh ) |
| do |
| { if ( pSh->ISA( SwCrsrShell ) ) |
| ((SwCrsrShell*)pSh)->StartAction(); |
| else |
| pSh->StartAction(); |
| pSh = (ViewShell*)pSh->GetNext(); |
| |
| } while ( pSh != GetCurrShell() ); |
| } |
| |
| void SwRootFrm::EndAllAction( sal_Bool bVirDev ) |
| { |
| ViewShell *pSh = GetCurrShell(); |
| if ( pSh ) |
| do |
| { |
| const sal_Bool bOldEndActionByVirDev = pSh->IsEndActionByVirDev(); |
| pSh->SetEndActionByVirDev( bVirDev ); |
| if ( pSh->ISA( SwCrsrShell ) ) |
| { |
| ((SwCrsrShell*)pSh)->EndAction(); |
| ((SwCrsrShell*)pSh)->CallChgLnk(); |
| if ( pSh->ISA( SwFEShell ) ) |
| ((SwFEShell*)pSh)->SetChainMarker(); |
| } |
| else |
| pSh->EndAction(); |
| pSh->SetEndActionByVirDev( bOldEndActionByVirDev ); |
| pSh = (ViewShell*)pSh->GetNext(); |
| |
| } while ( pSh != GetCurrShell() ); |
| } |
| |
| void SwRootFrm::UnoRemoveAllActions() |
| { |
| ViewShell *pSh = GetCurrShell(); |
| if ( pSh ) |
| do |
| { |
| // --> OD 2008-05-16 #i84729# |
| // No end action, if <ViewShell> instance is currently in its end action. |
| // Recursives calls to <::EndAction()> are not allowed. |
| if ( !pSh->IsInEndAction() ) |
| { |
| DBG_ASSERT(!pSh->GetRestoreActions(), "Restore action count is already set!"); |
| sal_Bool bCrsr = pSh->ISA( SwCrsrShell ); |
| sal_Bool bFE = pSh->ISA( SwFEShell ); |
| sal_uInt16 nRestore = 0; |
| while( pSh->ActionCount() ) |
| { |
| if( bCrsr ) |
| { |
| ((SwCrsrShell*)pSh)->EndAction(); |
| ((SwCrsrShell*)pSh)->CallChgLnk(); |
| if ( bFE ) |
| ((SwFEShell*)pSh)->SetChainMarker(); |
| } |
| else |
| pSh->EndAction(); |
| nRestore++; |
| } |
| pSh->SetRestoreActions(nRestore); |
| } |
| // <-- |
| pSh->LockView(sal_True); |
| pSh = (ViewShell*)pSh->GetNext(); |
| |
| } while ( pSh != GetCurrShell() ); |
| } |
| |
| void SwRootFrm::UnoRestoreAllActions() |
| { |
| ViewShell *pSh = GetCurrShell(); |
| if ( pSh ) |
| do |
| { |
| sal_uInt16 nActions = pSh->GetRestoreActions(); |
| while( nActions-- ) |
| { |
| if ( pSh->ISA( SwCrsrShell ) ) |
| ((SwCrsrShell*)pSh)->StartAction(); |
| else |
| pSh->StartAction(); |
| } |
| pSh->SetRestoreActions(0); |
| pSh->LockView(sal_False); |
| pSh = (ViewShell*)pSh->GetNext(); |
| |
| } while ( pSh != GetCurrShell() ); |
| } |
| |
| // PAGES01: Helper functions for SwRootFrm::CheckViewLayout |
| void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset ); |
| |
| void lcl_MoveAllLowerObjs( SwFrm* pFrm, const Point& rOffset ) |
| { |
| SwSortedObjs* pSortedObj = 0; |
| const bool bPage = pFrm->IsPageFrm(); |
| |
| if ( bPage ) |
| pSortedObj = static_cast<SwPageFrm*>(pFrm)->GetSortedObjs(); |
| else |
| pSortedObj = pFrm->GetDrawObjs(); |
| |
| for ( sal_uInt16 i = 0; pSortedObj && i < pSortedObj->Count(); ++i) |
| { |
| SwAnchoredObject* pAnchoredObj = (*pSortedObj)[i]; |
| |
| const SwFrmFmt& rObjFmt = pAnchoredObj->GetFrmFmt(); |
| const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor(); |
| |
| // all except from the as character anchored objects are moved |
| // when processing the page frame: |
| const bool bAsChar = (rAnchor.GetAnchorId() == FLY_AS_CHAR); |
| if ( !bPage && !bAsChar ) |
| continue; |
| |
| SwObjPositioningInProgress aPosInProgress( *pAnchoredObj ); |
| |
| if ( pAnchoredObj->ISA(SwFlyFrm) ) |
| { |
| SwFlyFrm* pFlyFrm( static_cast<SwFlyFrm*>(pAnchoredObj) ); |
| lcl_MoveAllLowers( pFlyFrm, rOffset ); |
| pFlyFrm->NotifyDrawObj(); |
| // --> let the active embedded object be moved |
| if ( pFlyFrm->Lower() ) |
| { |
| if ( pFlyFrm->Lower()->IsNoTxtFrm() ) |
| { |
| SwCntntFrm* pCntntFrm = static_cast<SwCntntFrm*>(pFlyFrm->Lower()); |
| SwRootFrm* pRoot = pFlyFrm->Lower()->getRootFrm(); |
| ViewShell *pSh = pRoot ? pRoot->GetCurrShell() : 0; |
| if ( pSh ) |
| { |
| SwOLENode* pNode = pCntntFrm->GetNode()->GetOLENode(); |
| if ( pNode ) |
| { |
| svt::EmbeddedObjectRef& xObj = pNode->GetOLEObj().GetObject(); |
| if ( xObj.is() ) |
| { |
| ViewShell* pTmp = pSh; |
| do |
| { |
| SwFEShell* pFEShell = dynamic_cast< SwFEShell* >( pTmp ); |
| if ( pFEShell ) |
| pFEShell->MoveObjectIfActive( xObj, rOffset ); |
| pTmp = static_cast<ViewShell*>( pTmp->GetNext() ); |
| } while( pTmp != pSh ); |
| } |
| } |
| } |
| } |
| } |
| // <-- |
| } |
| else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) ) |
| { |
| SwAnchoredDrawObject* pAnchoredDrawObj( static_cast<SwAnchoredDrawObject*>(pAnchoredObj) ); |
| |
| // don't touch objects that are not yet positioned: |
| const bool bNotYetPositioned = pAnchoredDrawObj->NotYetPositioned(); |
| if ( bNotYetPositioned ) |
| continue; |
| |
| const Point aCurrAnchorPos = pAnchoredDrawObj->GetDrawObj()->GetAnchorPos(); |
| const Point aNewAnchorPos( ( aCurrAnchorPos + rOffset ) ); |
| pAnchoredDrawObj->DrawObj()->SetAnchorPos( aNewAnchorPos ); |
| pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() ); |
| |
| // clear contour cache if contour wrapping is enabled #i100684# |
| if ( pAnchoredDrawObj->GetFrmFmt().GetSurround().IsContour() ) |
| ClrContourCache( pAnchoredDrawObj->GetDrawObj() ); |
| } |
| // --> OD 2009-08-20 #i92511# |
| // cache for object rectangle inclusive spaces has to be invalidated. |
| pAnchoredObj->InvalidateObjRectWithSpaces(); |
| // <-- |
| } |
| } |
| |
| void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset ) |
| { |
| const SwRect aFrm( pFrm->Frm() ); |
| |
| // first move the current frame |
| pFrm->Frm().Pos() += rOffset; |
| |
| // Don't forget accessibility: |
| if( pFrm->IsAccessibleFrm() ) |
| { |
| SwRootFrm *pRootFrm = pFrm->getRootFrm(); |
| if( pRootFrm && pRootFrm->IsAnyShellAccessible() && |
| pRootFrm->GetCurrShell() ) |
| { |
| pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm ); |
| } |
| } |
| |
| // the move any objects |
| lcl_MoveAllLowerObjs( pFrm, rOffset ); |
| |
| // finally, for layout frames we have to call this function recursively: |
| if ( pFrm->ISA(SwLayoutFrm) ) |
| { |
| SwFrm* pLowerFrm = pFrm->GetLower(); |
| while ( pLowerFrm ) |
| { |
| lcl_MoveAllLowers( pLowerFrm, rOffset ); |
| pLowerFrm = pLowerFrm->GetNext(); |
| } |
| } |
| } |
| |
| // PAGES01: Calculate how the pages have to be positioned |
| void SwRootFrm::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVisArea ) |
| { |
| // --> OD 2008-07-07 #i91432# |
| // No calculation of page positions, if only an empty page is present. |
| // This situation occurs when <SwRootFrm> instance is in construction |
| // and the document contains only left pages. |
| if ( Lower()->GetNext() == 0 && |
| static_cast<SwPageFrm*>(Lower())->IsEmptyPage() ) |
| { |
| return; |
| } |
| // <-- |
| |
| if ( !pVisArea ) |
| { |
| // no early return for bNewPage |
| if ( mnViewWidth < 0 ) |
| mnViewWidth = 0; |
| } |
| else |
| { |
| ASSERT( pViewOpt, "CheckViewLayout required ViewOptions" ) |
| |
| const sal_uInt16 nColumns = pViewOpt->GetViewLayoutColumns(); |
| const bool bBookMode = pViewOpt->IsViewLayoutBookMode(); |
| |
| if ( nColumns == mnColumns && bBookMode == mbBookMode && pVisArea->Width() == mnViewWidth && !mbSidebarChanged ) |
| return; |
| |
| mnColumns = nColumns; |
| mbBookMode = bBookMode; |
| mnViewWidth = pVisArea->Width(); |
| mbSidebarChanged = false; |
| } |
| |
| if( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE ) ) |
| { |
| mnColumns = 1; |
| mbBookMode = false; |
| } |
| |
| Calc(); |
| |
| const sal_Bool bOldCallbackActionEnabled = IsCallbackActionEnabled(); |
| SetCallbackActionEnabled( sal_False ); |
| |
| maPageRects.clear(); |
| |
| const long nBorder = Frm().Pos().X(); |
| const long nVisWidth = mnViewWidth - 2 * nBorder; |
| const long nGapBetweenPages = GAPBETWEENPAGES; |
| |
| // check how many pages fit into the first page layout row: |
| SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(Lower()); |
| |
| // will contain the number of pages per row. 0 means that |
| // the page does not fit. |
| long nWidthRemain = nVisWidth; |
| |
| // after one row has been processed, these variables contain |
| // the width of the row and the maxium of the page heights |
| long nCurrentRowHeight = 0; |
| long nCurrentRowWidth = 0; |
| |
| // these variables are used to finally set the size of the |
| // root frame |
| long nSumRowHeight = 0; |
| SwTwips nMinPageLeft = TWIPS_MAX; |
| SwTwips nMaxPageRight = 0; |
| SwPageFrm* pStartOfRow = pPageFrm; |
| sal_uInt16 nNumberOfPagesInRow = mbBookMode ? 1 : 0; // in book view, start with right page |
| bool bFirstRow = true; |
| |
| bool bPageChanged = false; |
| const bool bRTL = !IsLeftToRightViewLayout(); |
| const SwTwips nSidebarWidth = SwPageFrm::GetSidebarBorderWidth( GetCurrShell() ); |
| |
| while ( pPageFrm ) |
| { |
| // we consider the current page to be "start of row" if |
| // 1. it is the first page in the current row or |
| // 2. it is the second page in the row and the first page is an empty page in non-book view: |
| const bool bStartOfRow = pPageFrm == pStartOfRow || |
| ( pStartOfRow->IsEmptyPage() && pPageFrm == pStartOfRow->GetNext() && !mbBookMode ); |
| |
| const bool bEmptyPage = pPageFrm->IsEmptyPage() && !mbBookMode; |
| |
| // no half doc border space for first page in each row and |
| long nPageWidth = 0; |
| long nPageHeight = 0; |
| |
| if ( mbBookMode ) |
| { |
| const SwFrm& rFormatPage = pPageFrm->GetFormatPage(); |
| |
| nPageWidth = rFormatPage.Frm().Width() + nSidebarWidth + ((bStartOfRow || 1 == (pPageFrm->GetPhyPageNum()%2)) ? 0 : nGapBetweenPages); |
| nPageHeight = rFormatPage.Frm().Height() + nGapBetweenPages; |
| } |
| else |
| { |
| SwRect aPageFrm; |
| if ( !pPageFrm->IsEmptyPage() ) |
| { |
| nPageWidth = pPageFrm->Frm().Width() + nSidebarWidth + (bStartOfRow ? 0 : nGapBetweenPages); |
| nPageHeight = pPageFrm->Frm().Height() + nGapBetweenPages; |
| } |
| } |
| |
| if ( !bEmptyPage ) |
| ++nNumberOfPagesInRow; |
| |
| // finish current row if |
| // 1. in dynamic mode the current page does not fit anymore or |
| // 2. the current page exceeds the maximum number of columns |
| bool bRowFinished = (0 == mnColumns && nWidthRemain < nPageWidth ) || |
| (0 != mnColumns && mnColumns < nNumberOfPagesInRow); |
| |
| // make sure that at least one page goes to the current row: |
| if ( !bRowFinished || bStartOfRow ) |
| { |
| // current page is allowed to be in current row |
| nWidthRemain = nWidthRemain - nPageWidth; |
| |
| nCurrentRowWidth = nCurrentRowWidth + nPageWidth; |
| nCurrentRowHeight = Max( nCurrentRowHeight, nPageHeight ); |
| |
| pPageFrm = static_cast<SwPageFrm*>(pPageFrm->GetNext()); |
| |
| if ( !pPageFrm ) |
| bRowFinished = true; |
| } |
| |
| if ( bRowFinished ) |
| { |
| // pPageFrm now points to the first page in the new row or null |
| // pStartOfRow points to the first page in the current row |
| |
| // special centering for last row. pretend to fill the last row with virtual copies of the last page before centering: |
| if ( !pPageFrm && nWidthRemain > 0 ) |
| { |
| // find last page in current row: |
| const SwPageFrm* pLastPageInCurrentRow = pStartOfRow; |
| while( pLastPageInCurrentRow->GetNext() ) |
| pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetNext()); |
| |
| if ( pLastPageInCurrentRow->IsEmptyPage() ) |
| pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetPrev()); |
| |
| // check how many times the last page would still fit into the remaining space: |
| sal_uInt16 nNumberOfVirtualPages = 0; |
| const sal_uInt16 nMaxNumberOfVirtualPages = mnColumns > 0 ? mnColumns - nNumberOfPagesInRow : USHRT_MAX; |
| SwTwips nRemain = nWidthRemain; |
| SwTwips nVirtualPagesWidth = 0; |
| SwTwips nLastPageWidth = pLastPageInCurrentRow->Frm().Width() + nSidebarWidth; |
| |
| while ( ( mnColumns > 0 || nRemain > 0 ) && nNumberOfVirtualPages < nMaxNumberOfVirtualPages ) |
| { |
| SwTwips nLastPageWidthWithGap = nLastPageWidth; |
| if ( !mbBookMode || ( 0 == (nNumberOfVirtualPages + nNumberOfPagesInRow) %2) ) |
| nLastPageWidthWithGap += nGapBetweenPages; |
| |
| if ( mnColumns > 0 || nLastPageWidthWithGap < nRemain ) |
| { |
| ++nNumberOfVirtualPages; |
| nVirtualPagesWidth += nLastPageWidthWithGap; |
| } |
| nRemain = nRemain - nLastPageWidthWithGap; |
| } |
| |
| nCurrentRowWidth = nCurrentRowWidth + nVirtualPagesWidth; |
| } |
| |
| // first page in book mode is always special: |
| if ( bFirstRow && mbBookMode ) |
| { |
| // --> OD 2008-04-08 #i88036# |
| // nCurrentRowWidth += pStartOfRow->Frm().Width() + nSidebarWidth; |
| nCurrentRowWidth += |
| pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth; |
| // <-- |
| } |
| |
| // center page if possible |
| const long nSizeDiff = nVisWidth > nCurrentRowWidth ? |
| ( nVisWidth - nCurrentRowWidth ) / 2 : |
| 0; |
| |
| // adjust positions of pages in current row |
| long nX = nSizeDiff; |
| |
| const long nRowStart = nBorder + nSizeDiff; |
| const long nRowEnd = nRowStart + nCurrentRowWidth; |
| |
| if ( bFirstRow && mbBookMode ) |
| { |
| // --> OD 2008-04-08 #i88036# |
| // nX += pStartOfRow->Frm().Width() + nSidebarWidth; |
| nX += pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth; |
| // <-- |
| } |
| |
| SwPageFrm* pEndOfRow = pPageFrm; |
| SwPageFrm* pPageToAdjust = pStartOfRow; |
| |
| do |
| { |
| const SwPageFrm* pFormatPage = pPageToAdjust; |
| if ( mbBookMode ) |
| pFormatPage = &pPageToAdjust->GetFormatPage(); |
| |
| const SwTwips nCurrentPageWidth = pFormatPage->Frm().Width() + (pFormatPage->IsEmptyPage() ? 0 : nSidebarWidth); |
| const Point aOldPagePos = pPageToAdjust->Frm().Pos(); |
| const bool bLeftSidebar = pPageToAdjust->SidebarPosition() == sw::sidebarwindows::SIDEBAR_LEFT; |
| const SwTwips nLeftPageAddOffset = bLeftSidebar ? |
| nSidebarWidth : |
| 0; |
| |
| Point aNewPagePos( nBorder + nX, nBorder + nSumRowHeight ); |
| Point aNewPagePosWithLeftOffset( nBorder + nX + nLeftPageAddOffset, nBorder + nSumRowHeight ); |
| |
| // RTL view layout: Calculate mirrored page position |
| if ( bRTL ) |
| { |
| const long nXOffsetInRow = aNewPagePos.X() - nRowStart; |
| aNewPagePos.X() = nRowEnd - nXOffsetInRow - nCurrentPageWidth; |
| aNewPagePosWithLeftOffset = aNewPagePos; |
| aNewPagePosWithLeftOffset.X() += nLeftPageAddOffset; |
| } |
| |
| if ( aNewPagePosWithLeftOffset != aOldPagePos ) |
| { |
| lcl_MoveAllLowers( pPageToAdjust, aNewPagePosWithLeftOffset - aOldPagePos ); |
| pPageToAdjust->SetCompletePaint(); |
| bPageChanged = true; |
| } |
| |
| // calculate area covered by the current page and store to |
| // maPageRects. This is used e.g., for cursor setting |
| const bool bFirstColumn = pPageToAdjust == pStartOfRow; |
| const bool bLastColumn = pPageToAdjust->GetNext() == pEndOfRow; |
| const bool bLastRow = !pEndOfRow; |
| |
| nMinPageLeft = Min( nMinPageLeft, aNewPagePos.X() ); |
| nMaxPageRight = Max( nMaxPageRight, aNewPagePos.X() + nCurrentPageWidth); |
| |
| // border of nGapBetweenPages around the current page: |
| SwRect aPageRectWithBorders( aNewPagePos.X() - nGapBetweenPages, |
| aNewPagePos.Y(), |
| pPageToAdjust->Frm().SSize().Width() + nGapBetweenPages + nSidebarWidth, |
| nCurrentRowHeight ); |
| |
| static const long nOuterClickDiff = 1000000; |
| |
| // adjust borders for these special cases: |
| if ( (bFirstColumn && !bRTL) || (bLastColumn && bRTL) ) |
| aPageRectWithBorders.SubLeft( nOuterClickDiff ); |
| if ( (bLastColumn && !bRTL) || (bFirstColumn && bRTL) ) |
| aPageRectWithBorders.AddRight( nOuterClickDiff ); |
| if ( bFirstRow ) |
| aPageRectWithBorders.SubTop( nOuterClickDiff ); |
| if ( bLastRow ) |
| aPageRectWithBorders.AddBottom( nOuterClickDiff ); |
| |
| maPageRects.push_back( aPageRectWithBorders ); |
| |
| nX = nX + nCurrentPageWidth; |
| pPageToAdjust = static_cast<SwPageFrm*>(pPageToAdjust->GetNext()); |
| |
| // distance to next page |
| if ( pPageToAdjust && pPageToAdjust != pEndOfRow ) |
| { |
| // in book view, we add the x gap before left (even) pages: |
| if ( mbBookMode ) |
| { |
| if ( 0 == (pPageToAdjust->GetPhyPageNum()%2) ) |
| nX = nX + nGapBetweenPages; |
| } |
| else |
| { |
| // in non-book view, dont add x gap before |
| // 1. the last empty page in a row |
| // 2. after an empty page |
| const bool bDontAddGap = ( pPageToAdjust->IsEmptyPage() && pPageToAdjust->GetNext() == pEndOfRow ) || |
| ( static_cast<SwPageFrm*>(pPageToAdjust->GetPrev())->IsEmptyPage() ); |
| |
| if ( !bDontAddGap ) |
| nX = nX + nGapBetweenPages; |
| } |
| } |
| } |
| while ( pPageToAdjust != pEndOfRow ); |
| |
| // adjust values for root frame size |
| nSumRowHeight = nSumRowHeight + nCurrentRowHeight; |
| |
| // start new row: |
| nCurrentRowHeight = 0; |
| nCurrentRowWidth = 0; |
| pStartOfRow = pEndOfRow; |
| nWidthRemain = nVisWidth; |
| nNumberOfPagesInRow = 0; |
| bFirstRow = false; |
| } // end row finished |
| } // end while |
| |
| // set size of root frame: |
| const Size aOldSize( Frm().SSize() ); |
| const Size aNewSize( nMaxPageRight - nBorder, nSumRowHeight - nGapBetweenPages ); |
| |
| if ( bPageChanged || aNewSize != aOldSize ) |
| { |
| ChgSize( aNewSize ); |
| ::AdjustSizeChgNotify( this ); |
| Calc(); |
| |
| ViewShell* pSh = GetCurrShell(); |
| |
| if ( pSh && pSh->GetDoc()->GetDocShell() ) |
| { |
| pSh->SetFirstVisPageInvalid(); |
| if (bOldCallbackActionEnabled) |
| { |
| pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) ); |
| pSh->GetDoc()->GetDocShell()->Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED)); |
| } |
| } |
| } |
| |
| maPagesArea.Pos( Frm().Pos() ); |
| maPagesArea.SSize( aNewSize ); |
| if ( TWIPS_MAX != nMinPageLeft ) |
| maPagesArea._Left( nMinPageLeft ); |
| |
| SetCallbackActionEnabled( bOldCallbackActionEnabled ); |
| } |
| |
| bool SwRootFrm::IsLeftToRightViewLayout() const |
| { |
| // Layout direction determined by layout direction of the first page. |
| // --> OD 2008-04-08 #i88036# |
| // Only ask a non-empty page frame for its layout direction |
| // const SwPageFrm* pPage = dynamic_cast<const SwPageFrm*>(Lower()); |
| // return !pPage->IsRightToLeft() && !pPage->IsVertical(); |
| const SwPageFrm& rPage = |
| dynamic_cast<const SwPageFrm*>(Lower())->GetFormatPage(); |
| return !rPage.IsRightToLeft() && !rPage.IsVertical(); |
| // <-- |
| } |
| |
| /*const SwRect SwRootFrm::GetExtendedPageArea( sal_uInt16 nPageNumber ) const |
| { |
| SwRect aRet; |
| ASSERT( nPageNumber < maPageRects.size(), "No extended page area available" ) |
| if ( nPageNumber < maPageRects.size() ) |
| aRet = maPageRects[ nPageNumber ]; |
| return aRet; |
| }*/ |
| |
| |
| const SwPageFrm& SwPageFrm::GetFormatPage() const |
| { |
| const SwPageFrm* pRet = this; |
| if ( IsEmptyPage() ) |
| { |
| pRet = static_cast<const SwPageFrm*>( OnRightPage() ? GetNext() : GetPrev() ); |
| // --> OD 2008-04-08 #i88035# |
| // Typically a right empty page frame has a next non-empty page frame and |
| // a left empty page frame has a previous non-empty page frame. |
| // But under certain cirsumstances this assumption is not true - |
| // e.g. during insertion of a left page at the end of the document right |
| // after a left page in an intermediate state a right empty page does not |
| // have a next page frame. |
| if ( pRet == 0 ) |
| { |
| if ( OnRightPage() ) |
| { |
| pRet = static_cast<const SwPageFrm*>( GetPrev() ); |
| } |
| else |
| { |
| pRet = static_cast<const SwPageFrm*>( GetNext() ); |
| } |
| } |
| ASSERT( pRet, |
| "<SwPageFrm::GetFormatPage()> - inconsistent layout: empty page without previous and next page frame --> crash." ); |
| // <-- |
| } |
| return *pRet; |
| } |
| |