Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / sw / source / core / doc / docdesc.cxx
blob1852b4c16fd494de9c47850b1e9590db21b17ca5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
30 #include <fesh.hxx>
31 #include <ndole.hxx>
32 #include <mdiexp.hxx>
33 #include <doc.hxx>
34 #include <IDocumentUndoRedo.hxx>
35 #include <docary.hxx>
36 #include <rootfrm.hxx> //For DelPageDesc
37 #include <frmtool.hxx>
38 #include <poolfmt.hxx>
39 #include <docsh.hxx>
40 #include <ftnidx.hxx>
41 #include <fmtftn.hxx>
42 #include <txtftn.hxx>
43 #include <fntcache.hxx>
44 #include <viewopt.hxx>
45 #include <fldbas.hxx>
46 #include <swwait.hxx>
47 #include <GetMetricVal.hxx>
48 #include <statstr.hrc>
49 #include <hints.hxx>
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,
57 SwFrmFmt &rFmt1,
58 SwFrmFmt &rFmt2,
59 SwFrmFmt &rFmt3 )
61 // --> #i41075# Printer on demand
62 // This function does not require a printer anymore.
63 // The default page size is obtained from the application
64 //locale
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
89 else
91 nMinTop = nMinBottom = 1440; // as in MS Word: 1 Inch
92 nMinLeft = nMinRight = 1800; // 1,25 Inch
95 // set margins
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,
132 RES_COL, RES_COL,
133 RES_FRAMEDIR, RES_FRAMEDIR,
134 RES_TEXTGRID, RES_TEXTGRID,
135 // #i45539#
136 RES_HEADER_FOOTER_EAT_SPACING,
137 RES_HEADER_FOOTER_EAT_SPACING,
138 RES_UNKNOWNATR_CONTAINER,
139 RES_UNKNOWNATR_CONTAINER,
140 0 };
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 )
147 // #i45539#
148 // bPage == true:
149 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
150 // bPage == false:
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 );
157 else
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);
190 else
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"),
203 GetDfltFrmFmt() );
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 ) );
218 else
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);
245 else
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"),
258 GetDfltFrmFmt() );
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 ) );
273 else
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();
297 else
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;
332 // Synch header.
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() );
349 // Synch Footer.
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.
373 bool bUseOn = false;
374 bool bFollow = false;
375 if ( pDesc->GetUseOn() != rChged.GetUseOn() )
376 { pDesc->SetUseOn( rChged.GetUseOn() );
377 bUseOn = true;
379 if ( pDesc->GetFollow() != rChged.GetFollow() )
380 { if ( rChged.GetFollow() == &rChged )
381 { if ( pDesc->GetFollow() != pDesc )
382 { pDesc->SetFollow( pDesc );
383 bFollow = true;
386 else
387 { pDesc->SetFollow( rChged.pFollow );
388 bFollow = true;
392 if ( (bUseOn || bFollow) && pTmpRoot)
393 // Inform layout!
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) );
419 SetModified();
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 |*************************************************************************/
437 // #i7983#
438 void SwDoc::PreDelPageDesc(SwPageDesc * pDel)
440 if (0 == pDel)
441 return;
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] );
451 if ( bHasLayout )
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] );
460 if ( bHasLayout )
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 );
472 if( bHasLayout )
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,
482 sal_uInt16 nOp)
484 if (pDocShell)
486 SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool();
488 if (pPool)
490 pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
491 SfxStyleSheetBase * pBase = pPool->Find(rName);
493 if (pBase != NULL)
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.");
503 if ( i == 0 )
504 return;
506 SwPageDesc *pDel = aPageDescs[i];
508 if (bBroadcast)
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 );
521 delete pDel;
522 SetModified();
527 /*************************************************************************
529 |* SwDoc::MakePageDesc()
531 |*************************************************************************/
533 sal_uInt16 SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy,
534 bool bRegardLanguage, bool bBroadcast)
536 SwPageDesc *pNew;
537 if( pCpy )
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 );
548 else
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 );
564 if (bBroadcast)
565 BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE,
566 SFX_STYLESHEET_CREATED);
568 if (GetIDocumentUndoRedo().DoesUndo())
570 GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew, this));
573 SetModified();
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 ];
586 if( pPos )
587 *pPos = n;
588 break;
590 return pRet;
593 /******************************************************************************
594 * Method : void SwDoc::PrtDataChanged()
595 * Description :
596 ******************************************************************************/
598 void SwDoc::PrtDataChanged()
600 // If you change this, also modify InJobSetup in Sw3io if appropriate.
602 // #i41075#
603 OSL_ENSURE( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ||
604 0 != getPrinter( sal_False ), "PrtDataChanged will be called recursively!" );
605 SwRootFrm* pTmpRoot = GetCurrentLayout();
606 SwWait *pWait = 0;
607 bool bEndAction = false;
609 if( GetDocShell() )
610 GetDocShell()->UpdateFontList();
612 bool bDraw = true;
613 if ( pTmpRoot )
615 ViewShell *pSh = GetCurrentViewShell();
616 if( pSh &&
617 (!pSh->GetViewOptions()->getBrowseMode() ||
618 pSh->GetViewOptions()->IsPrtFormat()) )
620 if ( GetDocShell() )
621 pWait = new SwWait( *GetDocShell(), sal_True );
623 pTmpRoot->StartAllAction();
624 bEndAction = true;
626 bDraw = false;
627 if( pDrawModel )
629 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
630 pDrawModel->SetRefDevice( getReferenceDevice( false ) );
633 pFntCache->Flush();
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 );
659 if ( bEndAction )
660 pTmpRoot->EndAllAction();
661 delete pWait;
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;
685 if ( !pShell )
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
690 // in the document,
691 // which is made up for later on when creating the first Shell.
692 mbOLEPrtNotifyPending = sal_True;
693 if ( bAll )
694 mbAllOLENotify = sal_True;
696 else
698 if ( mbAllOLENotify )
699 bAll = sal_True;
701 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False;
703 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), !bAll );
704 if ( pNodes )
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.
718 SvGlobalName aName;
720 svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject();
721 if ( xObj.is() )
722 aName = SvGlobalName( xObj->getClassID() );
723 else // Not yet loaded
725 // TODO/LATER: retrieve ClassID of an unloaded object
726 // aName = ????
729 bool bFound = false;
730 for ( sal_uInt16 j = 0;
731 j < pGlobalOLEExcludeList->size() && !bFound;
732 ++j )
734 bFound = *(*pGlobalOLEExcludeList)[j] == aName;
736 if ( bFound )
737 continue;
739 // We don't know it, so the object has to be loaded.
740 // If it doesn't want to be informed
741 if ( xObj.is() )
743 pGlobalOLEExcludeList->push_back( new SvGlobalName( aName ) );
746 delete pNodes;
747 GetCurrentLayout()->EndAllAction();
748 ::EndProgress( GetDocShell() );
753 IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, )
755 SwFEShell* pSh = (SwFEShell*)GetEditShell();
756 if( pSh )
758 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False;
760 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), true );
761 if( pNodes )
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() );
784 delete pNodes;
787 return 0;
790 bool SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound)
792 bool bResult = false;
793 sal_uInt16 nI;
794 for (nI = 0; nI < aPageDescs.size(); nI++)
796 if (aPageDescs[nI]->GetName() == rName)
798 *pFound = nI;
799 bResult = true;
800 break;
804 return bResult;
807 SwPageDesc * SwDoc::GetPageDesc( const String & rName )
809 SwPageDesc * aResult = NULL;
811 sal_uInt16 nI;
813 if (FindPageDesc(rName, &nI))
814 aResult = aPageDescs[nI];
816 return aResult;
819 void SwDoc::DelPageDesc( const String & rName, bool bBroadcast )
821 sal_uInt16 nI;
823 if (FindPageDesc(rName, &nI))
824 DelPageDesc(nI, bBroadcast);
827 void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc)
829 sal_uInt16 nI;
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
838 * values.
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();
857 if ( bSetSize )
858 lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft(), rDesc.GetFirst() );
862 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode)
864 if( !bSquaredPageMode == !IsSquaredPageMode() )
865 return;
867 const SwTextGridItem& rGrid =
868 (const SwTextGridItem&)GetDefault( RES_TEXTGRID );
869 SwTextGridItem aNewGrid = rGrid;
870 aNewGrid.SetSquaredMode(bSquaredPageMode);
871 aNewGrid.Init();
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: */