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