1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: newfrm.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdpage.hxx>
35 #include <fmtfordr.hxx>
36 #include <fmtpdsc.hxx>
38 #include <swtable.hxx>
39 #include <rootfrm.hxx>
40 #include <pagefrm.hxx>
45 #include <dflyobj.hxx>
46 #include <frmtool.hxx>
47 #include <virtoutp.hxx>
49 #include <ndindex.hxx>
50 #include <sectfrm.hxx>
51 #include <notxtfrm.hxx>
52 #include <pagedesc.hxx>
53 #include "viewimp.hxx"
54 #include "IDocumentTimerAccess.hxx"
55 #include "IDocumentLayoutAccess.hxx"
56 #include "IDocumentFieldsAccess.hxx"
57 #include "IDocumentSettingAccess.hxx"
58 #include "IDocumentDrawModelAccess.hxx"
60 #include <viewopt.hxx>
62 SwLayVout
*SwRootFrm::pVout
= 0;
63 BOOL
SwRootFrm::bInPaint
= FALSE
;
64 BOOL
SwRootFrm::bNoVirDev
= FALSE
;
66 SwCache
*SwFrm::pCache
= 0;
68 long FirstMinusSecond( long nFirst
, long nSecond
)
69 { return nFirst
- nSecond
; }
70 long SecondMinusFirst( long nFirst
, long nSecond
)
71 { return nSecond
- nFirst
; }
72 long SwIncrement( long nA
, long nAdd
)
74 long SwDecrement( long nA
, long nSub
)
77 static SwRectFnCollection aHorizontal
= {
105 &SwFrm::GetTopMargin
,
106 &SwFrm::GetBottomMargin
,
107 &SwFrm::GetLeftMargin
,
108 &SwFrm::GetRightMargin
,
109 &SwFrm::SetLeftRightMargins
,
110 &SwFrm::SetTopBottomMargins
,
112 &SwFrm::GetPrtBottom
,
115 &SwRect::GetTopDistance
,
116 &SwRect::GetBottomDistance
,
117 &SwRect::GetLeftDistance
,
118 &SwRect::GetRightDistance
,
119 &SwFrm::SetMaxBottom
,
120 &SwRect::OverStepBottom
,
122 &SwRect::SetUpperLeftCorner
,
123 &SwFrm::MakeBelowPos
,
128 &SwRect::SetLeftAndWidth
,
129 &SwRect::SetTopAndHeight
132 static SwRectFnCollection aVertical
= {
141 &SwRect::SwappedSize
,
160 &SwFrm::GetRightMargin
,
161 &SwFrm::GetLeftMargin
,
162 &SwFrm::GetTopMargin
,
163 &SwFrm::GetBottomMargin
,
164 &SwFrm::SetTopBottomMargins
,
165 &SwFrm::SetRightLeftMargins
,
169 &SwFrm::GetPrtBottom
,
170 &SwRect::GetRightDistance
,
171 &SwRect::GetLeftDistance
,
172 &SwRect::GetTopDistance
,
173 &SwRect::GetBottomDistance
,
175 &SwRect::OverStepLeft
,
177 &SwRect::SetUpperRightCorner
,
183 &SwRect::SetTopAndHeight
,
184 &SwRect::SetRightAndWidth
187 static SwRectFnCollection aBottomToTop
= {
215 &SwFrm::GetBottomMargin
,
216 &SwFrm::GetTopMargin
,
217 &SwFrm::GetLeftMargin
,
218 &SwFrm::GetRightMargin
,
219 &SwFrm::SetLeftRightMargins
,
220 &SwFrm::SetBottomTopMargins
,
221 &SwFrm::GetPrtBottom
,
225 &SwRect::GetBottomDistance
,
226 &SwRect::GetTopDistance
,
227 &SwRect::GetLeftDistance
,
228 &SwRect::GetRightDistance
,
230 &SwRect::OverStepTop
,
232 &SwRect::SetLowerLeftCorner
,
233 &SwFrm::MakeUpperPos
,
238 &SwRect::SetLeftAndWidth
,
239 &SwRect::SetBottomAndHeight
242 static SwRectFnCollection aVerticalRightToLeft
= {
250 &SwRect::BottomRight
,
251 &SwRect::SwappedSize
,
270 &SwFrm::GetLeftMargin
,
271 &SwFrm::GetRightMargin
,
272 &SwFrm::GetTopMargin
,
273 &SwFrm::GetBottomMargin
,
274 &SwFrm::SetTopBottomMargins
,
275 &SwFrm::SetLeftRightMargins
,
278 &SwFrm::GetPrtBottom
,
280 &SwRect::GetLeftDistance
,
281 &SwRect::GetRightDistance
,
282 &SwRect::GetBottomDistance
,
283 &SwRect::GetTopDistance
,
285 &SwRect::OverStepRight
,
287 &SwRect::SetLowerLeftCorner
,
288 &SwFrm::MakeRightPos
,
293 &SwRect::SetBottomAndHeight
,
294 &SwRect::SetLeftAndWidth
297 SwRectFn fnRectHori
= &aHorizontal
;
298 SwRectFn fnRectVert
= &aVertical
;
299 SwRectFn fnRectB2T
= &aBottomToTop
;
300 SwRectFn fnRectVL2R
= &aVerticalRightToLeft
;
302 // --> OD 2006-05-10 #i65250#
303 sal_uInt32
SwFrm::mnLastFrmId
=0;
306 TYPEINIT1(SwFrm
,SwClient
); //rtti fuer SwFrm
307 TYPEINIT1(SwCntntFrm
,SwFrm
); //rtti fuer SwCntntFrm
312 SwRootFrm::pVout
= new SwLayVout();
313 SwCache
*pNew
= new SwCache( 100, 100
315 , "static SwBorderAttrs::pCache"
318 SwFrm::SetCache( pNew
);
326 // im Chache duerfen nur noch 0-Pointer stehen
327 for( USHORT n
= SwFrm::GetCachePtr()->Count(); n
; )
328 if( (*SwFrm::GetCachePtr())[ --n
] )
330 SwCacheObj
* pObj
= (*SwFrm::GetCachePtr())[ n
];
331 ASSERT( !pObj
, "Wer hat sich nicht ausgetragen?")
334 delete SwRootFrm::pVout
;
335 delete SwFrm::GetCachePtr();
338 /*************************************************************************
340 |* RootFrm::Alles was so zur CurrShell gehoert
342 |* Ersterstellung MA 09. Sep. 98
343 |* Letzte Aenderung MA 18. Feb. 99
345 |*************************************************************************/
347 typedef CurrShell
* CurrShellPtr
;
348 SV_DECL_PTRARR_SORT(SwCurrShells
,CurrShellPtr
,4,4)
349 SV_IMPL_PTRARR_SORT(SwCurrShells
,CurrShellPtr
)
351 CurrShell::CurrShell( ViewShell
*pNew
)
353 ASSERT( pNew
, "0-Shell einsetzen?" );
354 pRoot
= pNew
->GetLayout();
357 pPrev
= pRoot
->pCurrShell
;
358 pRoot
->pCurrShell
= pNew
;
359 pRoot
->pCurrShells
->Insert( this );
365 CurrShell::~CurrShell()
369 pRoot
->pCurrShells
->Remove( this );
371 pRoot
->pCurrShell
= pPrev
;
372 if ( !pRoot
->pCurrShells
->Count() && pRoot
->pWaitingCurrShell
)
374 pRoot
->pCurrShell
= pRoot
->pWaitingCurrShell
;
375 pRoot
->pWaitingCurrShell
= 0;
380 void SetShell( ViewShell
*pSh
)
382 SwRootFrm
*pRoot
= pSh
->GetLayout();
383 if ( !pRoot
->pCurrShells
->Count() )
384 pRoot
->pCurrShell
= pSh
;
386 pRoot
->pWaitingCurrShell
= pSh
;
389 void SwRootFrm::DeRegisterShell( ViewShell
*pSh
)
391 //Wenn moeglich irgendeine Shell aktivieren
392 if ( pCurrShell
== pSh
)
393 pCurrShell
= pSh
->GetNext() != pSh
? (ViewShell
*)pSh
->GetNext() : 0;
395 //Das hat sich eruebrigt
396 if ( pWaitingCurrShell
== pSh
)
397 pWaitingCurrShell
= 0;
399 //Referenzen entfernen.
400 for ( USHORT i
= 0; i
< pCurrShells
->Count(); ++i
)
402 CurrShell
*pC
= (*pCurrShells
)[i
];
403 if (pC
->pPrev
== pSh
)
408 void InitCurrShells( SwRootFrm
*pRoot
)
410 pRoot
->pCurrShells
= new SwCurrShells
;
414 /*************************************************************************
416 |* SwRootFrm::SwRootFrm()
419 |* Der RootFrm laesst sich grundsaetzlich vom Dokument ein eigenes
420 |* FrmFmt geben. Dieses loescht er dann selbst im DTor.
421 |* Das eigene FrmFmt wird vom uebergebenen Format abgeleitet.
422 |* Ersterstellung SS 05-Apr-1991
423 |* Letzte Aenderung MA 12. Dec. 94
425 |*************************************************************************/
428 SwRootFrm::SwRootFrm( SwFrmFmt
*pFmt
, ViewShell
* pSh
) :
429 SwLayoutFrm( pFmt
->GetDoc()->MakeFrmFmt(
430 XubString( "Root", RTL_TEXTENCODING_MS_1252
), pFmt
) ),
436 mbSidebarChanged( false ),
437 mbNeedGrammarCheck( false ),
439 nBrowseWidth( MM50
*4 ), //2cm Minimum
443 pWaitingCurrShell( 0 ),
447 nAccessibleShells( 0 )
450 bIdleFormat
= bTurboAllowed
= bAssertFlyPages
= bIsNewLayout
= TRUE
;
451 bCheckSuperfluous
= bBrowseWidthValid
= FALSE
;
453 InitCurrShells( this );
455 IDocumentTimerAccess
*pTimerAccess
= pFmt
->getIDocumentTimerAccess();
456 IDocumentLayoutAccess
*pLayoutAccess
= pFmt
->getIDocumentLayoutAccess();
457 IDocumentFieldsAccess
*pFieldsAccess
= pFmt
->getIDocumentFieldsAccess();
458 const IDocumentSettingAccess
*pSettingAccess
= pFmt
->getIDocumentSettingAccess();
459 pTimerAccess
->StopIdling();
460 pLayoutAccess
->SetRootFrm( this ); //Fuer das Erzeugen der Flys durch MakeFrms()
461 bCallbackActionEnabled
= FALSE
; //vor Verlassen auf TRUE setzen!
463 SdrModel
*pMd
= pFmt
->getIDocumentDrawModelAccess()->GetDrawModel();
467 pDrawPage
= pMd
->GetPage( 0 );
468 pDrawPage
->SetSize( Frm().SSize() );
471 //Initialisierung des Layouts: Seiten erzeugen. Inhalt mit cntnt verbinden
473 //Zuerst einiges initialiseren und den ersten Node besorgen (der wird
474 //fuer den PageDesc benoetigt).
476 SwDoc
* pDoc
= pFmt
->GetDoc();
477 SwNodeIndex
aIndex( *pDoc
->GetNodes().GetEndOfContent().StartOfSectionNode() );
478 SwCntntNode
*pNode
= pDoc
->GetNodes().GoNextSection( &aIndex
, TRUE
, FALSE
);
479 // --> FME 2005-05-25 #123067# pNode = 0 can really happen:
480 SwTableNode
*pTblNd
= pNode
? pNode
->FindTableNode() : 0;
483 //PageDesc besorgen (entweder vom FrmFmt des ersten Node oder den
485 SwPageDesc
*pDesc
= 0;
490 const SwFmtPageDesc
&rDesc
= pTblNd
->GetTable().GetFrmFmt()->GetPageDesc();
491 pDesc
= (SwPageDesc
*)rDesc
.GetPageDesc();
492 //#19104# Seitennummeroffset beruecksictigen!!
493 bIsVirtPageNum
= 0 != ( nPgNum
= rDesc
.GetNumOffset() );
497 const SwFmtPageDesc
&rDesc
= pNode
->GetSwAttrSet().GetPageDesc();
498 pDesc
= (SwPageDesc
*)rDesc
.GetPageDesc();
499 //#19104# Seitennummeroffset beruecksictigen!!
500 bIsVirtPageNum
= 0 != ( nPgNum
= rDesc
.GetNumOffset() );
503 bIsVirtPageNum
= FALSE
;
505 pDesc
= (SwPageDesc
*)
506 &const_cast<const SwDoc
*>(pDoc
)->GetPageDesc( 0 );
507 const BOOL bOdd
= !nPgNum
|| 0 != ( nPgNum
% 2 );
509 //Eine Seite erzeugen und in das Layout stellen
510 SwPageFrm
*pPage
= ::InsertNewPage( *pDesc
, this, bOdd
, FALSE
, FALSE
, 0 );
512 //Erstes Blatt im Bodytext-Bereich suchen.
513 SwLayoutFrm
*pLay
= pPage
->FindBodyCont();
514 while( pLay
->Lower() )
515 pLay
= (SwLayoutFrm
*)pLay
->Lower();
517 SwNodeIndex
aTmp( *pDoc
->GetNodes().GetEndOfContent().StartOfSectionNode(), 1 );
518 ::_InsertCnt( pLay
, pDoc
, aTmp
.GetIndex(), TRUE
);
519 //Noch nicht ersetzte Master aus der Liste entfernen.
520 RemoveMasterObjs( pDrawPage
);
521 if( pSettingAccess
->get(IDocumentSettingAccess::GLOBAL_DOCUMENT
) )
522 pFieldsAccess
->UpdateRefFlds( NULL
);
523 //b6433357: Update page fields after loading
525 if ( !pCurrShell
|| !pCurrShell
->Imp()->IsUpdateExpFlds() )
527 SwDocPosUpdate
aMsgHnt( pPage
->Frm().Top() );
528 pFieldsAccess
->UpdatePageFlds( &aMsgHnt
);
532 pTimerAccess
->StartIdling();
533 bCallbackActionEnabled
= TRUE
;
535 ViewShell
*pViewSh
= GetCurrShell();
537 mbNeedGrammarCheck
= pViewSh
->GetViewOptions()->IsOnlineSpell();
540 /*************************************************************************
542 |* SwRootFrm::~SwRootFrm()
544 |* Ersterstellung SS 05-Apr-1991
545 |* Letzte Aenderung MA 12. Dec. 94
547 |*************************************************************************/
551 SwRootFrm::~SwRootFrm()
553 bTurboAllowed
= FALSE
;
556 pBlink
->FrmDelete( this );
557 ((SwFrmFmt
*)pRegisteredIn
)->GetDoc()->DelFrmFmt( (SwFrmFmt
*)pRegisteredIn
);
560 //Referenzen entfernen.
561 for ( USHORT i
= 0; i
< pCurrShells
->Count(); ++i
)
562 (*pCurrShells
)[i
]->pRoot
= 0;
566 ASSERT( 0==nAccessibleShells
, "Some accessible shells are left" );
569 /*************************************************************************
571 |* SwRootFrm::RemoveMasterObjs()
573 |* Ersterstellung MA 19.10.95
574 |* Letzte Aenderung MA 19.10.95
576 |*************************************************************************/
579 void SwRootFrm::RemoveMasterObjs( SdrPage
*pPg
)
581 //Alle Masterobjekte aus der Page entfernen. Nicht loeschen!!
582 for( ULONG i
= pPg
? pPg
->GetObjCount() : 0; i
; )
584 SdrObject
* pObj
= pPg
->GetObj( --i
);
585 if( pObj
->ISA(SwFlyDrawObj
) )
586 pPg
->RemoveObject( i
);