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: docdesc.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 <hintids.hxx>
34 #include <vcl/virdev.hxx>
35 #include <svx/svdmodel.hxx>
36 #include <svx/ulspitem.hxx>
37 #include <svx/lrspitem.hxx>
38 #include <svx/paperinf.hxx>
39 #include "svx/frmdiritem.hxx"
40 #include <tools/urlobj.hxx>
41 #include <sfx2/docfile.hxx>
42 #include <unotools/localedatawrapper.hxx>
43 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
44 #include <fmtfsize.hxx>
45 #include <fmthdft.hxx>
46 #include <fmtcntnt.hxx>
47 #include <fmtpdsc.hxx>
48 #include <ftninfo.hxx>
54 #include <pagefrm.hxx> //Fuer DelPageDesc
55 #include <rootfrm.hxx> //Fuer DelPageDesc
57 #include <frmtool.hxx>
58 #include <pagedesc.hxx>
59 #include <poolfmt.hxx>
63 #include <ndindex.hxx>
67 #include <fntcache.hxx>
69 #include <viewopt.hxx>
72 #include <GetMetricVal.hxx>
73 #include <svtools/syslocale.hxx>
75 #include <statstr.hrc>
78 #include <SwUndoPageDesc.hxx>
80 #include <tgrditem.hxx>
82 using namespace com::sun::star
;
84 static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId
,
88 // --> FME 2005-01-21 #i41075# Printer on demand
89 // This function does not require a printer anymore.
90 // The default page size is obtained from the application
94 SwFmtFrmSize
aFrmSize( ATT_FIX_SIZE
);
95 const Size aPhysSize
= SvxPaperInfo::GetDefaultPaperSize();
96 aFrmSize
.SetSize( aPhysSize
);
98 //Auf Default-Raender vorbereiten.
99 //Raender haben eine defaultmaessige Mindestgroesse.
100 //wenn der Drucker einen groesseren Rand vorgibt, so
101 //ist mir dass auch recht.
102 // MIB 06/25/2002, #99397#: The HTML page desc had A4 as page size
103 // always. This has been changed to take the page size from the printer.
104 // Unfortunately, the margins of the HTML page desc are smaller than
105 // the margins used here in general, so one extra case is required.
106 // In the long term, this needs to be changed to always keep the
107 // margins from the page desc.
108 sal_Int32 nMinTop
, nMinBottom
, nMinLeft
, nMinRight
;
109 if( RES_POOLPAGE_HTML
== nPoolFmtId
)
111 nMinRight
= nMinTop
= nMinBottom
= GetMetricVal( CM_1
);
112 nMinLeft
= nMinRight
* 2;
114 else if( MEASURE_METRIC
== SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() )
116 nMinTop
= nMinBottom
= nMinLeft
= nMinRight
= 1134; //2 Zentimeter
120 nMinTop
= nMinBottom
= 1440; //al la WW: 1Inch
121 nMinLeft
= nMinRight
= 1800; // 1,25 Inch
124 //Raender einstellen.
125 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
126 SvxULSpaceItem
aUL( RES_UL_SPACE
);
128 aUL
.SetUpper( (USHORT
)nMinTop
);
129 aUL
.SetLower( (USHORT
)nMinBottom
);
130 aLR
.SetRight( nMinRight
);
131 aLR
.SetLeft( nMinLeft
);
133 rFmt1
.SetFmtAttr( aFrmSize
);
134 rFmt1
.SetFmtAttr( aLR
);
135 rFmt1
.SetFmtAttr( aUL
);
137 rFmt2
.SetFmtAttr( aFrmSize
);
138 rFmt2
.SetFmtAttr( aLR
);
139 rFmt2
.SetFmtAttr( aUL
);
142 /*************************************************************************
144 |* SwDoc::ChgPageDesc()
146 |* Ersterstellung MA 25. Jan. 93
147 |* Letzte Aenderung MA 01. Mar. 95
149 |*************************************************************************/
151 void lcl_DescSetAttr( const SwFrmFmt
&rSource
, SwFrmFmt
&rDest
,
152 const BOOL bPage
= TRUE
)
154 /////////////// !!!!!!!!!!!!!!!!
156 // eigentlich sollte hier das Intersect von ItemSet benutzt werden, aber das
157 // funktioniert nicht richtig, wenn man unterschiedliche WhichRanges hat.
158 /////////////// !!!!!!!!!!!!!!!!
159 //Die interressanten Attribute uebernehmen.
160 USHORT __READONLY_DATA aIdArr
[] = { RES_FRM_SIZE
, RES_UL_SPACE
,
161 RES_BACKGROUND
, RES_SHADOW
,
163 RES_FRAMEDIR
, RES_FRAMEDIR
,
164 RES_TEXTGRID
, RES_TEXTGRID
,
165 // --> FME 2005-04-18 #i45539#
166 RES_HEADER_FOOTER_EAT_SPACING
,
167 RES_HEADER_FOOTER_EAT_SPACING
,
169 RES_UNKNOWNATR_CONTAINER
,
170 RES_UNKNOWNATR_CONTAINER
,
173 const SfxPoolItem
* pItem
;
174 for( USHORT n
= 0; aIdArr
[ n
]; n
+= 2 )
176 for( USHORT nId
= aIdArr
[ n
]; nId
<= aIdArr
[ n
+1]; ++nId
)
178 // --> FME 2005-04-18 #i45539#
180 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
182 // All in aIdArr except from RES_COL and RES_PAPER_BIN:
184 if( ( bPage
&& RES_HEADER_FOOTER_EAT_SPACING
!= nId
) ||
185 ( !bPage
&& RES_COL
!= nId
&& RES_PAPER_BIN
!= nId
))
187 if( SFX_ITEM_SET
== rSource
.GetItemState( nId
, FALSE
, &pItem
))
188 rDest
.SetFmtAttr( *pItem
);
190 rDest
.ResetFmtAttr( nId
);
195 // auch Pool-, Hilfe-Id's uebertragen
196 rDest
.SetPoolFmtId( rSource
.GetPoolFmtId() );
197 rDest
.SetPoolHelpId( rSource
.GetPoolHelpId() );
198 rDest
.SetPoolHlpFileId( rSource
.GetPoolHlpFileId() );
202 void SwDoc::ChgPageDesc( USHORT i
, const SwPageDesc
&rChged
)
204 ASSERT( i
< aPageDescs
.Count(), "PageDescs ueberindiziert." );
206 SwPageDesc
*pDesc
= aPageDescs
[i
];
208 BOOL bDoesUndo
= DoesUndo();
211 AppendUndo(new SwUndoPageDesc(*pDesc
, rChged
, this));
215 //Als erstes wird ggf. gespiegelt.
216 if ( rChged
.GetUseOn() == nsUseOnPage::PD_MIRROR
)
217 ((SwPageDesc
&)rChged
).Mirror();
219 //sonst Werte aus Master nach Left uebertragen.
220 ::lcl_DescSetAttr( ((SwPageDesc
&)rChged
).GetMaster(),
221 ((SwPageDesc
&)rChged
).GetLeft() );
223 //NumType uebernehmen.
224 if( rChged
.GetNumType().GetNumberingType() != pDesc
->GetNumType().GetNumberingType() )
226 pDesc
->SetNumType( rChged
.GetNumType() );
227 // JP 30.03.99: Bug 64121 - den Seitennummernfeldern bescheid sagen,
228 // das sich das Num-Format geaendert hat
229 GetSysFldType( RES_PAGENUMBERFLD
)->UpdateFlds();
230 GetSysFldType( RES_REFPAGEGETFLD
)->UpdateFlds();
232 // Wenn sich die Numerierungsart geaendert hat, koennte es QuoVadis/
233 // ErgoSum-Texte geben, die sich auf eine geaenderte Seite beziehen,
234 // deshalb werden die Fussnoten invalidiert
235 SwFtnIdxs
& rFtnIdxs
= GetFtnIdxs();
236 for( USHORT nPos
= 0; nPos
< rFtnIdxs
.Count(); ++nPos
)
238 SwTxtFtn
*pTxtFtn
= rFtnIdxs
[ nPos
];
239 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
240 pTxtFtn
->SetNumber( rFtn
.GetNumber(), &rFtn
.GetNumStr());
244 //Orientierung uebernehmen
245 pDesc
->SetLandscape( rChged
.GetLandscape() );
247 // #i46909# no undo if header or footer changed
248 bool bHeaderFooterChanged
= false;
251 const SwFmtHeader
&rHead
= rChged
.GetMaster().GetHeader();
254 // #i46909# no undo if header or footer changed
255 // hat sich an den Nodes etwas veraendert ?
256 const SwFmtHeader
&rOldHead
= pDesc
->GetMaster().GetHeader();
257 bHeaderFooterChanged
|=
258 ( rHead
.IsActive() != rOldHead
.IsActive() ||
259 rChged
.IsHeaderShared() != pDesc
->IsHeaderShared() );
261 pDesc
->GetMaster().SetFmtAttr( rHead
);
262 if ( rChged
.IsHeaderShared() || !rHead
.IsActive() )
264 //Left teilt sich den Header mit dem Master.
265 pDesc
->GetLeft().SetFmtAttr( pDesc
->GetMaster().GetHeader() );
267 else if ( rHead
.IsActive() )
268 { //Left bekommt einen eigenen Header verpasst wenn das Format nicht
270 //Wenn er bereits einen hat und dieser auf die gleiche Section
271 //wie der Rechte zeigt, so muss er einen eigenen bekommen. Der
272 //Inhalt wird sinnigerweise kopiert.
273 const SwFmtHeader
&rLeftHead
= pDesc
->GetLeft().GetHeader();
274 if ( !rLeftHead
.IsActive() )
276 SwFmtHeader
aHead( MakeLayoutFmt( RND_STD_HEADERL
, 0 ) );
277 pDesc
->GetLeft().SetFmtAttr( aHead
);
278 //Weitere Attribute (Raender, Umrandung...) uebernehmen.
279 ::lcl_DescSetAttr( *rHead
.GetHeaderFmt(), *aHead
.GetHeaderFmt(), FALSE
);
283 const SwFrmFmt
*pRight
= rHead
.GetHeaderFmt();
284 const SwFmtCntnt
&aRCnt
= pRight
->GetCntnt();
285 const SwFmtCntnt
&aLCnt
= rLeftHead
.GetHeaderFmt()->GetCntnt();
286 if( !aLCnt
.GetCntntIdx() )
287 pDesc
->GetLeft().SetFmtAttr( rChged
.GetLeft().GetHeader() );
288 else if( (*aRCnt
.GetCntntIdx()) == (*aLCnt
.GetCntntIdx()) )
290 SwFrmFmt
*pFmt
= new SwFrmFmt( GetAttrPool(), "Header",
292 ::lcl_DescSetAttr( *pRight
, *pFmt
, FALSE
);
293 //Der Bereich auf den das rechte Kopfattribut zeigt wird
294 //kopiert und der Index auf den StartNode in das linke
295 //Kopfattribut gehaengt.
296 SwNodeIndex
aTmp( GetNodes().GetEndOfAutotext() );
297 SwStartNode
* pSttNd
= GetNodes().MakeEmptySection( aTmp
, SwHeaderStartNode
);
298 SwNodeRange
aRange( aRCnt
.GetCntntIdx()->GetNode(), 0,
299 *aRCnt
.GetCntntIdx()->GetNode().EndOfSectionNode() );
300 aTmp
= *pSttNd
->EndOfSectionNode();
301 GetNodes()._Copy( aRange
, aTmp
, FALSE
);
303 pFmt
->SetFmtAttr( SwFmtCntnt( pSttNd
) );
304 pDesc
->GetLeft().SetFmtAttr( SwFmtHeader( pFmt
) );
307 ::lcl_DescSetAttr( *pRight
,
308 *(SwFrmFmt
*)rLeftHead
.GetHeaderFmt(), FALSE
);
312 pDesc
->ChgHeaderShare( rChged
.IsHeaderShared() );
315 const SwFmtFooter
&rFoot
= rChged
.GetMaster().GetFooter();
318 // #i46909# no undo if header or footer changed
319 // hat sich an den Nodes etwas veraendert ?
320 const SwFmtFooter
&rOldFoot
= pDesc
->GetMaster().GetFooter();
321 bHeaderFooterChanged
|=
322 ( rFoot
.IsActive() != rOldFoot
.IsActive() ||
323 rChged
.IsFooterShared() != pDesc
->IsFooterShared() );
325 pDesc
->GetMaster().SetFmtAttr( rFoot
);
326 if ( rChged
.IsFooterShared() || !rFoot
.IsActive() )
327 //Left teilt sich den Header mit dem Master.
328 pDesc
->GetLeft().SetFmtAttr( pDesc
->GetMaster().GetFooter() );
329 else if ( rFoot
.IsActive() )
330 { //Left bekommt einen eigenen Footer verpasst wenn das Format nicht
332 //Wenn er bereits einen hat und dieser auf die gleiche Section
333 //wie der Rechte zeigt, so muss er einen eigenen bekommen. Der
334 //Inhalt wird sinnigerweise kopiert.
335 const SwFmtFooter
&rLeftFoot
= pDesc
->GetLeft().GetFooter();
336 if ( !rLeftFoot
.IsActive() )
338 SwFmtFooter
aFoot( MakeLayoutFmt( RND_STD_FOOTER
, 0 ) );
339 pDesc
->GetLeft().SetFmtAttr( aFoot
);
340 //Weitere Attribute (Raender, Umrandung...) uebernehmen.
341 ::lcl_DescSetAttr( *rFoot
.GetFooterFmt(), *aFoot
.GetFooterFmt(), FALSE
);
345 const SwFrmFmt
*pRight
= rFoot
.GetFooterFmt();
346 const SwFmtCntnt
&aRCnt
= pRight
->GetCntnt();
347 const SwFmtCntnt
&aLCnt
= rLeftFoot
.GetFooterFmt()->GetCntnt();
348 if( !aLCnt
.GetCntntIdx() )
349 pDesc
->GetLeft().SetFmtAttr( rChged
.GetLeft().GetFooter() );
350 else if( (*aRCnt
.GetCntntIdx()) == (*aLCnt
.GetCntntIdx()) )
352 SwFrmFmt
*pFmt
= new SwFrmFmt( GetAttrPool(), "Footer",
354 ::lcl_DescSetAttr( *pRight
, *pFmt
, FALSE
);
355 //Der Bereich auf den das rechte Kopfattribut zeigt wird
356 //kopiert und der Index auf den StartNode in das linke
357 //Kopfattribut gehaengt.
358 SwNodeIndex
aTmp( GetNodes().GetEndOfAutotext() );
359 SwStartNode
* pSttNd
= GetNodes().MakeEmptySection( aTmp
, SwFooterStartNode
);
360 SwNodeRange
aRange( aRCnt
.GetCntntIdx()->GetNode(), 0,
361 *aRCnt
.GetCntntIdx()->GetNode().EndOfSectionNode() );
362 aTmp
= *pSttNd
->EndOfSectionNode();
363 GetNodes()._Copy( aRange
, aTmp
, FALSE
);
365 pFmt
->SetFmtAttr( SwFmtCntnt( pSttNd
) );
366 pDesc
->GetLeft().SetFmtAttr( SwFmtFooter( pFmt
) );
369 ::lcl_DescSetAttr( *pRight
,
370 *(SwFrmFmt
*)rLeftFoot
.GetFooterFmt(), FALSE
);
373 pDesc
->ChgFooterShare( rChged
.IsFooterShared() );
375 if ( pDesc
->GetName() != rChged
.GetName() )
376 pDesc
->SetName( rChged
.GetName() );
378 // Dadurch wird ein RegisterChange ausgeloest, wenn notwendig
379 pDesc
->SetRegisterFmtColl( rChged
.GetRegisterFmtColl() );
381 //Wenn sich das UseOn oder der Follow aendern muessen die
382 //Absaetze das erfahren.
384 BOOL bFollow
= FALSE
;
385 if ( pDesc
->GetUseOn() != rChged
.GetUseOn() )
386 { pDesc
->SetUseOn( rChged
.GetUseOn() );
389 if ( pDesc
->GetFollow() != rChged
.GetFollow() )
390 { if ( rChged
.GetFollow() == &rChged
)
391 { if ( pDesc
->GetFollow() != pDesc
)
392 { pDesc
->SetFollow( pDesc
);
397 { pDesc
->SetFollow( rChged
.pFollow
);
402 if ( (bUseOn
|| bFollow
) && GetRootFrm() )
403 //Layot benachrichtigen!
404 GetRootFrm()->CheckPageDescs( (SwPageFrm
*)GetRootFrm()->Lower() );
406 //Jetzt noch die Seiten-Attribute uebernehmen.
407 ::lcl_DescSetAttr( rChged
.GetMaster(), pDesc
->GetMaster() );
408 ::lcl_DescSetAttr( rChged
.GetLeft(), pDesc
->GetLeft() );
410 //Wenn sich FussnotenInfo veraendert, so werden die Seiten
412 if( !(pDesc
->GetFtnInfo() == rChged
.GetFtnInfo()) )
414 pDesc
->SetFtnInfo( rChged
.GetFtnInfo() );
415 SwMsgPoolItem
aInfo( RES_PAGEDESC_FTNINFO
);
417 SwClientIter
aIter( pDesc
->GetMaster() );
418 for( SwClient
* pLast
= aIter
.First(TYPE(SwFrm
)); pLast
;
419 pLast
= aIter
.Next() )
420 pLast
->Modify( &aInfo
, 0 );
423 SwClientIter
aIter( pDesc
->GetLeft() );
424 for( SwClient
* pLast
= aIter
.First(TYPE(SwFrm
)); pLast
;
425 pLast
= aIter
.Next() )
426 pLast
->Modify( &aInfo
, 0 );
433 // #i46909# no undo if header or footer changed
434 if( bHeaderFooterChanged
)
441 /*************************************************************************
443 |* SwDoc::DelPageDesc()
445 |* Beschreibung Alle Descriptoren, deren Follow auf den zu loeschenden
446 |* zeigen muessen angepasst werden.
447 |* Ersterstellung MA 25. Jan. 93
448 |* Letzte Aenderung JP 04.09.95
450 |*************************************************************************/
452 void lcl_RemoveFrms( SwFrmFmt
& rFmt
, BOOL
& rbFtnsRemoved
)
454 SwClientIter
aIter( rFmt
);
456 for( pFrm
= (SwFrm
*)aIter
.First(TYPE(SwFrm
)); pFrm
;
457 pFrm
= (SwFrm
*)aIter
.Next() )
458 if ( !rbFtnsRemoved
&& pFrm
->IsPageFrm() &&
459 ((SwPageFrm
*)pFrm
)->IsFtnPage() )
461 rFmt
.getIDocumentLayoutAccess()->GetRootFrm()->RemoveFtns( 0, FALSE
, TRUE
);
462 rbFtnsRemoved
= TRUE
;
472 void SwDoc::PreDelPageDesc(SwPageDesc
* pDel
)
477 SwFmtPageDesc
aDfltDesc( aPageDescs
[0] );
478 SwClientIter
aIter( *pDel
);
480 while( 0 != ( pLast
= aIter
.GoRoot() ))
482 if( pLast
->ISA( SwFmtPageDesc
) )
484 const SwModify
* pMod
= ((SwFmtPageDesc
*)pLast
)->GetDefinedIn();
487 if( pMod
->ISA( SwCntntNode
) )
488 ((SwCntntNode
*)pMod
)->SetAttr( aDfltDesc
);
489 else if( pMod
->ISA( SwFmt
))
490 ((SwFmt
*)pMod
)->SetFmtAttr( aDfltDesc
);
493 ASSERT( !this, "was ist das fuer ein Mofify-Obj?" );
494 aPageDescs
[0]->Add( pLast
);
497 else //Es kann noch eine Undo-Kopie existieren
498 aPageDescs
[0]->Add( pLast
);
501 BOOL bFtnInf
= FALSE
;
502 if ( TRUE
== (bFtnInf
= pLast
== pFtnInfo
->GetPageDescDep()) ||
503 pLast
== pEndNoteInfo
->GetPageDescDep() )
505 aPageDescs
[0]->Add( pLast
);
507 GetRootFrm()->CheckFtnPageDescs( !bFtnInf
);
511 for ( USHORT j
= 0; j
< aPageDescs
.Count(); ++j
)
513 if ( aPageDescs
[j
]->GetFollow() == pDel
)
515 aPageDescs
[j
]->SetFollow( 0 );
516 //Clients des PageDesc sind die Attribute, denen sagen wir bescheid.
517 //die Attribute wiederum reichen die Meldung an die Absaetze weiter.
519 //Layot benachrichtigen!
520 if( GetRootFrm() ) // ist nicht immer vorhanden!! (Orginizer)
521 GetRootFrm()->CheckPageDescs( (SwPageFrm
*)GetRootFrm()->Lower() );
525 if( GetRootFrm() ) // ist nicht immer vorhanden!! (Orginizer)
527 //Wenn jetzt noch irgendwelche Seiten auf die FrmFmt'e (Master und Left)
528 //Zeigen (z.B. irgendwelche Fussnotenseiten), so muessen die Seiten
531 // Wenn wir auf Endnotenseiten stossen, schmeissen wir alle Fussnoten weg,
532 // anders kann die Reihenfolge der Seiten (FollowsPageDescs usw.)
533 // nicht garantiert werden.
534 BOOL bFtnsRemoved
= FALSE
;
536 ::lcl_RemoveFrms( pDel
->GetMaster(), bFtnsRemoved
);
537 ::lcl_RemoveFrms( pDel
->GetLeft(), bFtnsRemoved
);
542 void SwDoc::BroadcastStyleOperation(String rName
, SfxStyleFamily eFamily
,
547 SfxStyleSheetBasePool
* pPool
= pDocShell
->GetStyleSheetPool();
551 pPool
->SetSearchMask(eFamily
, SFXSTYLEBIT_ALL
);
552 SfxStyleSheetBase
* pBase
= pPool
->Find(rName
);
555 pPool
->Broadcast(SfxStyleSheetHint( nOp
, *pBase
));
560 void SwDoc::DelPageDesc( USHORT i
, BOOL bBroadcast
)
562 ASSERT( i
< aPageDescs
.Count(), "PageDescs ueberindiziert." );
563 ASSERT( i
!= 0, "Default Pagedesc loeschen is nicht." );
567 SwPageDesc
*pDel
= aPageDescs
[i
];
571 BroadcastStyleOperation(pDel
->GetName(), SFX_STYLE_FAMILY_PAGE
,
572 SFX_STYLESHEET_ERASED
);
577 AppendUndo(new SwUndoPageDescDelete(*pDel
, this));
580 PreDelPageDesc(pDel
); // #i7983#
582 aPageDescs
.Remove( i
);
589 /*************************************************************************
591 |* SwDoc::MakePageDesc()
593 |* Ersterstellung MA 25. Jan. 93
594 |* Letzte Aenderung MA 20. Aug. 93
596 |*************************************************************************/
598 USHORT
SwDoc::MakePageDesc( const String
&rName
, const SwPageDesc
*pCpy
,
599 BOOL bRegardLanguage
, BOOL bBroadcast
) // #116530#
604 pNew
= new SwPageDesc( *pCpy
);
605 pNew
->SetName( rName
);
606 if( rName
!= pCpy
->GetName() )
608 pNew
->SetPoolFmtId( USHRT_MAX
);
609 pNew
->SetPoolHelpId( USHRT_MAX
);
610 pNew
->SetPoolHlpFileId( UCHAR_MAX
);
615 pNew
= new SwPageDesc( rName
, GetDfltFrmFmt(), this );
616 //Default-Seitenformat einstellen.
617 lcl_DefaultPageFmt( USHRT_MAX
, pNew
->GetMaster(), pNew
->GetLeft() );
619 SvxFrameDirection aFrameDirection
= bRegardLanguage
?
620 GetDefaultFrameDirection(GetAppLanguage())
621 : FRMDIR_HORI_LEFT_TOP
;
623 pNew
->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection
, RES_FRAMEDIR
) );
624 pNew
->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection
, RES_FRAMEDIR
) );
626 aPageDescs
.Insert( pNew
, aPageDescs
.Count() );
630 BroadcastStyleOperation(rName
, SFX_STYLE_FAMILY_PAGE
,
631 SFX_STYLESHEET_CREATED
);
635 AppendUndo(new SwUndoPageDescCreate(pNew
, this)); // #116530#
638 return (aPageDescs
.Count()-1);
641 SwPageDesc
* SwDoc::FindPageDescByName( const String
& rName
, USHORT
* pPos
) const
643 SwPageDesc
* pRet
= 0;
644 if( pPos
) *pPos
= USHRT_MAX
;
646 for( USHORT n
= 0, nEnd
= aPageDescs
.Count(); n
< nEnd
; ++n
)
647 if( aPageDescs
[ n
]->GetName() == rName
)
649 pRet
= aPageDescs
[ n
];
657 /******************************************************************************
658 * Methode : void SwDoc::PrtDataChanged()
660 * Erstellt : OK 27.10.94 10:20
661 * Aenderung : MA 26. Mar. 98
662 ******************************************************************************/
664 void SwDoc::PrtDataChanged()
666 //!!!!!!!! Bei Aenderungen hier bitte ggf. InJobSetup im Sw3io mitpflegen
668 // --> FME 2005-01-21 #i41075#
669 ASSERT( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE
) ||
670 0 != getPrinter( sal_False
), "PrtDataChanged will be called recursive!" )
674 BOOL bEndAction
= FALSE
;
677 GetDocShell()->UpdateFontList();
682 ViewShell
*pSh
= GetRootFrm()->GetCurrShell();
683 if( !get(IDocumentSettingAccess::BROWSE_MODE
) ||
684 ( pSh
&& pSh
->GetViewOptions()->IsPrtFormat() ) )
687 pWait
= new SwWait( *GetDocShell(), TRUE
);
689 GetRootFrm()->StartAllAction();
695 pDrawModel
->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING
) );
696 pDrawModel
->SetRefDevice( getReferenceDevice( false ) );
700 GetRootFrm()->InvalidateAllCntnt();
706 pSh
->InitPrt( pPrt
);
707 pSh
= (ViewShell
*)pSh
->GetNext();
709 while ( pSh
!= GetRootFrm()->GetCurrShell() );
714 if ( bDraw
&& pDrawModel
)
716 const sal_Bool bTmpAddExtLeading
= get(IDocumentSettingAccess::ADD_EXT_LEADING
);
717 if ( bTmpAddExtLeading
!= pDrawModel
->IsAddExtLeading() )
718 pDrawModel
->SetAddExtLeading( bTmpAddExtLeading
);
720 OutputDevice
* pOutDev
= getReferenceDevice( false );
721 if ( pOutDev
!= pDrawModel
->GetRefDevice() )
722 pDrawModel
->SetRefDevice( pOutDev
);
725 PrtOLENotify( TRUE
);
728 GetRootFrm()->EndAllAction();
732 //Zur Laufzeit sammeln wir die GlobalNames der Server, die keine
733 //Benachrichtigung zu Druckerwechseln wuenschen. Dadurch sparen wir
734 //das Laden vieler Objekte (gluecklicherweise werden obendrein alle
735 //Fremdobjekte unter einer ID abgebuildet). Init und DeInit vom Array
736 //ist in init.cxx zu finden.
737 extern SvPtrarr
*pGlobalOLEExcludeList
;
739 void SwDoc::PrtOLENotify( BOOL bAll
)
741 SwFEShell
*pShell
= 0;
742 if ( GetRootFrm() && GetRootFrm()->GetCurrShell() )
744 ViewShell
*pSh
= GetRootFrm()->GetCurrShell();
745 if ( !pSh
->ISA(SwFEShell
) )
747 { pSh
= (ViewShell
*)pSh
->GetNext();
748 } while ( !pSh
->ISA(SwFEShell
) &&
749 pSh
!= GetRootFrm()->GetCurrShell() );
751 if ( pSh
->ISA(SwFEShell
) )
752 pShell
= (SwFEShell
*)pSh
;
756 //Das hat ohne Shell und damit ohne Client keinen Sinn, weil nur darueber
757 //die Kommunikation bezueglich der Groessenaenderung implementiert ist.
758 //Da wir keine Shell haben, merken wir uns diesen unguenstigen
759 //Zustand am Dokument, dies wird dann beim Erzeugen der ersten Shell
761 mbOLEPrtNotifyPending
= TRUE
;
763 mbAllOLENotify
= TRUE
;
767 if ( mbAllOLENotify
)
770 mbOLEPrtNotifyPending
= mbAllOLENotify
= FALSE
;
773 SwOLENodes
*pNodes
= 0;
774 SwClientIter
aIter( *(SwModify
*)GetDfltGrfFmtColl() );
775 for( SwCntntNode
* pNd
= (SwCntntNode
*)aIter
.First( TYPE( SwCntntNode
) );
777 pNd
= (SwCntntNode
*)aIter
.Next() )
780 if ( 0 != (pONd
= pNd
->GetOLENode()) &&
781 (bAll
|| pONd
->IsOLESizeInvalid()) )
784 pNodes
= new SwOLENodes
;
785 pNodes
->Insert( pONd
, pNodes
->Count() );
791 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY
,
792 0, pNodes
->Count(), GetDocShell());
793 GetRootFrm()->StartAllAction();
795 for( USHORT i
= 0; i
< pNodes
->Count(); ++i
)
797 ::SetProgressState( i
, GetDocShell() );
799 SwOLENode
* pOLENd
= (*pNodes
)[i
];
800 pOLENd
->SetOLESizeInvalid( FALSE
);
802 //Ersteinmal die Infos laden und festellen ob das Teil nicht
803 //schon in der Exclude-Liste steht
806 svt::EmbeddedObjectRef
& xObj
= pOLENd
->GetOLEObj().GetObject();
808 aName
= SvGlobalName( xObj
->getClassID() );
809 else //Noch nicht geladen
811 // TODO/LATER: retrieve ClassID of an unloaded object
817 j
< pGlobalOLEExcludeList
->Count() && !bFound
;
820 bFound
= *(SvGlobalName
*)(*pGlobalOLEExcludeList
)[j
] ==
826 //Kennen wir nicht, also muss das Objekt geladen werden.
827 //Wenn es keine Benachrichtigung wuenscht
830 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange
832 if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus())
834 if ( pOLENd->GetFrm() )
836 xObj->OnDocumentPrinterChanged( pPrt );
837 pShell->CalcAndSetScale( xObj );//Client erzeugen lassen.
840 pOLENd->SetOLESizeInvalid( TRUE );
843 pGlobalOLEExcludeList
->Insert(
844 new SvGlobalName( aName
),
845 pGlobalOLEExcludeList
->Count() );
849 GetRootFrm()->EndAllAction();
850 ::EndProgress( GetDocShell() );
855 IMPL_LINK( SwDoc
, DoUpdateModifiedOLE
, Timer
*, )
857 SwFEShell
* pSh
= (SwFEShell
*)GetEditShell();
860 mbOLEPrtNotifyPending
= mbAllOLENotify
= FALSE
;
862 SwOLENodes aOLENodes
;
863 SwClientIter
aIter( *(SwModify
*)GetDfltGrfFmtColl() );
864 for( SwCntntNode
* pNd
= (SwCntntNode
*)aIter
.First( TYPE( SwCntntNode
) );
866 pNd
= (SwCntntNode
*)aIter
.Next() )
868 SwOLENode
*pONd
= pNd
->GetOLENode();
869 if( pONd
&& pONd
->IsOLESizeInvalid() )
871 aOLENodes
.Insert( pONd
, aOLENodes
.Count() );
875 if( aOLENodes
.Count() )
877 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY
,
878 0, aOLENodes
.Count(), GetDocShell());
879 GetRootFrm()->StartAllAction();
880 SwMsgPoolItem
aMsgHint( RES_UPDATE_ATTR
);
882 for( USHORT i
= 0; i
< aOLENodes
.Count(); ++i
)
884 ::SetProgressState( i
, GetDocShell() );
886 SwOLENode
* pOLENd
= aOLENodes
[i
];
887 pOLENd
->SetOLESizeInvalid( FALSE
);
889 //Kennen wir nicht, also muss das Objekt geladen werden.
890 //Wenn es keine Benachrichtigung wuenscht
891 if( pOLENd
->GetOLEObj().GetOleRef().is() ) //Kaputt?
893 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange
895 if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE &
896 xRef->GetMiscStatus() )
898 if( pOLENd->GetFrm() )
900 xRef->OnDocumentPrinterChanged( pPrt );
901 pSh->CalcAndSetScale( xRef );//Client erzeugen lassen.
904 pOLENd->SetOLESizeInvalid( TRUE );
907 pOLENd
->Modify( &aMsgHint
, &aMsgHint
);
910 GetRootFrm()->EndAllAction();
911 ::EndProgress( GetDocShell() );
917 BOOL
SwDoc::FindPageDesc( const String
& rName
, sal_uInt16
* pFound
)
919 BOOL bResult
= FALSE
;
921 for (nI
= 0; nI
< aPageDescs
.Count(); nI
++)
923 if (aPageDescs
[nI
]->GetName() == rName
)
934 SwPageDesc
* SwDoc::GetPageDesc( const String
& rName
)
936 SwPageDesc
* aResult
= NULL
;
940 if (FindPageDesc(rName
, &nI
))
941 aResult
= aPageDescs
[nI
];
946 void SwDoc::DelPageDesc( const String
& rName
, BOOL bBroadcast
) // #116530#
950 if (FindPageDesc(rName
, &nI
))
951 DelPageDesc(nI
, bBroadcast
); // #116530#
954 void SwDoc::ChgPageDesc( const String
& rName
, const SwPageDesc
& rDesc
)
958 if (FindPageDesc(rName
, &nI
))
959 ChgPageDesc(nI
, rDesc
);
963 * The HTML import cannot resist changing the page descriptions, I don't
964 * know why. This function is meant to check the page descriptors for invalid
967 void SwDoc::CheckDefaultPageFmt()
969 for ( USHORT i
= 0; i
< GetPageDescCnt(); ++i
)
971 SwPageDesc
& rDesc
= _GetPageDesc( i
);
973 SwFrmFmt
& rMaster
= rDesc
.GetMaster();
974 SwFrmFmt
& rLeft
= rDesc
.GetLeft();
976 const SwFmtFrmSize
& rMasterSize
= rMaster
.GetFrmSize();
977 const SwFmtFrmSize
& rLeftSize
= rLeft
.GetFrmSize();
979 const bool bSetSize
= LONG_MAX
== rMasterSize
.GetWidth() ||
980 LONG_MAX
== rMasterSize
.GetHeight() ||
981 LONG_MAX
== rLeftSize
.GetWidth() ||
982 LONG_MAX
== rLeftSize
.GetHeight();
985 lcl_DefaultPageFmt( rDesc
.GetPoolFmtId(), rDesc
.GetMaster(), rDesc
.GetLeft() );
989 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode
)
991 if( !bSquaredPageMode
== !IsSquaredPageMode() )
994 const SwTextGridItem
& rGrid
=
995 (const SwTextGridItem
&)GetDefault( RES_TEXTGRID
);
996 SwTextGridItem aNewGrid
= rGrid
;
997 aNewGrid
.SetSquaredMode(bSquaredPageMode
);
999 SetDefault(aNewGrid
);
1001 for ( USHORT i
= 0; i
< GetPageDescCnt(); ++i
)
1003 SwPageDesc
& rDesc
= _GetPageDesc( i
);
1005 SwFrmFmt
& rMaster
= rDesc
.GetMaster();
1006 SwFrmFmt
& rLeft
= rDesc
.GetLeft();
1008 SwTextGridItem
aGrid((SwTextGridItem
&)rMaster
.GetFmtAttr(RES_TEXTGRID
));
1009 aGrid
.SwitchPaperMode( bSquaredPageMode
);
1010 rMaster
.SetFmtAttr(aGrid
);
1011 rLeft
.SetFmtAttr(aGrid
);
1015 sal_Bool
SwDoc::IsSquaredPageMode() const
1017 const SwTextGridItem
& rGrid
=
1018 (const SwTextGridItem
&)GetDefault( RES_TEXTGRID
);
1019 return rGrid
.IsSquaredMode();