xref: /trunk/main/sw/source/core/doc/docdesc.cxx (revision 26ea3662)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 
25 #include <cmdid.h>
26 #include <hintids.hxx>
27 #include <vcl/virdev.hxx>
28 #include <svx/svdmodel.hxx>
29 #include <editeng/ulspitem.hxx>
30 #include <editeng/lrspitem.hxx>
31 #include <editeng/paperinf.hxx>
32 #include "editeng/frmdiritem.hxx"
33 #include <tools/urlobj.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/printer.hxx>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <unotools/localedatawrapper.hxx>
39 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
40 #include <fmtfsize.hxx>
41 #include <fmthdft.hxx>
42 #include <fmtcntnt.hxx>
43 #include <fmtpdsc.hxx>
44 #include <ftninfo.hxx>
45 #include <fesh.hxx>
46 #include <ndole.hxx>
47 #include <mdiexp.hxx>
48 #include <doc.hxx>
49 #include <IDocumentUndoRedo.hxx>
50 #include <docary.hxx>
51 #include <pagefrm.hxx>	//Fuer DelPageDesc
52 #include <rootfrm.hxx>	//Fuer DelPageDesc
53 #include <ndtxt.hxx>
54 #include <frmtool.hxx>
55 #include <pagedesc.hxx>
56 #include <poolfmt.hxx>
57 #include <docsh.hxx>
58 #include <ndindex.hxx>
59 #include <ftnidx.hxx>
60 #include <fmtftn.hxx>
61 #include <txtftn.hxx>
62 #include <fntcache.hxx>
63 #include <viewsh.hxx>
64 #include <viewopt.hxx>
65 #include <fldbas.hxx>
66 #include <swwait.hxx>
67 #include <GetMetricVal.hxx>
68 #include <unotools/syslocale.hxx>
69 #include <statstr.hrc>
70 #include <switerator.hxx>
71 #include <hints.hxx>
72 #include <SwUndoPageDesc.hxx>
73 #include <pagedeschint.hxx>
74 #include <tgrditem.hxx>
75 #include <drawdoc.hxx>
76 
77 using namespace com::sun::star;
78 
79 static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId,
80                                 SwFrmFmt &rFmt1,
81                                 SwFrmFmt &rFmt2 )
82 {
83     // --> FME 2005-01-21 #i41075# Printer on demand
84     // This function does not require a printer anymore.
85     // The default page size is obtained from the application
86     //locale
87     // <--
88 
89     SwFmtFrmSize aFrmSize( ATT_FIX_SIZE );
90     const Size aPhysSize = SvxPaperInfo::GetDefaultPaperSize();
91     aFrmSize.SetSize( aPhysSize );
92 
93     //Auf Default-Raender vorbereiten.
94     //Raender haben eine defaultmaessige Mindestgroesse.
95     //wenn der Drucker einen groesseren Rand vorgibt, so
96     //ist mir dass auch recht.
97     // MIB 06/25/2002, #99397#: The HTML page desc had A4 as page size
98     // always. This has been changed to take the page size from the printer.
99     // Unfortunately, the margins of the HTML page desc are smaller than
100     // the margins used here in general, so one extra case is required.
101     // In the long term, this needs to be changed to always keep the
102     // margins from the page desc.
103     sal_Int32 nMinTop, nMinBottom, nMinLeft, nMinRight;
104     if( RES_POOLPAGE_HTML == nPoolFmtId )
105     {
106         nMinRight = nMinTop = nMinBottom = GetMetricVal( CM_1 );
107         nMinLeft = nMinRight * 2;
108     }
109     else if( MEASURE_METRIC == SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() )
110     {
111         nMinTop = nMinBottom = nMinLeft = nMinRight = 1134; //2 Zentimeter
112     }
113     else
114     {
115         nMinTop = nMinBottom = 1440;    //al la WW: 1Inch
116         nMinLeft = nMinRight = 1800;    //          1,25 Inch
117     }
118 
119     //Raender einstellen.
120     SvxLRSpaceItem aLR( RES_LR_SPACE );
121     SvxULSpaceItem aUL( RES_UL_SPACE );
122 
123     aUL.SetUpper( (sal_uInt16)nMinTop );
124     aUL.SetLower( (sal_uInt16)nMinBottom );
125     aLR.SetRight( nMinRight );
126     aLR.SetLeft( nMinLeft );
127 
128     rFmt1.SetFmtAttr( aFrmSize );
129     rFmt1.SetFmtAttr( aLR );
130     rFmt1.SetFmtAttr( aUL );
131 
132     rFmt2.SetFmtAttr( aFrmSize );
133     rFmt2.SetFmtAttr( aLR );
134     rFmt2.SetFmtAttr( aUL );
135 }
136 
137 /*************************************************************************
138 |*
139 |*	SwDoc::ChgPageDesc()
140 |*
141 |*	Ersterstellung		MA 25. Jan. 93
142 |*	Letzte Aenderung	MA 01. Mar. 95
143 |*
144 |*************************************************************************/
145 
146 void lcl_DescSetAttr( const SwFrmFmt &rSource, SwFrmFmt &rDest,
147 						 const sal_Bool bPage = sal_True )
148 {
149 /////////////// !!!!!!!!!!!!!!!!
150 //JP 03.03.99:
151 // eigentlich sollte hier das Intersect von ItemSet benutzt werden, aber das
152 // funktioniert nicht richtig, wenn man unterschiedliche WhichRanges hat.
153 /////////////// !!!!!!!!!!!!!!!!
154     //Die interressanten Attribute uebernehmen.
155     sal_uInt16 __READONLY_DATA aIdArr[] = {
156         RES_FRM_SIZE,                   RES_UL_SPACE,                   // [83..86
157         RES_BACKGROUND,                 RES_SHADOW,                     // [99..101
158         RES_COL,                        RES_COL,                        // [103
159         RES_TEXTGRID,                   RES_TEXTGRID,                   // [109
160         RES_FRAMEDIR,                   RES_FRAMEDIR,                   // [114
161         RES_HEADER_FOOTER_EAT_SPACING,  RES_HEADER_FOOTER_EAT_SPACING,  // [115
162         RES_UNKNOWNATR_CONTAINER,       RES_UNKNOWNATR_CONTAINER,       // [143
163 
164         //UUUU take over DrawingLayer FillStyles
165         XATTR_FILL_FIRST,               XATTR_FILL_LAST,                // [1014
166 
167         0};
168 
169 	const SfxPoolItem* pItem;
170 	for( sal_uInt16 n = 0; aIdArr[ n ]; n += 2 )
171 	{
172 		for( sal_uInt16 nId = aIdArr[ n ]; nId <= aIdArr[ n+1]; ++nId )
173 		{
174             // bPage == true:
175             // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
176             // bPage == false:
177             // All in aIdArr except from RES_COL and RES_PAPER_BIN:
178             bool bExecuteId(true);
179 
180             if(bPage)
181             {
182                 // When Page
183                 switch(nId)
184                 {
185                     // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
186                     case RES_HEADER_FOOTER_EAT_SPACING:
187                     //UUUU take out SvxBrushItem; it's the result of the fallback
188                     // at SwFmt::GetItemState and not really in state SFX_ITEM_SET
189                     case RES_BACKGROUND:
190                         bExecuteId = false;
191                         break;
192                     default:
193                         break;
194                 }
195             }
196             else
197             {
198                 // When not Page
199                 switch(nId)
200                 {
201                     // When not Page: All in aIdArr except from RES_COL and RES_PAPER_BIN:
202                     case RES_COL:
203                     case RES_PAPER_BIN:
204                         bExecuteId = false;
205                         break;
206                     default:
207                         break;
208                 }
209             }
210 
211             if(bExecuteId)
212             {
213                 if(SFX_ITEM_SET == rSource.GetItemState(nId,sal_False,&pItem))
214                 {
215                     rDest.SetFmtAttr(*pItem);
216                 }
217                 else
218                 {
219                     rDest.ResetFmtAttr(nId);
220                 }
221             }
222         }
223     }
224 
225 	// auch Pool-, Hilfe-Id's uebertragen
226 	rDest.SetPoolFmtId( rSource.GetPoolFmtId() );
227 	rDest.SetPoolHelpId( rSource.GetPoolHelpId() );
228 	rDest.SetPoolHlpFileId( rSource.GetPoolHlpFileId() );
229 }
230 
231 
232 void SwDoc::ChgPageDesc( sal_uInt16 i, const SwPageDesc &rChged )
233 {
234 	ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." );
235 
236 	SwPageDesc *pDesc = aPageDescs[i];
237 	SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
238 
239     if (GetIDocumentUndoRedo().DoesUndo())
240     {
241         SwUndo *const pUndo(new SwUndoPageDesc(*pDesc, rChged, this));
242         GetIDocumentUndoRedo().AppendUndo(pUndo);
243     }
244     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
245 
246 	//Als erstes wird ggf. gespiegelt.
247 	if ( rChged.GetUseOn() == nsUseOnPage::PD_MIRROR )
248 		((SwPageDesc&)rChged).Mirror();
249 	else
250 		//sonst Werte aus Master nach Left uebertragen.
251 		::lcl_DescSetAttr( ((SwPageDesc&)rChged).GetMaster(),
252 					   ((SwPageDesc&)rChged).GetLeft() );
253 
254     //NumType uebernehmen.
255 	if( rChged.GetNumType().GetNumberingType() != pDesc->GetNumType().GetNumberingType() )
256 	{
257 		pDesc->SetNumType( rChged.GetNumType() );
258 		// JP 30.03.99: Bug 64121 - den Seitennummernfeldern bescheid sagen,
259 		//		das sich das Num-Format geaendert hat
260 		GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds();
261 		GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds();
262 
263 		// Wenn sich die Numerierungsart geaendert hat, koennte es QuoVadis/
264 		// ErgoSum-Texte geben, die sich auf eine geaenderte Seite beziehen,
265 		// deshalb werden die Fussnoten invalidiert
266 		SwFtnIdxs& rFtnIdxs = GetFtnIdxs();
267 		for( sal_uInt16 nPos = 0; nPos < rFtnIdxs.Count(); ++nPos )
268 		{
269 			SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ];
270 			const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
271 			pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr());
272 		}
273 	}
274 
275 	//Orientierung uebernehmen
276 	pDesc->SetLandscape( rChged.GetLandscape() );
277 
278     // #i46909# no undo if header or footer changed
279     bool bHeaderFooterChanged = false;
280 
281 	//Header abgleichen.
282 	const SwFmtHeader &rHead = rChged.GetMaster().GetHeader();
283     if (undoGuard.UndoWasEnabled())
284     {
285         // #i46909# no undo if header or footer changed
286 		// hat sich an den Nodes etwas veraendert ?
287 		const SwFmtHeader &rOldHead = pDesc->GetMaster().GetHeader();
288         bHeaderFooterChanged |=
289             ( rHead.IsActive() != rOldHead.IsActive() ||
290               rChged.IsHeaderShared() != pDesc->IsHeaderShared() );
291 	}
292     pDesc->GetMaster().SetFmtAttr( rHead );
293 	if ( rChged.IsHeaderShared() || !rHead.IsActive() )
294 	{
295 		//Left teilt sich den Header mit dem Master.
296         pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetHeader() );
297 	}
298 	else if ( rHead.IsActive() )
299 	{	//Left bekommt einen eigenen Header verpasst wenn das Format nicht
300 		//bereits einen hat.
301 		//Wenn er bereits einen hat und dieser auf die gleiche Section
302 		//wie der Rechte zeigt, so muss er einen eigenen bekommen. Der
303 		//Inhalt wird sinnigerweise kopiert.
304 		const SwFmtHeader &rLeftHead = pDesc->GetLeft().GetHeader();
305 		if ( !rLeftHead.IsActive() )
306 		{
307             SwFmtHeader aHead( MakeLayoutFmt( RND_STD_HEADERL, 0 ) );
308             pDesc->GetLeft().SetFmtAttr( aHead );
309 			//Weitere Attribute (Raender, Umrandung...) uebernehmen.
310 			::lcl_DescSetAttr( *rHead.GetHeaderFmt(), *aHead.GetHeaderFmt(), sal_False);
311 		}
312 		else
313 		{
314 			const SwFrmFmt *pRight = rHead.GetHeaderFmt();
315 			const SwFmtCntnt &aRCnt = pRight->GetCntnt();
316 			const SwFmtCntnt &aLCnt = rLeftHead.GetHeaderFmt()->GetCntnt();
317 			if( !aLCnt.GetCntntIdx() )
318                 pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetHeader() );
319             else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) )
320 			{
321 				SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Header",
322 												GetDfltFrmFmt() );
323 				::lcl_DescSetAttr( *pRight, *pFmt, sal_False );
324 				//Der Bereich auf den das rechte Kopfattribut zeigt wird
325 				//kopiert und der Index auf den StartNode in das linke
326 				//Kopfattribut gehaengt.
327 				SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
328 				SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwHeaderStartNode );
329 				SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0,
330 							*aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() );
331 				aTmp = *pSttNd->EndOfSectionNode();
332 				GetNodes()._Copy( aRange, aTmp, sal_False );
333 
334                 pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) );
335                 pDesc->GetLeft().SetFmtAttr( SwFmtHeader( pFmt ) );
336 			}
337 			else
338 				::lcl_DescSetAttr( *pRight,
339 							   *(SwFrmFmt*)rLeftHead.GetHeaderFmt(), sal_False );
340 
341 		}
342 	}
343 	pDesc->ChgHeaderShare( rChged.IsHeaderShared() );
344 
345 	//Footer abgleichen.
346 	const SwFmtFooter &rFoot = rChged.GetMaster().GetFooter();
347     if (undoGuard.UndoWasEnabled())
348     {
349         // #i46909# no undo if header or footer changed
350 		// hat sich an den Nodes etwas veraendert ?
351         const SwFmtFooter &rOldFoot = pDesc->GetMaster().GetFooter();
352         bHeaderFooterChanged |=
353             ( rFoot.IsActive() != rOldFoot.IsActive() ||
354               rChged.IsFooterShared() != pDesc->IsFooterShared() );
355     }
356     pDesc->GetMaster().SetFmtAttr( rFoot );
357 	if ( rChged.IsFooterShared() || !rFoot.IsActive() )
358 		//Left teilt sich den Header mit dem Master.
359         pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetFooter() );
360 	else if ( rFoot.IsActive() )
361 	{	//Left bekommt einen eigenen Footer verpasst wenn das Format nicht
362 		//bereits einen hat.
363 		//Wenn er bereits einen hat und dieser auf die gleiche Section
364 		//wie der Rechte zeigt, so muss er einen eigenen bekommen. Der
365 		//Inhalt wird sinnigerweise kopiert.
366 		const SwFmtFooter &rLeftFoot = pDesc->GetLeft().GetFooter();
367 		if ( !rLeftFoot.IsActive() )
368 		{
369             SwFmtFooter aFoot( MakeLayoutFmt( RND_STD_FOOTER, 0 ) );
370             pDesc->GetLeft().SetFmtAttr( aFoot );
371 			//Weitere Attribute (Raender, Umrandung...) uebernehmen.
372 			::lcl_DescSetAttr( *rFoot.GetFooterFmt(), *aFoot.GetFooterFmt(), sal_False);
373 		}
374 		else
375 		{
376 			const SwFrmFmt *pRight = rFoot.GetFooterFmt();
377 			const SwFmtCntnt &aRCnt = pRight->GetCntnt();
378 			const SwFmtCntnt &aLCnt = rLeftFoot.GetFooterFmt()->GetCntnt();
379 			if( !aLCnt.GetCntntIdx() )
380                 pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetFooter() );
381 			else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) )
382 			{
383 				SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Footer",
384 												GetDfltFrmFmt() );
385 				::lcl_DescSetAttr( *pRight, *pFmt, sal_False );
386 				//Der Bereich auf den das rechte Kopfattribut zeigt wird
387 				//kopiert und der Index auf den StartNode in das linke
388 				//Kopfattribut gehaengt.
389 				SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
390 				SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwFooterStartNode );
391 				SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0,
392 							*aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() );
393 				aTmp = *pSttNd->EndOfSectionNode();
394 				GetNodes()._Copy( aRange, aTmp, sal_False );
395 
396                 pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) );
397                 pDesc->GetLeft().SetFmtAttr( SwFmtFooter( pFmt ) );
398 			}
399 			else
400 				::lcl_DescSetAttr( *pRight,
401 							   *(SwFrmFmt*)rLeftFoot.GetFooterFmt(), sal_False );
402 		}
403 	}
404 	pDesc->ChgFooterShare( rChged.IsFooterShared() );
405 
406 	if ( pDesc->GetName() != rChged.GetName() )
407 		pDesc->SetName( rChged.GetName() );
408 
409 	// Dadurch wird ein RegisterChange ausgeloest, wenn notwendig
410 	pDesc->SetRegisterFmtColl( rChged.GetRegisterFmtColl() );
411 
412 	//Wenn sich das UseOn oder der Follow aendern muessen die
413 	//Absaetze das erfahren.
414 	sal_Bool bUseOn  = sal_False;
415 	sal_Bool bFollow = sal_False;
416 	if ( pDesc->GetUseOn() != rChged.GetUseOn() )
417 	{   pDesc->SetUseOn( rChged.GetUseOn() );
418 		bUseOn = sal_True;
419 	}
420 	if ( pDesc->GetFollow() != rChged.GetFollow() )
421 	{	if ( rChged.GetFollow() == &rChged )
422 		{	if ( pDesc->GetFollow() != pDesc )
423 			{	pDesc->SetFollow( pDesc );
424 				bFollow = sal_True;
425 			}
426 		}
427 		else
428 		{	pDesc->SetFollow( rChged.pFollow );
429 			bFollow = sal_True;
430 		}
431 	}
432 
433 	if ( (bUseOn || bFollow) && pTmpRoot)
434 		//Layot benachrichtigen!
435 	{
436 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
437 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080304
438 	}
439 
440 	//Jetzt noch die Seiten-Attribute uebernehmen.
441 	::lcl_DescSetAttr( rChged.GetMaster(), pDesc->GetMaster() );
442 	::lcl_DescSetAttr( rChged.GetLeft(), pDesc->GetLeft() );
443 
444 	//Wenn sich FussnotenInfo veraendert, so werden die Seiten
445 	//angetriggert.
446 	if( !(pDesc->GetFtnInfo() == rChged.GetFtnInfo()) )
447 	{
448 		pDesc->SetFtnInfo( rChged.GetFtnInfo() );
449 		SwMsgPoolItem  aInfo( RES_PAGEDESC_FTNINFO );
450 		{
451             pDesc->GetMaster().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) );
452 		}
453 		{
454             pDesc->GetLeft().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) );
455 		}
456 	}
457 	SetModified();
458 
459     // #i46909# no undo if header or footer changed
460     if( bHeaderFooterChanged )
461     {
462         GetIDocumentUndoRedo().DelAllUndoObj();
463     }
464 
465     SfxBindings* pBindings =
466         ( GetDocShell() && GetDocShell()->GetDispatcher() ) ? GetDocShell()->GetDispatcher()->GetBindings() : 0;
467     if ( pBindings )
468     {
469         pBindings->Invalidate( SID_ATTR_PAGE_COLUMN );
470         pBindings->Invalidate( SID_ATTR_PAGE );
471         pBindings->Invalidate( SID_ATTR_PAGE_SIZE );
472         pBindings->Invalidate( SID_ATTR_PAGE_ULSPACE );
473         pBindings->Invalidate( SID_ATTR_PAGE_LRSPACE );
474     }
475 
476 }
477 
478 /*************************************************************************
479 |*
480 |*	SwDoc::DelPageDesc()
481 |*
482 |* 	Beschreibung		Alle Descriptoren, deren Follow auf den zu loeschenden
483 |*		zeigen muessen angepasst werden.
484 |*	Ersterstellung		MA 25. Jan. 93
485 |*	Letzte Aenderung	JP 04.09.95
486 |*
487 |*************************************************************************/
488 
489 // #i7983#
490 void SwDoc::PreDelPageDesc(SwPageDesc * pDel)
491 {
492     if (0 == pDel)
493         return;
494 
495     // mba: test iteration as clients are removed while iteration
496     SwPageDescHint aHint( aPageDescs[0] );
497     pDel->CallSwClientNotify( aHint );
498 
499     bool bHasLayout = HasLayout();
500     if ( pFtnInfo->DependsOn( pDel ) )
501     {
502         pFtnInfo->ChgPageDesc( aPageDescs[0] );
503         if ( bHasLayout )
504         {
505             std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
506             std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), false));
507         }
508     }
509     else if ( pEndNoteInfo->DependsOn( pDel ) )
510     {
511         pEndNoteInfo->ChgPageDesc( aPageDescs[0] );
512         if ( bHasLayout )
513         {
514             std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
515             std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), true));
516         }
517     }
518 
519     for ( sal_uInt16 j = 0; j < aPageDescs.Count(); ++j )
520     {
521         if ( aPageDescs[j]->GetFollow() == pDel )
522         {
523             aPageDescs[j]->SetFollow( 0 );
524             if( bHasLayout )
525             {
526                 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
527                 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080228
528             }
529         }
530     }
531 }
532 
533 // #116530#
534 void SwDoc::BroadcastStyleOperation(String rName, SfxStyleFamily eFamily,
535                                     sal_uInt16 nOp)
536 {
537     if (pDocShell)
538     {
539         SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool();
540 
541         if (pPool)
542         {
543             pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
544             SfxStyleSheetBase * pBase = pPool->Find(rName);
545 
546             if (pBase != NULL)
547                 pPool->Broadcast(SfxStyleSheetHint( nOp, *pBase ));
548         }
549     }
550 }
551 
552 void SwDoc::DelPageDesc( sal_uInt16 i, sal_Bool bBroadcast )
553 {
554 	ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." );
555 	ASSERT( i != 0, "Default Pagedesc loeschen is nicht." );
556 	if ( i == 0 )
557 		return;
558 
559 	SwPageDesc *pDel = aPageDescs[i];
560 
561     // -> #116530#
562     if (bBroadcast)
563         BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PAGE,
564                                 SFX_STYLESHEET_ERASED);
565     // <- #116530#
566 
567     if (GetIDocumentUndoRedo().DoesUndo())
568     {
569         SwUndo *const pUndo(new SwUndoPageDescDelete(*pDel, this));
570         GetIDocumentUndoRedo().AppendUndo(pUndo);
571     }
572 
573     PreDelPageDesc(pDel); // #i7983#
574 
575 	aPageDescs.Remove( i );
576 	delete pDel;
577 	SetModified();
578 }
579 
580 
581 
582 /*************************************************************************
583 |*
584 |*	SwDoc::MakePageDesc()
585 |*
586 |*	Ersterstellung		MA 25. Jan. 93
587 |*	Letzte Aenderung	MA 20. Aug. 93
588 |*
589 |*************************************************************************/
590 
591 sal_uInt16 SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy,
592                             sal_Bool bRegardLanguage, sal_Bool bBroadcast) // #116530#
593 {
594 	SwPageDesc *pNew;
595 	if( pCpy )
596 	{
597 		pNew = new SwPageDesc( *pCpy );
598 		pNew->SetName( rName );
599 		if( rName != pCpy->GetName() )
600 		{
601 			pNew->SetPoolFmtId( USHRT_MAX );
602 			pNew->SetPoolHelpId( USHRT_MAX );
603 			pNew->SetPoolHlpFileId( UCHAR_MAX );
604 		}
605 	}
606 	else
607 	{
608 		pNew = new SwPageDesc( rName, GetDfltFrmFmt(), this );
609 		//Default-Seitenformat einstellen.
610         lcl_DefaultPageFmt( USHRT_MAX, pNew->GetMaster(), pNew->GetLeft() );
611 
612 		SvxFrameDirection aFrameDirection = bRegardLanguage ?
613             GetDefaultFrameDirection(GetAppLanguage())
614             : FRMDIR_HORI_LEFT_TOP;
615 
616         pNew->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
617         pNew->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
618 	}
619 	aPageDescs.Insert( pNew, aPageDescs.Count() );
620 
621     // -> #116530#
622     if (bBroadcast)
623         BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE,
624                                 SFX_STYLESHEET_CREATED);
625     // <- #116530#
626 
627     if (GetIDocumentUndoRedo().DoesUndo())
628     {
629         // #116530#
630         GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew, this));
631     }
632 
633 	SetModified();
634 	return (aPageDescs.Count()-1);
635 }
636 
637 SwPageDesc* SwDoc::FindPageDescByName( const String& rName, sal_uInt16* pPos ) const
638 {
639 	SwPageDesc* pRet = 0;
640 	if( pPos ) *pPos = USHRT_MAX;
641 
642 	for( sal_uInt16 n = 0, nEnd = aPageDescs.Count(); n < nEnd; ++n )
643 		if( aPageDescs[ n ]->GetName() == rName )
644 		{
645 			pRet = aPageDescs[ n ];
646 			if( pPos )
647 				*pPos = n;
648 			break;
649 		}
650 	return pRet;
651 }
652 
653 /******************************************************************************
654  *  Methode     :   void SwDoc::PrtDataChanged()
655  *	Beschreibung:
656  *	Erstellt	:	OK 27.10.94 10:20
657  *	Aenderung	:	MA 26. Mar. 98
658  ******************************************************************************/
659 
660 void SwDoc::PrtDataChanged()
661 {
662 //!!!!!!!! Bei Aenderungen hier bitte ggf. InJobSetup im Sw3io mitpflegen
663 
664     // --> FME 2005-01-21 #i41075#
665     ASSERT( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ||
666             0 != getPrinter( sal_False ), "PrtDataChanged will be called recursive!" )
667     // <--
668 	SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
669 	SwWait *pWait = 0;
670 	sal_Bool bEndAction = sal_False;
671 
672 	if( GetDocShell() )
673 		GetDocShell()->UpdateFontList();
674 
675 	sal_Bool bDraw = sal_True;
676 	if ( pTmpRoot )
677 	{
678 		ViewShell *pSh = GetCurrentViewShell();
679         if( !pSh->GetViewOptions()->getBrowseMode() ||
680             pSh->GetViewOptions()->IsPrtFormat() )
681 		{
682 			if ( GetDocShell() )
683 				pWait = new SwWait( *GetDocShell(), true );
684 
685 			pTmpRoot->StartAllAction();
686 			bEndAction = sal_True;
687 
688 			bDraw = sal_False;
689 			if( pDrawModel )
690             {
691                 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
692                 pDrawModel->SetRefDevice( getReferenceDevice( false ) );
693             }
694 
695 			pFntCache->Flush();
696 
697 			std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
698 			std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));//swmod 080304
699 
700 			if ( pSh )
701 			{
702 				do
703                 {
704                     pSh->InitPrt( pPrt );
705 					pSh = (ViewShell*)pSh->GetNext();
706                 }
707                 while ( pSh != GetCurrentViewShell() );
708 			}
709 
710 		}
711 	}	//swmod 080218
712     if ( bDraw && pDrawModel )
713     {
714         const sal_Bool bTmpAddExtLeading = get(IDocumentSettingAccess::ADD_EXT_LEADING);
715         if ( bTmpAddExtLeading != pDrawModel->IsAddExtLeading() )
716             pDrawModel->SetAddExtLeading( bTmpAddExtLeading );
717 
718         OutputDevice* pOutDev = getReferenceDevice( false );
719         if ( pOutDev != pDrawModel->GetRefDevice() )
720             pDrawModel->SetRefDevice( pOutDev );
721     }
722 
723 	PrtOLENotify( sal_True );
724 
725 	if ( bEndAction )
726 		pTmpRoot->EndAllAction();	//swmod 080218
727 	delete pWait;
728 }
729 
730 //Zur Laufzeit sammeln wir die GlobalNames der Server, die keine
731 //Benachrichtigung zu Druckerwechseln wuenschen. Dadurch sparen wir
732 //das Laden vieler Objekte (gluecklicherweise werden obendrein alle
733 //Fremdobjekte unter einer ID abgebuildet). Init und DeInit vom Array
734 //ist in init.cxx zu finden.
735 extern SvPtrarr *pGlobalOLEExcludeList;
736 
737 void SwDoc::PrtOLENotify( sal_Bool bAll )
738 {
739 	SwFEShell *pShell = 0;
740 	if ( GetCurrentViewShell() )
741 	{
742 		ViewShell *pSh = GetCurrentViewShell();
743 		if ( !pSh->ISA(SwFEShell) )
744 			do
745 			{	pSh = (ViewShell*)pSh->GetNext();
746 			} while ( !pSh->ISA(SwFEShell) &&
747 					  pSh != GetCurrentViewShell() );
748 
749 		if ( pSh->ISA(SwFEShell) )
750 			pShell = (SwFEShell*)pSh;
751 	}	//swmod 071107//swmod 071225
752 	if ( !pShell )
753 	{
754 		//Das hat ohne Shell und damit ohne Client keinen Sinn, weil nur darueber
755 		//die Kommunikation bezueglich der Groessenaenderung implementiert ist.
756 		//Da wir keine Shell haben, merken wir uns diesen unguenstigen
757 		//Zustand am Dokument, dies wird dann beim Erzeugen der ersten Shell
758 		//nachgeholt.
759 		mbOLEPrtNotifyPending = sal_True;
760 		if ( bAll )
761 			mbAllOLENotify = sal_True;
762 	}
763 	else
764 	{
765 		if ( mbAllOLENotify )
766 			bAll = sal_True;
767 
768 		mbOLEPrtNotifyPending = mbAllOLENotify = sal_False;
769 
770 		SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), !bAll );
771 		if ( pNodes )
772 		{
773 			::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY,
774 							 0, pNodes->Count(), GetDocShell());
775 			GetCurrentLayout()->StartAllAction();	//swmod 080218
776 
777 			for( sal_uInt16 i = 0; i < pNodes->Count(); ++i )
778 			{
779 				::SetProgressState( i, GetDocShell() );
780 
781 				SwOLENode* pOLENd = (*pNodes)[i];
782 				pOLENd->SetOLESizeInvalid( sal_False );
783 
784 				//Ersteinmal die Infos laden und festellen ob das Teil nicht
785 				//schon in der Exclude-Liste steht
786 				SvGlobalName aName;
787 
788                 svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject();
789                 if ( xObj.is() )
790                     aName = SvGlobalName( xObj->getClassID() );
791                 else  //Noch nicht geladen
792 				{
793                         // TODO/LATER: retrieve ClassID of an unloaded object
794                         // aName = ????
795                 }
796 
797 				sal_Bool bFound = sal_False;
798 				for ( sal_uInt16 j = 0;
799 					  j < pGlobalOLEExcludeList->Count() && !bFound;
800 					  ++j )
801 				{
802 					bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[j] ==
803 									aName;
804 				}
805 				if ( bFound )
806 					continue;
807 
808 				//Kennen wir nicht, also muss das Objekt geladen werden.
809 				//Wenn es keine Benachrichtigung wuenscht
810                 if ( xObj.is() )
811 				{
812                     //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange
813                     /*
814 					if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus())
815 					{
816 						if ( pOLENd->GetFrm() )
817 						{
818                             xObj->OnDocumentPrinterChanged( pPrt );
819                             pShell->CalcAndSetScale( xObj );//Client erzeugen lassen.
820 						}
821 						else
822 							pOLENd->SetOLESizeInvalid( sal_True );
823                     }
824                     else */
825 						pGlobalOLEExcludeList->Insert(
826                                 new SvGlobalName( aName ),
827 								pGlobalOLEExcludeList->Count() );
828 				}
829 			}
830 			delete pNodes;
831 			GetCurrentLayout()->EndAllAction();	//swmod 080218
832 			::EndProgress( GetDocShell() );
833 		}
834 	}
835 }
836 
837 IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, )
838 {
839 	SwFEShell* pSh = (SwFEShell*)GetEditShell();
840 	if( pSh )
841 	{
842 		mbOLEPrtNotifyPending = mbAllOLENotify = sal_False;
843 
844 		SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), true );
845 		if( pNodes )
846 		{
847 			::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY,
848 							 0, pNodes->Count(), GetDocShell());
849 			GetCurrentLayout()->StartAllAction();	//swmod 080218
850 			SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR );
851 
852 			for( sal_uInt16 i = 0; i < pNodes->Count(); ++i )
853 			{
854 				::SetProgressState( i, GetDocShell() );
855 
856 				SwOLENode* pOLENd = (*pNodes)[i];
857 				pOLENd->SetOLESizeInvalid( sal_False );
858 
859 				//Kennen wir nicht, also muss das Objekt geladen werden.
860 				//Wenn es keine Benachrichtigung wuenscht
861                 if( pOLENd->GetOLEObj().GetOleRef().is() ) //Kaputt?
862 				{
863                     //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange
864                     /*
865 					if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE &
866 							xRef->GetMiscStatus() )
867 					{
868 						if( pOLENd->GetFrm() )
869 						{
870 							xRef->OnDocumentPrinterChanged( pPrt );
871 							pSh->CalcAndSetScale( xRef );//Client erzeugen lassen.
872 						}
873 						else
874 							pOLENd->SetOLESizeInvalid( sal_True );
875                     }*/
876 					// repaint it
877 					pOLENd->ModifyNotification( &aMsgHint, &aMsgHint );
878 				}
879 			}
880 			GetCurrentLayout()->EndAllAction();	//swmod 080218
881 			::EndProgress( GetDocShell() );
882             delete pNodes;
883 		}
884 	}
885 	return 0;
886 }
887 
888 sal_Bool SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound)
889 {
890     sal_Bool bResult = sal_False;
891     sal_uInt16 nI;
892     for (nI = 0; nI < aPageDescs.Count(); nI++)
893     {
894         if (aPageDescs[nI]->GetName() == rName)
895         {
896             *pFound = nI;
897             bResult = sal_True;
898             break;
899         }
900     }
901 
902     return bResult;
903 }
904 
905 SwPageDesc * SwDoc::GetPageDesc( const String & rName )
906 {
907     SwPageDesc * aResult = NULL;
908 
909     sal_uInt16 nI;
910 
911     if (FindPageDesc(rName, &nI))
912         aResult = aPageDescs[nI];
913 
914     return aResult;
915 }
916 
917 void SwDoc::DelPageDesc( const String & rName, sal_Bool bBroadcast ) // #116530#
918 {
919     sal_uInt16 nI;
920 
921     if (FindPageDesc(rName, &nI))
922         DelPageDesc(nI, bBroadcast); // #116530#
923 }
924 
925 void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc)
926 {
927     sal_uInt16 nI;
928 
929     if (FindPageDesc(rName, &nI))
930         ChgPageDesc(nI, rDesc);
931 }
932 
933 /*
934  * The HTML import cannot resist changing the page descriptions, I don't
935  * know why. This function is meant to check the page descriptors for invalid
936  * values.
937  */
938 void SwDoc::CheckDefaultPageFmt()
939 {
940     for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i )
941     {
942         SwPageDesc& rDesc = _GetPageDesc( i );
943 
944         SwFrmFmt& rMaster = rDesc.GetMaster();
945         SwFrmFmt& rLeft   = rDesc.GetLeft();
946 
947         const SwFmtFrmSize& rMasterSize  = rMaster.GetFrmSize();
948         const SwFmtFrmSize& rLeftSize    = rLeft.GetFrmSize();
949 
950         const bool bSetSize = LONG_MAX == rMasterSize.GetWidth() ||
951                               LONG_MAX == rMasterSize.GetHeight() ||
952                               LONG_MAX == rLeftSize.GetWidth() ||
953                               LONG_MAX == rLeftSize.GetHeight();
954 
955         if ( bSetSize )
956             lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft() );
957     }
958 }
959 
960 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode)
961 {
962     if( !bSquaredPageMode == !IsSquaredPageMode() )
963 		return;
964 
965 	const SwTextGridItem& rGrid =
966 					(const SwTextGridItem&)GetDefault( RES_TEXTGRID );
967 	SwTextGridItem aNewGrid = rGrid;
968 	aNewGrid.SetSquaredMode(bSquaredPageMode);
969 	aNewGrid.Init();
970 	SetDefault(aNewGrid);
971 
972     for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i )
973     {
974         SwPageDesc& rDesc = _GetPageDesc( i );
975 
976         SwFrmFmt& rMaster = rDesc.GetMaster();
977 		SwFrmFmt& rLeft = rDesc.GetLeft();
978 
979         SwTextGridItem aGrid((SwTextGridItem&)rMaster.GetFmtAttr(RES_TEXTGRID));
980         aGrid.SwitchPaperMode( bSquaredPageMode );
981         rMaster.SetFmtAttr(aGrid);
982         rLeft.SetFmtAttr(aGrid);
983     }
984 }
985 
986 sal_Bool SwDoc::IsSquaredPageMode() const
987 {
988 	const SwTextGridItem& rGrid =
989 						(const SwTextGridItem&)GetDefault( RES_TEXTGRID );
990 	return rGrid.IsSquaredMode();
991 }
992