update dev300-m58
[ooovba.git] / sw / source / core / doc / docdesc.cxx
blob88176f79c8e3c37082907b6465942aaa07c87904
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docdesc.cxx,v $
10 * $Revision: 1.43 $
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>
49 #include <fesh.hxx>
50 #include <ndole.hxx>
51 #include <mdiexp.hxx>
52 #include <doc.hxx>
53 #include <docary.hxx>
54 #include <pagefrm.hxx> //Fuer DelPageDesc
55 #include <rootfrm.hxx> //Fuer DelPageDesc
56 #include <ndtxt.hxx>
57 #include <frmtool.hxx>
58 #include <pagedesc.hxx>
59 #include <poolfmt.hxx>
60 #ifndef _DOCSH_HXX
61 #include <docsh.hxx>
62 #endif
63 #include <ndindex.hxx>
64 #include <ftnidx.hxx>
65 #include <fmtftn.hxx>
66 #include <txtftn.hxx>
67 #include <fntcache.hxx>
68 #include <viewsh.hxx>
69 #include <viewopt.hxx>
70 #include <fldbas.hxx>
71 #include <swwait.hxx>
72 #include <GetMetricVal.hxx>
73 #include <svtools/syslocale.hxx>
74 #ifndef _STATSTR_HRC
75 #include <statstr.hrc>
76 #endif
78 #include <SwUndoPageDesc.hxx>
80 #include <tgrditem.hxx>
82 using namespace com::sun::star;
84 static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId,
85 SwFrmFmt &rFmt1,
86 SwFrmFmt &rFmt2 )
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
91 //locale
92 // <--
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
118 else
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 /////////////// !!!!!!!!!!!!!!!!
155 //JP 03.03.99:
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,
162 RES_COL, RES_COL,
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,
168 // <--
169 RES_UNKNOWNATR_CONTAINER,
170 RES_UNKNOWNATR_CONTAINER,
171 0 };
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#
179 // bPage == true:
180 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
181 // bPage == false:
182 // All in aIdArr except from RES_COL and RES_PAPER_BIN:
183 // <--
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 );
189 else
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();
209 if (DoesUndo())
211 AppendUndo(new SwUndoPageDesc(*pDesc, rChged, this));
212 DoUndo(FALSE);
215 //Als erstes wird ggf. gespiegelt.
216 if ( rChged.GetUseOn() == nsUseOnPage::PD_MIRROR )
217 ((SwPageDesc&)rChged).Mirror();
218 else
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;
250 //Header abgleichen.
251 const SwFmtHeader &rHead = rChged.GetMaster().GetHeader();
252 if( bDoesUndo )
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
269 //bereits einen hat.
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);
281 else
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",
291 GetDfltFrmFmt() );
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 ) );
306 else
307 ::lcl_DescSetAttr( *pRight,
308 *(SwFrmFmt*)rLeftHead.GetHeaderFmt(), FALSE );
312 pDesc->ChgHeaderShare( rChged.IsHeaderShared() );
314 //Footer abgleichen.
315 const SwFmtFooter &rFoot = rChged.GetMaster().GetFooter();
316 if( bDoesUndo )
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
331 //bereits einen hat.
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);
343 else
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",
353 GetDfltFrmFmt() );
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 ) );
368 else
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.
383 BOOL bUseOn = FALSE;
384 BOOL bFollow = FALSE;
385 if ( pDesc->GetUseOn() != rChged.GetUseOn() )
386 { pDesc->SetUseOn( rChged.GetUseOn() );
387 bUseOn = TRUE;
389 if ( pDesc->GetFollow() != rChged.GetFollow() )
390 { if ( rChged.GetFollow() == &rChged )
391 { if ( pDesc->GetFollow() != pDesc )
392 { pDesc->SetFollow( pDesc );
393 bFollow = TRUE;
396 else
397 { pDesc->SetFollow( rChged.pFollow );
398 bFollow = TRUE;
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
411 //angetriggert.
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 );
429 SetModified();
431 DoUndo(bDoesUndo);
433 // #i46909# no undo if header or footer changed
434 if( bHeaderFooterChanged )
436 ClearRedo();
437 DelAllUndoObj();
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 );
455 SwFrm *pFrm;
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;
464 else
466 pFrm->Cut();
467 delete pFrm;
471 // #i7983#
472 void SwDoc::PreDelPageDesc(SwPageDesc * pDel)
474 if (0 == pDel)
475 return;
477 SwFmtPageDesc aDfltDesc( aPageDescs[0] );
478 SwClientIter aIter( *pDel );
479 SwClient* pLast;
480 while( 0 != ( pLast = aIter.GoRoot() ))
482 if( pLast->ISA( SwFmtPageDesc ) )
484 const SwModify* pMod = ((SwFmtPageDesc*)pLast)->GetDefinedIn();
485 if ( pMod )
487 if( pMod->ISA( SwCntntNode ) )
488 ((SwCntntNode*)pMod)->SetAttr( aDfltDesc );
489 else if( pMod->ISA( SwFmt ))
490 ((SwFmt*)pMod)->SetFmtAttr( aDfltDesc );
491 else
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 );
506 if ( GetRootFrm() )
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
529 //vernichtet werden.
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 );
541 // #116530#
542 void SwDoc::BroadcastStyleOperation(String rName, SfxStyleFamily eFamily,
543 USHORT nOp)
545 if (pDocShell)
547 SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool();
549 if (pPool)
551 pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
552 SfxStyleSheetBase * pBase = pPool->Find(rName);
554 if (pBase != NULL)
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." );
564 if ( i == 0 )
565 return;
567 SwPageDesc *pDel = aPageDescs[i];
569 // -> #116530#
570 if (bBroadcast)
571 BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PAGE,
572 SFX_STYLESHEET_ERASED);
573 // <- #116530#
575 if (DoesUndo())
577 AppendUndo(new SwUndoPageDescDelete(*pDel, this));
580 PreDelPageDesc(pDel); // #i7983#
582 aPageDescs.Remove( i );
583 delete pDel;
584 SetModified();
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#
601 SwPageDesc *pNew;
602 if( pCpy )
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 );
613 else
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() );
628 // -> #116530#
629 if (bBroadcast)
630 BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE,
631 SFX_STYLESHEET_CREATED);
632 // <- #116530#
634 if (DoesUndo())
635 AppendUndo(new SwUndoPageDescCreate(pNew, this)); // #116530#
637 SetModified();
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 ];
650 if( pPos )
651 *pPos = n;
652 break;
654 return pRet;
657 /******************************************************************************
658 * Methode : void SwDoc::PrtDataChanged()
659 * Beschreibung:
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!" )
671 // <--
673 SwWait *pWait = 0;
674 BOOL bEndAction = FALSE;
676 if( GetDocShell() )
677 GetDocShell()->UpdateFontList();
679 BOOL bDraw = TRUE;
680 if ( GetRootFrm() )
682 ViewShell *pSh = GetRootFrm()->GetCurrShell();
683 if( !get(IDocumentSettingAccess::BROWSE_MODE) ||
684 ( pSh && pSh->GetViewOptions()->IsPrtFormat() ) )
686 if ( GetDocShell() )
687 pWait = new SwWait( *GetDocShell(), TRUE );
689 GetRootFrm()->StartAllAction();
690 bEndAction = TRUE;
692 bDraw = FALSE;
693 if( pDrawModel )
695 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
696 pDrawModel->SetRefDevice( getReferenceDevice( false ) );
699 pFntCache->Flush();
700 GetRootFrm()->InvalidateAllCntnt();
702 if ( pSh )
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 );
727 if ( bEndAction )
728 GetRootFrm()->EndAllAction();
729 delete pWait;
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;
754 if ( !pShell )
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
760 //nachgeholt.
761 mbOLEPrtNotifyPending = TRUE;
762 if ( bAll )
763 mbAllOLENotify = TRUE;
765 else
767 if ( mbAllOLENotify )
768 bAll = TRUE;
770 mbOLEPrtNotifyPending = mbAllOLENotify = FALSE;
773 SwOLENodes *pNodes = 0;
774 SwClientIter aIter( *(SwModify*)GetDfltGrfFmtColl() );
775 for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) );
776 pNd;
777 pNd = (SwCntntNode*)aIter.Next() )
779 SwOLENode *pONd;
780 if ( 0 != (pONd = pNd->GetOLENode()) &&
781 (bAll || pONd->IsOLESizeInvalid()) )
783 if ( !pNodes )
784 pNodes = new SwOLENodes;
785 pNodes->Insert( pONd, pNodes->Count() );
789 if ( pNodes )
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
804 SvGlobalName aName;
806 svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject();
807 if ( xObj.is() )
808 aName = SvGlobalName( xObj->getClassID() );
809 else //Noch nicht geladen
811 // TODO/LATER: retrieve ClassID of an unloaded object
812 // aName = ????
815 BOOL bFound = FALSE;
816 for ( USHORT j = 0;
817 j < pGlobalOLEExcludeList->Count() && !bFound;
818 ++j )
820 bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[j] ==
821 aName;
823 if ( bFound )
824 continue;
826 //Kennen wir nicht, also muss das Objekt geladen werden.
827 //Wenn es keine Benachrichtigung wuenscht
828 if ( xObj.is() )
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.
839 else
840 pOLENd->SetOLESizeInvalid( TRUE );
842 else */
843 pGlobalOLEExcludeList->Insert(
844 new SvGlobalName( aName ),
845 pGlobalOLEExcludeList->Count() );
848 delete pNodes;
849 GetRootFrm()->EndAllAction();
850 ::EndProgress( GetDocShell() );
855 IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, )
857 SwFEShell* pSh = (SwFEShell*)GetEditShell();
858 if( pSh )
860 mbOLEPrtNotifyPending = mbAllOLENotify = FALSE;
862 SwOLENodes aOLENodes;
863 SwClientIter aIter( *(SwModify*)GetDfltGrfFmtColl() );
864 for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) );
865 pNd;
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.
903 else
904 pOLENd->SetOLESizeInvalid( TRUE );
906 // repaint it
907 pOLENd->Modify( &aMsgHint, &aMsgHint );
910 GetRootFrm()->EndAllAction();
911 ::EndProgress( GetDocShell() );
914 return 0;
917 BOOL SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound)
919 BOOL bResult = FALSE;
920 sal_uInt16 nI;
921 for (nI = 0; nI < aPageDescs.Count(); nI++)
923 if (aPageDescs[nI]->GetName() == rName)
925 *pFound = nI;
926 bResult = TRUE;
927 break;
931 return bResult;
934 SwPageDesc * SwDoc::GetPageDesc( const String & rName )
936 SwPageDesc * aResult = NULL;
938 sal_uInt16 nI;
940 if (FindPageDesc(rName, &nI))
941 aResult = aPageDescs[nI];
943 return aResult;
946 void SwDoc::DelPageDesc( const String & rName, BOOL bBroadcast ) // #116530#
948 sal_uInt16 nI;
950 if (FindPageDesc(rName, &nI))
951 DelPageDesc(nI, bBroadcast); // #116530#
954 void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc)
956 sal_uInt16 nI;
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
965 * values.
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();
984 if ( bSetSize )
985 lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft() );
989 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode)
991 if( !bSquaredPageMode == !IsSquaredPageMode() )
992 return;
994 const SwTextGridItem& rGrid =
995 (const SwTextGridItem&)GetDefault( RES_TEXTGRID );
996 SwTextGridItem aNewGrid = rGrid;
997 aNewGrid.SetSquaredMode(bSquaredPageMode);
998 aNewGrid.Init();
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();