1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svx/svdmodel.hxx>
22 #include <editeng/ulspitem.hxx>
23 #include <editeng/paperinf.hxx>
24 #include "editeng/frmdiritem.hxx"
25 #include <sfx2/printer.hxx>
26 #include <fmtfsize.hxx>
27 #include <fmthdft.hxx>
28 #include <fmtcntnt.hxx>
29 #include <ftninfo.hxx>
34 #include <IDocumentUndoRedo.hxx>
36 #include <rootfrm.hxx> //For DelPageDesc
37 #include <frmtool.hxx>
38 #include <poolfmt.hxx>
43 #include <fntcache.hxx>
44 #include <viewopt.hxx>
47 #include <GetMetricVal.hxx>
48 #include <statstr.hrc>
50 #include <SwUndoPageDesc.hxx>
51 #include <pagedeschint.hxx>
52 #include <tgrditem.hxx>
54 using namespace com::sun::star
;
56 static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId
,
61 // --> #i41075# Printer on demand
62 // This function does not require a printer anymore.
63 // The default page size is obtained from the application
66 SwFmtFrmSize
aFrmSize( ATT_FIX_SIZE
);
67 const Size aPhysSize
= SvxPaperInfo::GetDefaultPaperSize();
68 aFrmSize
.SetSize( aPhysSize
);
70 // Prepare for default margins.
71 // Margins have a default minimum size.
72 // If the printer forces a larger margins, that's ok too.
73 // The HTML page desc had A4 as page size always.
74 // This has been changed to take the page size from the printer.
75 // Unfortunately, the margins of the HTML page desc are smaller than
76 // the margins used here in general, so one extra case is required.
77 // In the long term, this needs to be changed to always keep the
78 // margins from the page desc.
79 sal_Int32 nMinTop
, nMinBottom
, nMinLeft
, nMinRight
;
80 if( RES_POOLPAGE_HTML
== nPoolFmtId
)
82 nMinRight
= nMinTop
= nMinBottom
= GetMetricVal( CM_1
);
83 nMinLeft
= nMinRight
* 2;
85 else if( MEASURE_METRIC
== SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() )
87 nMinTop
= nMinBottom
= nMinLeft
= nMinRight
= 1134; // 2 centimetres
91 nMinTop
= nMinBottom
= 1440; // as in MS Word: 1 Inch
92 nMinLeft
= nMinRight
= 1800; // 1,25 Inch
96 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
97 SvxULSpaceItem
aUL( RES_UL_SPACE
);
99 aUL
.SetUpper( (sal_uInt16
)nMinTop
);
100 aUL
.SetLower( (sal_uInt16
)nMinBottom
);
101 aLR
.SetRight( nMinRight
);
102 aLR
.SetLeft( nMinLeft
);
104 rFmt1
.SetFmtAttr( aFrmSize
);
105 rFmt1
.SetFmtAttr( aLR
);
106 rFmt1
.SetFmtAttr( aUL
);
108 rFmt2
.SetFmtAttr( aFrmSize
);
109 rFmt2
.SetFmtAttr( aLR
);
110 rFmt2
.SetFmtAttr( aUL
);
112 rFmt3
.SetFmtAttr( aFrmSize
);
113 rFmt3
.SetFmtAttr( aLR
);
114 rFmt3
.SetFmtAttr( aUL
);
117 /*************************************************************************
119 |* SwDoc::ChgPageDesc()
121 |*************************************************************************/
123 static void lcl_DescSetAttr( const SwFrmFmt
&rSource
, SwFrmFmt
&rDest
,
124 const bool bPage
= true )
126 // We should actually use ItemSet's Intersect here, but that doesn't work
127 // correctly if we have different WhichRanges.
129 // Take over the attributes which are of interest.
130 sal_uInt16
const aIdArr
[] = { RES_FRM_SIZE
, RES_UL_SPACE
,
131 RES_BACKGROUND
, RES_SHADOW
,
133 RES_FRAMEDIR
, RES_FRAMEDIR
,
134 RES_TEXTGRID
, RES_TEXTGRID
,
136 RES_HEADER_FOOTER_EAT_SPACING
,
137 RES_HEADER_FOOTER_EAT_SPACING
,
138 RES_UNKNOWNATR_CONTAINER
,
139 RES_UNKNOWNATR_CONTAINER
,
142 const SfxPoolItem
* pItem
;
143 for( sal_uInt16 n
= 0; aIdArr
[ n
]; n
+= 2 )
145 for( sal_uInt16 nId
= aIdArr
[ n
]; nId
<= aIdArr
[ n
+1]; ++nId
)
149 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
151 // All in aIdArr except from RES_COL and RES_PAPER_BIN:
152 if( ( bPage
&& RES_HEADER_FOOTER_EAT_SPACING
!= nId
) ||
153 ( !bPage
&& RES_COL
!= nId
&& RES_PAPER_BIN
!= nId
))
155 if( SFX_ITEM_SET
== rSource
.GetItemState( nId
, sal_False
, &pItem
))
156 rDest
.SetFmtAttr( *pItem
);
158 rDest
.ResetFmtAttr( nId
);
163 // Transmit pool and help IDs too
164 rDest
.SetPoolFmtId( rSource
.GetPoolFmtId() );
165 rDest
.SetPoolHelpId( rSource
.GetPoolHelpId() );
166 rDest
.SetPoolHlpFileId( rSource
.GetPoolHlpFileId() );
169 void SwDoc::CopyMasterHeader(const SwPageDesc
&rChged
, const SwFmtHeader
&rHead
, SwPageDesc
*pDesc
, bool bLeft
)
171 SwFrmFmt
& rDescFrmFmt
= (bLeft
? pDesc
->GetLeft() : pDesc
->GetFirst());
172 if ( (bLeft
? rChged
.IsHeaderShared() : rChged
.IsFirstShared() ) || !rHead
.IsActive() )
174 // Left or first shares the header with the Master.
175 rDescFrmFmt
.SetFmtAttr( pDesc
->GetMaster().GetHeader() );
177 else if ( rHead
.IsActive() )
178 { // Left or first gets its own header if the Format doesn't alrady have one.
179 // If it already has one and it points to the same Section as the
180 // Right one, it needs to get an own Header.
181 // The content is evidently copied.
182 const SwFmtHeader
&rFmtHead
= rDescFrmFmt
.GetHeader();
183 if ( !rFmtHead
.IsActive() )
185 SwFmtHeader
aHead( MakeLayoutFmt( RND_STD_HEADERL
, 0 ) );
186 rDescFrmFmt
.SetFmtAttr( aHead
);
187 // take over additional attributes (margins, borders ...)
188 ::lcl_DescSetAttr( *rHead
.GetHeaderFmt(), *aHead
.GetHeaderFmt(), false);
192 const SwFrmFmt
*pRight
= rHead
.GetHeaderFmt();
193 const SwFmtCntnt
&aRCnt
= pRight
->GetCntnt();
194 const SwFmtCntnt
&aCnt
= rFmtHead
.GetHeaderFmt()->GetCntnt();
195 if( !aCnt
.GetCntntIdx() )
197 const SwFrmFmt
& rChgedFrmFmt
= (bLeft
? rChged
.GetLeft() : rChged
.GetFirst());
198 rDescFrmFmt
.SetFmtAttr( rChgedFrmFmt
.GetHeader() );
200 else if( (*aRCnt
.GetCntntIdx()) == (*aCnt
.GetCntntIdx()) )
202 SwFrmFmt
*pFmt
= new SwFrmFmt( GetAttrPool(), (bLeft
? "Left header" : "First header"),
204 ::lcl_DescSetAttr( *pRight
, *pFmt
, false );
205 // The section which the right header attribute is pointing
206 // is copied, and the Index to the StartNode is set to
207 // the left or first header attribute.
208 SwNodeIndex
aTmp( GetNodes().GetEndOfAutotext() );
209 SwStartNode
* pSttNd
= GetNodes().MakeEmptySection( aTmp
, SwHeaderStartNode
);
210 SwNodeRange
aRange( aRCnt
.GetCntntIdx()->GetNode(), 0,
211 *aRCnt
.GetCntntIdx()->GetNode().EndOfSectionNode() );
212 aTmp
= *pSttNd
->EndOfSectionNode();
213 GetNodes()._Copy( aRange
, aTmp
, sal_False
);
215 pFmt
->SetFmtAttr( SwFmtCntnt( pSttNd
) );
216 rDescFrmFmt
.SetFmtAttr( SwFmtHeader( pFmt
) );
219 ::lcl_DescSetAttr( *pRight
,
220 *(SwFrmFmt
*)rFmtHead
.GetHeaderFmt(), false );
226 void SwDoc::CopyMasterFooter(const SwPageDesc
&rChged
, const SwFmtFooter
&rFoot
, SwPageDesc
*pDesc
, bool bLeft
)
228 SwFrmFmt
& rDescFrmFmt
= (bLeft
? pDesc
->GetLeft() : pDesc
->GetFirst());
229 if ( (bLeft
? rChged
.IsFooterShared() : rChged
.IsFirstShared() ) || !rFoot
.IsActive() )
230 // Left or first shares the Header with the Master.
231 rDescFrmFmt
.SetFmtAttr( pDesc
->GetMaster().GetFooter() );
232 else if ( rFoot
.IsActive() )
233 { // Left or first gets its own Footer if the Format does not already have one.
234 // If the Format already has a Footer and it points to the same section as the Right one,
235 // it needs to get an own one.
236 // The content is evidently copied.
237 const SwFmtFooter
&rFmtFoot
= rDescFrmFmt
.GetFooter();
238 if ( !rFmtFoot
.IsActive() )
240 SwFmtFooter
aFoot( MakeLayoutFmt( RND_STD_FOOTER
, 0 ) );
241 rDescFrmFmt
.SetFmtAttr( aFoot
);
242 // Take over additional attributes (margins, borders ...).
243 ::lcl_DescSetAttr( *rFoot
.GetFooterFmt(), *aFoot
.GetFooterFmt(), false);
247 const SwFrmFmt
*pRight
= rFoot
.GetFooterFmt();
248 const SwFmtCntnt
&aRCnt
= pRight
->GetCntnt();
249 const SwFmtCntnt
&aLCnt
= rFmtFoot
.GetFooterFmt()->GetCntnt();
250 if( !aLCnt
.GetCntntIdx() )
252 const SwFrmFmt
& rChgedFrmFmt
= (bLeft
? rChged
.GetLeft() : rChged
.GetFirst());
253 rDescFrmFmt
.SetFmtAttr( rChgedFrmFmt
.GetFooter() );
255 else if( (*aRCnt
.GetCntntIdx()) == (*aLCnt
.GetCntntIdx()) )
257 SwFrmFmt
*pFmt
= new SwFrmFmt( GetAttrPool(), (bLeft
? "Left footer" : "First footer"),
259 ::lcl_DescSetAttr( *pRight
, *pFmt
, false );
260 // The section to which the right footer attribute is pointing
261 // is copied, and the Index to the StartNode is set to
262 // the left footer attribute.
263 SwNodeIndex
aTmp( GetNodes().GetEndOfAutotext() );
264 SwStartNode
* pSttNd
= GetNodes().MakeEmptySection( aTmp
, SwFooterStartNode
);
265 SwNodeRange
aRange( aRCnt
.GetCntntIdx()->GetNode(), 0,
266 *aRCnt
.GetCntntIdx()->GetNode().EndOfSectionNode() );
267 aTmp
= *pSttNd
->EndOfSectionNode();
268 GetNodes()._Copy( aRange
, aTmp
, sal_False
);
270 pFmt
->SetFmtAttr( SwFmtCntnt( pSttNd
) );
271 rDescFrmFmt
.SetFmtAttr( SwFmtFooter( pFmt
) );
274 ::lcl_DescSetAttr( *pRight
,
275 *(SwFrmFmt
*)rFmtFoot
.GetFooterFmt(), false );
280 void SwDoc::ChgPageDesc( sal_uInt16 i
, const SwPageDesc
&rChged
)
282 OSL_ENSURE( i
< aPageDescs
.size(), "PageDescs is out of range." );
284 SwPageDesc
*pDesc
= aPageDescs
[i
];
285 SwRootFrm
* pTmpRoot
= GetCurrentLayout();
287 if (GetIDocumentUndoRedo().DoesUndo())
289 SwUndo
*const pUndo(new SwUndoPageDesc(*pDesc
, rChged
, this));
290 GetIDocumentUndoRedo().AppendUndo(pUndo
);
292 ::sw::UndoGuard
const undoGuard(GetIDocumentUndoRedo());
294 // Mirror at first if needed.
295 if ( rChged
.GetUseOn() == nsUseOnPage::PD_MIRROR
)
296 ((SwPageDesc
&)rChged
).Mirror();
299 // Or else transfer values from Master to Left
300 ::lcl_DescSetAttr(rChged
.GetMaster(),
301 const_cast<SwPageDesc
&>(rChged
).GetLeft());
303 ::lcl_DescSetAttr(rChged
.GetMaster(),
304 const_cast<SwPageDesc
&>(rChged
).GetFirst());
306 // Take over NumType.
307 if( rChged
.GetNumType().GetNumberingType() != pDesc
->GetNumType().GetNumberingType() )
309 pDesc
->SetNumType( rChged
.GetNumType() );
310 // Notify page number fields that NumFormat has changed
311 GetSysFldType( RES_PAGENUMBERFLD
)->UpdateFlds();
312 GetSysFldType( RES_REFPAGEGETFLD
)->UpdateFlds();
314 // If the numbering scheme has changed we could have QuoVadis/ErgoSum texts
315 // that refer to a changed page, so we invalidate foot notes.
316 SwFtnIdxs
& rFtnIdxs
= GetFtnIdxs();
317 for( sal_uInt16 nPos
= 0; nPos
< rFtnIdxs
.size(); ++nPos
)
319 SwTxtFtn
*pTxtFtn
= rFtnIdxs
[ nPos
];
320 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
321 pTxtFtn
->SetNumber( rFtn
.GetNumber(), &rFtn
.GetNumStr());
325 // Take over orientation
326 pDesc
->SetLandscape( rChged
.GetLandscape() );
327 pDesc
->ChgFirstShare( rChged
.IsFirstShared() );
329 // #i46909# no undo if header or footer changed
330 bool bHeaderFooterChanged
= false;
333 const SwFmtHeader
&rHead
= rChged
.GetMaster().GetHeader();
334 if (undoGuard
.UndoWasEnabled())
336 // #i46909# no undo if header or footer changed
337 // Did something change in the nodes?
338 const SwFmtHeader
&rOldHead
= pDesc
->GetMaster().GetHeader();
339 bHeaderFooterChanged
|=
340 ( rHead
.IsActive() != rOldHead
.IsActive() ||
341 rChged
.IsHeaderShared() != pDesc
->IsHeaderShared() ||
342 rChged
.IsFirstShared() != pDesc
->IsFirstShared() );
344 pDesc
->GetMaster().SetFmtAttr( rHead
);
345 CopyMasterHeader(rChged
, rHead
, pDesc
, true); // Copy left header
346 CopyMasterHeader(rChged
, rHead
, pDesc
, false); // Copy first header
347 pDesc
->ChgHeaderShare( rChged
.IsHeaderShared() );
350 const SwFmtFooter
&rFoot
= rChged
.GetMaster().GetFooter();
351 if (undoGuard
.UndoWasEnabled())
353 // #i46909# no undo if header or footer changed
354 // Did something change in the Nodes?
355 const SwFmtFooter
&rOldFoot
= pDesc
->GetMaster().GetFooter();
356 bHeaderFooterChanged
|=
357 ( rFoot
.IsActive() != rOldFoot
.IsActive() ||
358 rChged
.IsFooterShared() != pDesc
->IsFooterShared() ||
359 rChged
.IsFirstShared() != pDesc
->IsFirstShared() );
361 pDesc
->GetMaster().SetFmtAttr( rFoot
);
362 CopyMasterFooter(rChged
, rFoot
, pDesc
, true); // Copy left footer
363 CopyMasterFooter(rChged
, rFoot
, pDesc
, false); // Copy first footer
364 pDesc
->ChgFooterShare( rChged
.IsFooterShared() );
366 if ( pDesc
->GetName() != rChged
.GetName() )
367 pDesc
->SetName( rChged
.GetName() );
369 // A RegisterChange is triggered, if necessary
370 pDesc
->SetRegisterFmtColl( rChged
.GetRegisterFmtColl() );
372 // If UseOn or the Follow change, the paragraphs need to know about it.
374 bool bFollow
= false;
375 if ( pDesc
->GetUseOn() != rChged
.GetUseOn() )
376 { pDesc
->SetUseOn( rChged
.GetUseOn() );
379 if ( pDesc
->GetFollow() != rChged
.GetFollow() )
380 { if ( rChged
.GetFollow() == &rChged
)
381 { if ( pDesc
->GetFollow() != pDesc
)
382 { pDesc
->SetFollow( pDesc
);
387 { pDesc
->SetFollow( rChged
.pFollow
);
392 if ( (bUseOn
|| bFollow
) && pTmpRoot
)
395 std::set
<SwRootFrm
*> aAllLayouts
= GetAllLayouts();
396 std::for_each( aAllLayouts
.begin(), aAllLayouts
.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs
));
399 // Take over the page attributes.
400 ::lcl_DescSetAttr( rChged
.GetMaster(), pDesc
->GetMaster() );
401 ::lcl_DescSetAttr( rChged
.GetLeft(), pDesc
->GetLeft() );
402 ::lcl_DescSetAttr( rChged
.GetFirst(), pDesc
->GetFirst() );
404 // If the FootnoteInfo changes, the pages are triggered.
405 if( !(pDesc
->GetFtnInfo() == rChged
.GetFtnInfo()) )
407 pDesc
->SetFtnInfo( rChged
.GetFtnInfo() );
408 SwMsgPoolItem
aInfo( RES_PAGEDESC_FTNINFO
);
410 pDesc
->GetMaster().ModifyBroadcast( &aInfo
, 0, TYPE(SwFrm
) );
413 pDesc
->GetLeft().ModifyBroadcast( &aInfo
, 0, TYPE(SwFrm
) );
416 pDesc
->GetFirst().ModifyBroadcast( &aInfo
, 0, TYPE(SwFrm
) );
421 // #i46909# no undo if header or footer changed
422 if( bHeaderFooterChanged
)
424 GetIDocumentUndoRedo().DelAllUndoObj();
428 /*************************************************************************
430 |* SwDoc::DelPageDesc()
432 |* Description: All descriptors whose Follow point to the to-be-deleted
433 |* have to be adapted.
435 |*************************************************************************/
438 void SwDoc::PreDelPageDesc(SwPageDesc
* pDel
)
443 // mba: test iteration as clients are removed while iteration
444 SwPageDescHint
aHint( aPageDescs
[0] );
445 pDel
->CallSwClientNotify( aHint
);
447 bool bHasLayout
= HasLayout();
448 if ( pFtnInfo
->DependsOn( pDel
) )
450 pFtnInfo
->ChgPageDesc( aPageDescs
[0] );
453 std::set
<SwRootFrm
*> aAllLayouts
= GetAllLayouts();
454 std::for_each( aAllLayouts
.begin(), aAllLayouts
.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs
), false));
457 else if ( pEndNoteInfo
->DependsOn( pDel
) )
459 pEndNoteInfo
->ChgPageDesc( aPageDescs
[0] );
462 std::set
<SwRootFrm
*> aAllLayouts
= GetAllLayouts();
463 std::for_each( aAllLayouts
.begin(), aAllLayouts
.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs
), true));
467 for ( sal_uInt16 j
= 0; j
< aPageDescs
.size(); ++j
)
469 if ( aPageDescs
[j
]->GetFollow() == pDel
)
471 aPageDescs
[j
]->SetFollow( 0 );
474 std::set
<SwRootFrm
*> aAllLayouts
= GetAllLayouts();
475 std::for_each( aAllLayouts
.begin(), aAllLayouts
.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs
));
481 void SwDoc::BroadcastStyleOperation(String rName
, SfxStyleFamily eFamily
,
486 SfxStyleSheetBasePool
* pPool
= pDocShell
->GetStyleSheetPool();
490 pPool
->SetSearchMask(eFamily
, SFXSTYLEBIT_ALL
);
491 SfxStyleSheetBase
* pBase
= pPool
->Find(rName
);
494 pPool
->Broadcast(SfxStyleSheetHint( nOp
, *pBase
));
499 void SwDoc::DelPageDesc( sal_uInt16 i
, bool bBroadcast
)
501 OSL_ENSURE( i
< aPageDescs
.size(), "PageDescs is out of range." );
502 OSL_ENSURE( i
!= 0, "You cannot delete the default Pagedesc.");
506 SwPageDesc
*pDel
= aPageDescs
[i
];
509 BroadcastStyleOperation(pDel
->GetName(), SFX_STYLE_FAMILY_PAGE
,
510 SFX_STYLESHEET_ERASED
);
512 if (GetIDocumentUndoRedo().DoesUndo())
514 SwUndo
*const pUndo(new SwUndoPageDescDelete(*pDel
, this));
515 GetIDocumentUndoRedo().AppendUndo(pUndo
);
518 PreDelPageDesc(pDel
); // #i7983#
520 aPageDescs
.erase( aPageDescs
.begin() + i
);
527 /*************************************************************************
529 |* SwDoc::MakePageDesc()
531 |*************************************************************************/
533 sal_uInt16
SwDoc::MakePageDesc( const String
&rName
, const SwPageDesc
*pCpy
,
534 bool bRegardLanguage
, bool bBroadcast
)
539 pNew
= new SwPageDesc( *pCpy
);
540 pNew
->SetName( rName
);
541 if( rName
!= pCpy
->GetName() )
543 pNew
->SetPoolFmtId( USHRT_MAX
);
544 pNew
->SetPoolHelpId( USHRT_MAX
);
545 pNew
->SetPoolHlpFileId( UCHAR_MAX
);
550 pNew
= new SwPageDesc( rName
, GetDfltFrmFmt(), this );
551 // Set the default page format.
552 lcl_DefaultPageFmt( USHRT_MAX
, pNew
->GetMaster(), pNew
->GetLeft(), pNew
->GetFirst() );
554 SvxFrameDirection aFrameDirection
= bRegardLanguage
?
555 GetDefaultFrameDirection(GetAppLanguage())
556 : FRMDIR_HORI_LEFT_TOP
;
558 pNew
->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection
, RES_FRAMEDIR
) );
559 pNew
->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection
, RES_FRAMEDIR
) );
560 pNew
->GetFirst().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection
, RES_FRAMEDIR
) );
562 aPageDescs
.push_back( pNew
);
565 BroadcastStyleOperation(rName
, SFX_STYLE_FAMILY_PAGE
,
566 SFX_STYLESHEET_CREATED
);
568 if (GetIDocumentUndoRedo().DoesUndo())
570 GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew
, this));
574 return (aPageDescs
.size()-1);
577 SwPageDesc
* SwDoc::FindPageDescByName( const String
& rName
, sal_uInt16
* pPos
) const
579 SwPageDesc
* pRet
= 0;
580 if( pPos
) *pPos
= USHRT_MAX
;
582 for( sal_uInt16 n
= 0, nEnd
= aPageDescs
.size(); n
< nEnd
; ++n
)
583 if( aPageDescs
[ n
]->GetName() == rName
)
585 pRet
= aPageDescs
[ n
];
593 /******************************************************************************
594 * Method : void SwDoc::PrtDataChanged()
596 ******************************************************************************/
598 void SwDoc::PrtDataChanged()
600 // If you change this, also modify InJobSetup in Sw3io if appropriate.
603 OSL_ENSURE( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE
) ||
604 0 != getPrinter( sal_False
), "PrtDataChanged will be called recursively!" );
605 SwRootFrm
* pTmpRoot
= GetCurrentLayout();
607 bool bEndAction
= false;
610 GetDocShell()->UpdateFontList();
615 ViewShell
*pSh
= GetCurrentViewShell();
617 (!pSh
->GetViewOptions()->getBrowseMode() ||
618 pSh
->GetViewOptions()->IsPrtFormat()) )
621 pWait
= new SwWait( *GetDocShell(), sal_True
);
623 pTmpRoot
->StartAllAction();
629 pDrawModel
->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING
) );
630 pDrawModel
->SetRefDevice( getReferenceDevice( false ) );
635 std::set
<SwRootFrm
*> aAllLayouts
= GetAllLayouts();
636 std::for_each( aAllLayouts
.begin(), aAllLayouts
.end(),std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt
), INV_SIZE
));
640 pSh
->InitPrt( pPrt
);
641 pSh
= (ViewShell
*)pSh
->GetNext();
643 while ( pSh
!= GetCurrentViewShell() );
646 if ( bDraw
&& pDrawModel
)
648 const sal_Bool bTmpAddExtLeading
= get(IDocumentSettingAccess::ADD_EXT_LEADING
);
649 if ( bTmpAddExtLeading
!= pDrawModel
->IsAddExtLeading() )
650 pDrawModel
->SetAddExtLeading( bTmpAddExtLeading
);
652 OutputDevice
* pOutDev
= getReferenceDevice( false );
653 if ( pOutDev
!= pDrawModel
->GetRefDevice() )
654 pDrawModel
->SetRefDevice( pOutDev
);
657 PrtOLENotify( sal_True
);
660 pTmpRoot
->EndAllAction();
664 // We collect the GlobalNames of the servers at runtime, who don't want to be notified
665 // about printer changes. Thereby saving loading a lot of objects (luckily all foreign
666 // objects are mapped to one ID).
667 // Initialisation and deinitialisation can be found in init.cxx
668 extern std::vector
<SvGlobalName
*> *pGlobalOLEExcludeList
;
670 void SwDoc::PrtOLENotify( sal_Bool bAll
)
672 SwFEShell
*pShell
= 0;
673 if ( GetCurrentViewShell() )
675 ViewShell
*pSh
= GetCurrentViewShell();
676 if ( !pSh
->ISA(SwFEShell
) )
678 { pSh
= (ViewShell
*)pSh
->GetNext();
679 } while ( !pSh
->ISA(SwFEShell
) &&
680 pSh
!= GetCurrentViewShell() );
682 if ( pSh
->ISA(SwFEShell
) )
683 pShell
= (SwFEShell
*)pSh
;
687 // This doesn't make sense without a Shell and thus without a client, because
688 // the communication about size changes is implemented by these components.
689 // Because we don't have a Shell we remember this unfortunate situation
691 // which is made up for later on when creating the first Shell.
692 mbOLEPrtNotifyPending
= sal_True
;
694 mbAllOLENotify
= sal_True
;
698 if ( mbAllOLENotify
)
701 mbOLEPrtNotifyPending
= mbAllOLENotify
= sal_False
;
703 SwOLENodes
*pNodes
= SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), !bAll
);
706 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY
,
707 0, pNodes
->size(), GetDocShell());
708 GetCurrentLayout()->StartAllAction();
710 for( sal_uInt16 i
= 0; i
< pNodes
->size(); ++i
)
712 ::SetProgressState( i
, GetDocShell() );
714 SwOLENode
* pOLENd
= (*pNodes
)[i
];
715 pOLENd
->SetOLESizeInvalid( sal_False
);
717 // At first load the Infos and see if it's not already in the exclude list.
720 svt::EmbeddedObjectRef
& xObj
= pOLENd
->GetOLEObj().GetObject();
722 aName
= SvGlobalName( xObj
->getClassID() );
723 else // Not yet loaded
725 // TODO/LATER: retrieve ClassID of an unloaded object
730 for ( sal_uInt16 j
= 0;
731 j
< pGlobalOLEExcludeList
->size() && !bFound
;
734 bFound
= *(*pGlobalOLEExcludeList
)[j
] == aName
;
739 // We don't know it, so the object has to be loaded.
740 // If it doesn't want to be informed
743 pGlobalOLEExcludeList
->push_back( new SvGlobalName( aName
) );
747 GetCurrentLayout()->EndAllAction();
748 ::EndProgress( GetDocShell() );
753 IMPL_LINK( SwDoc
, DoUpdateModifiedOLE
, Timer
*, )
755 SwFEShell
* pSh
= (SwFEShell
*)GetEditShell();
758 mbOLEPrtNotifyPending
= mbAllOLENotify
= sal_False
;
760 SwOLENodes
*pNodes
= SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), true );
763 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY
,
764 0, pNodes
->size(), GetDocShell());
765 GetCurrentLayout()->StartAllAction();
766 SwMsgPoolItem
aMsgHint( RES_UPDATE_ATTR
);
768 for( sal_uInt16 i
= 0; i
< pNodes
->size(); ++i
)
770 ::SetProgressState( i
, GetDocShell() );
772 SwOLENode
* pOLENd
= (*pNodes
)[i
];
773 pOLENd
->SetOLESizeInvalid( sal_False
);
775 // We don't know it, so the object has to be loaded.
776 // If it doesn't want to be informed
777 if( pOLENd
->GetOLEObj().GetOleRef().is() ) // Broken?
779 pOLENd
->ModifyNotification( &aMsgHint
, &aMsgHint
);
782 GetCurrentLayout()->EndAllAction();
783 ::EndProgress( GetDocShell() );
790 bool SwDoc::FindPageDesc( const String
& rName
, sal_uInt16
* pFound
)
792 bool bResult
= false;
794 for (nI
= 0; nI
< aPageDescs
.size(); nI
++)
796 if (aPageDescs
[nI
]->GetName() == rName
)
807 SwPageDesc
* SwDoc::GetPageDesc( const String
& rName
)
809 SwPageDesc
* aResult
= NULL
;
813 if (FindPageDesc(rName
, &nI
))
814 aResult
= aPageDescs
[nI
];
819 void SwDoc::DelPageDesc( const String
& rName
, bool bBroadcast
)
823 if (FindPageDesc(rName
, &nI
))
824 DelPageDesc(nI
, bBroadcast
);
827 void SwDoc::ChgPageDesc( const String
& rName
, const SwPageDesc
& rDesc
)
831 if (FindPageDesc(rName
, &nI
))
832 ChgPageDesc(nI
, rDesc
);
836 * The HTML import cannot resist changing the page descriptions, I don't
837 * know why. This function is meant to check the page descriptors for invalid
840 void SwDoc::CheckDefaultPageFmt()
842 for ( sal_uInt16 i
= 0; i
< GetPageDescCnt(); ++i
)
844 SwPageDesc
& rDesc
= GetPageDesc( i
);
846 SwFrmFmt
& rMaster
= rDesc
.GetMaster();
847 SwFrmFmt
& rLeft
= rDesc
.GetLeft();
849 const SwFmtFrmSize
& rMasterSize
= rMaster
.GetFrmSize();
850 const SwFmtFrmSize
& rLeftSize
= rLeft
.GetFrmSize();
852 const bool bSetSize
= LONG_MAX
== rMasterSize
.GetWidth() ||
853 LONG_MAX
== rMasterSize
.GetHeight() ||
854 LONG_MAX
== rLeftSize
.GetWidth() ||
855 LONG_MAX
== rLeftSize
.GetHeight();
858 lcl_DefaultPageFmt( rDesc
.GetPoolFmtId(), rDesc
.GetMaster(), rDesc
.GetLeft(), rDesc
.GetFirst() );
862 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode
)
864 if( !bSquaredPageMode
== !IsSquaredPageMode() )
867 const SwTextGridItem
& rGrid
=
868 (const SwTextGridItem
&)GetDefault( RES_TEXTGRID
);
869 SwTextGridItem aNewGrid
= rGrid
;
870 aNewGrid
.SetSquaredMode(bSquaredPageMode
);
872 SetDefault(aNewGrid
);
874 for ( sal_uInt16 i
= 0; i
< GetPageDescCnt(); ++i
)
876 SwPageDesc
& rDesc
= GetPageDesc( i
);
878 SwFrmFmt
& rMaster
= rDesc
.GetMaster();
879 SwFrmFmt
& rLeft
= rDesc
.GetLeft();
881 SwTextGridItem
aGrid((SwTextGridItem
&)rMaster
.GetFmtAttr(RES_TEXTGRID
));
882 aGrid
.SwitchPaperMode( bSquaredPageMode
);
883 rMaster
.SetFmtAttr(aGrid
);
884 rLeft
.SetFmtAttr(aGrid
);
888 sal_Bool
SwDoc::IsSquaredPageMode() const
890 const SwTextGridItem
& rGrid
=
891 (const SwTextGridItem
&)GetDefault( RES_TEXTGRID
);
892 return rGrid
.IsSquaredMode();
895 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */