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