xref: /trunk/main/sd/source/core/drawdoc3.cxx (revision 79aad27f)
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_sd.hxx"
26 
27 
28 #include <com/sun/star/embed/ElementModes.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 
31 #include "comphelper/anytostring.hxx"
32 #include "cppuhelper/exc_hlp.hxx"
33 
34 #include <utility>
35 #include <algorithm>
36 #include <vcl/wrkwin.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sot/storage.hxx>
39 #include <sfx2/app.hxx>
40 #include <svl/itemset.hxx>
41 
42 #include <unotools/ucbstreamhelper.hxx>
43 #include <sfx2/fcontnr.hxx>
44 #include <svx/svdopath.hxx>
45 #include <svx/svditer.hxx>
46 #include <svl/style.hxx>
47 #include <sfx2/linkmgr.hxx>
48 #include <svx/svdpagv.hxx>
49 #include <svx/svdogrp.hxx>
50 #include <svx/svdundo.hxx>
51 #include <vcl/msgbox.hxx>
52 #include <sot/storage.hxx>
53 #include <sot/formats.hxx>
54 
55 #include <set>
56 #include <boost/bind.hpp>
57 
58 #include "glob.hrc"
59 #include "drawdoc.hxx"
60 #include "sdpage.hxx"
61 #include "stlpool.hxx"
62 #include "sdresid.hxx"
63 #include "sdiocmpt.hxx"
64 #include "strmname.h"
65 #include "anminfo.hxx"
66 
67 #include "../ui/inc/unmovss.hxx"
68 #include "../ui/inc/unchss.hxx"
69 #include "../ui/inc/unprlout.hxx"
70 #include "../ui/inc/DrawDocShell.hxx"
71 #include "../ui/inc/GraphicDocShell.hxx"
72 #include "../ui/inc/ViewShell.hxx"
73 #include "../ui/inc/View.hxx"
74 #include "../ui/inc/cfgids.hxx"
75 #include "../ui/inc/strings.hrc"
76 
77 using namespace ::com::sun::star;
78 
79 #define POOL_BUFFER_SIZE		(sal_uInt16)32768
80 #define BASIC_BUFFER_SIZE		(sal_uInt16)8192
81 #define DOCUMENT_BUFFER_SIZE	(sal_uInt16)32768
82 
83 /*************************************************************************
84 |*
85 |* Oeffnet ein Bookmark-Dokument
86 |*
87 \************************************************************************/
88 /*
89 SdStorageListener : public BaseImplHelper1 < lang::XEventListener >
90 {
91     uno::Reference < embed::XStorage >& xStor;
92 public:
93             SdStorageListener ( uno::Reference < embed::XStorage >& rStor )
94                 : xStor( rStor )
95             {}
96 
97     void disposing ( const lang::EventObject& aEvent ) throw ( uno::RuntimeException );
98 };
99 
100 void SdStorageListener::disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException )
101 {
102     xStor = NULL;
103 }*/
104 
105 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(SfxMedium& rMedium)
106 {
107 	sal_Bool bOK = sal_True;
108 	SdDrawDocument* pBookmarkDoc = NULL;
109 	String aBookmarkName = rMedium.GetName();
110     const SfxFilter* pFilter = rMedium.GetFilter();
111     if ( !pFilter )
112     {
113         rMedium.UseInteractionHandler( sal_True );
114         SFX_APP()->GetFilterMatcher().GuessFilter( rMedium, &pFilter );
115     }
116 
117     if ( !pFilter )
118     {
119         bOK = sal_False;
120     }
121     else if ( maBookmarkFile != aBookmarkName && aBookmarkName.Len() )
122 	{
123         sal_Bool bCreateGraphicShell = pFilter->GetServiceName().EqualsAscii( "com.sun.star.drawing.DrawingDocument" );
124         sal_Bool bCreateImpressShell = pFilter->GetServiceName().EqualsAscii( "com.sun.star.presentation.PresentationDocument" );
125         if ( bCreateGraphicShell || bCreateImpressShell )
126         {
127 			CloseBookmarkDoc();
128 
129 			// Es wird eine DocShell erzeugt, da in dem Dokument OLE-Objekte
130 			// enthalten sein koennten (Persist)
131 			// Wenn dem nicht so waere, so koennte man auch das Model
132 			// direkt laden
133             if ( bCreateGraphicShell )
134                 // Draw
135 				mxBookmarkDocShRef = new ::sd::GraphicDocShell(SFX_CREATE_MODE_STANDARD, sal_True);
136             else
137 				// Impress
138 				mxBookmarkDocShRef = new ::sd::DrawDocShell(SFX_CREATE_MODE_STANDARD, sal_True);
139 
140 			bOK = mxBookmarkDocShRef->DoLoad(&rMedium);
141             if( bOK )
142             {
143                 maBookmarkFile = aBookmarkName;
144 				pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
145             }
146 		}
147 	}
148 
149     DBG_ASSERT(aBookmarkName.Len(), "Empty document name!");
150 
151 	if (!bOK)
152 	{
153 		ErrorBox aErrorBox( NULL, (WinBits)WB_OK, String(SdResId(STR_READ_DATA_ERROR)));
154 		aErrorBox.Execute();
155 
156 		CloseBookmarkDoc();
157 		pBookmarkDoc = NULL;
158 	}
159 	else if (mxBookmarkDocShRef.Is())
160 	{
161 		pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
162 	}
163 
164 	return(pBookmarkDoc);
165 }
166 
167 /*************************************************************************
168 |*
169 |* Oeffnet ein Bookmark-Dokument
170 |*
171 \************************************************************************/
172 
173 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(const String& rBookmarkFile)
174 {
175 	SdDrawDocument* pBookmarkDoc = NULL;
176 
177 	if (maBookmarkFile != rBookmarkFile && rBookmarkFile.Len())
178 	{
179         SfxMedium* pMedium = new SfxMedium( rBookmarkFile, STREAM_READ, sal_False );
180         pBookmarkDoc = OpenBookmarkDoc(*pMedium);
181 	}
182 	else if (mxBookmarkDocShRef.Is())
183 	{
184 		pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
185 	}
186 
187 	return(pBookmarkDoc);
188 }
189 
190 /*************************************************************************
191 |*
192 |* Fuegt ein Bookmark (Seite oder Objekt) ein
193 |*
194 \************************************************************************/
195 
196 sal_Bool SdDrawDocument::InsertBookmark(
197 	List* pBookmarkList,			// Liste der Namen der einzufuegenden Bookmarks
198 	List* pExchangeList,            // Liste der zu verwendenen Namen
199 	sal_Bool bLink, 					// Bookmarks sollen als Verknuepfung eingefuegt werden
200 	sal_Bool bReplace,					// Aktuellen Seiten (Standard&Notiz) werden ersetzt
201 	sal_uInt16 nInsertPos,				// Einfuegeposition fuer Seiten
202 	sal_Bool bNoDialogs,				// Keine Dialoge anzeigen
203 	::sd::DrawDocShell* pBookmarkDocSh, // Wenn gesetzt, so ist dieses das Source-Dokument
204 	sal_Bool bCopy,                     // Seiten werden kopiert
205 	Point* pObjPos)                 // Einfuegeposition fuer Objekte
206 {
207 	sal_Bool bOK = sal_True;
208 	sal_Bool bInsertPages = sal_False;
209 
210 	if (!pBookmarkList)
211 	{
212 		/**********************************************************************
213 		* Alle Seiten werden eingefuegt
214 		**********************************************************************/
215 		bInsertPages = sal_True;
216 	}
217 	else
218 	{
219 		SdDrawDocument* pBookmarkDoc = NULL;
220 		String aBookmarkName;
221 
222 		if (pBookmarkDocSh)
223 		{
224 			pBookmarkDoc = pBookmarkDocSh->GetDoc();
225 			aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
226 		}
227 		else if ( mxBookmarkDocShRef.Is() )
228 		{
229 			pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
230 			aBookmarkName = maBookmarkFile;
231 		}
232 		else
233 			bOK = sal_False;
234 
235 		for (sal_uInt16 nPos = 0; bOK && ( nPos < pBookmarkList->Count() ) && !bInsertPages; nPos++)
236 		{
237 			/******************************************************************
238 			* Gibt es in der Bookmark-Liste einen Seitennamen?
239 			******************************************************************/
240 			String  aBMPgName (*(String*) pBookmarkList->GetObject(nPos));
241             sal_Bool    bIsMasterPage;
242 
243 			if( pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
244 			{
245 				// Seite gefunden
246 				bInsertPages = sal_True;
247 			}
248 		}
249 	}
250 
251 	if ( bOK && bInsertPages )
252 	{
253 		// Zuerst werden alle Seiten-Bookmarks eingefuegt
254 		bOK = InsertBookmarkAsPage(pBookmarkList, pExchangeList, bLink, bReplace,
255 								   nInsertPos, bNoDialogs, pBookmarkDocSh, bCopy, sal_True, sal_False);
256 	}
257 
258 	if ( bOK && pBookmarkList )
259 	{
260 		// Es werden alle Objekt-Bookmarks eingefuegt
261 		bOK = InsertBookmarkAsObject(pBookmarkList, pExchangeList, bLink,
262 									 pBookmarkDocSh, pObjPos);
263 	}
264 
265 	return bOK;
266 }
267 
268 /*************************************************************************
269 |*
270 |* Fuegt ein Bookmark als Seite ein
271 |*
272 \************************************************************************/
273 
274 /** Concrete incarnations get called by IterateBookmarkPages, for
275     every page in the bookmark document/list
276  */
277 class SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase
278 {
279 public:
280     virtual ~InsertBookmarkAsPage_PageFunctorBase() = 0;
281     virtual void operator()( SdDrawDocument&, SdPage* ) = 0;
282 };
283 
284 SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase::~InsertBookmarkAsPage_PageFunctorBase()
285 {
286 }
287 
288 void SdDrawDocument::IterateBookmarkPages( SdDrawDocument* pBookmarkDoc, List* pBookmarkList, sal_uInt16 nBMSdPageCount,
289                                            SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase& rPageIterator )
290 {
291     //
292     // #96029# Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage
293     //
294     int nPos, nEndPos;
295 
296     if( !pBookmarkList )
297     {
298         // no list? whole source document
299         nEndPos = nBMSdPageCount;
300     }
301     else
302     {
303         // bookmark list? number of entries
304         nEndPos = pBookmarkList->Count();
305     }
306 
307     SdPage* pBMPage;
308 
309     // iterate over number of pages to insert
310     for (nPos = 0; nPos < nEndPos; ++nPos)
311     {
312         // the master page associated to the nPos'th page to insert
313         SdPage* pBMMPage = NULL;
314 
315         if( !pBookmarkList )
316         {
317             // simply take master page of nPos'th page in source document
318 			pBMMPage = (SdPage*)(&(pBookmarkDoc->GetSdPage((sal_uInt16)nPos, PK_STANDARD)->TRG_GetMasterPage()));
319         }
320         else
321         {
322             // fetch nPos'th entry from bookmark list, and determine master page
323 			String  aBMPgName (*(String*) pBookmarkList->GetObject(nPos));
324             sal_Bool    bIsMasterPage;
325 
326 			sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage );
327 
328 			if (nBMPage != SDRPAGE_NOTFOUND)
329 			{
330 				pBMPage = (SdPage*) pBookmarkDoc->GetPage(nBMPage);
331 			}
332 			else
333 			{
334 				pBMPage = NULL;
335 			}
336 
337             // enforce that bookmarked page is a standard page and not already a master page
338 			if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage())
339 			{
340 				const sal_uInt16 nBMSdPage = (nBMPage - 1) / 2;
341                 pBMMPage = (SdPage*) (&(pBookmarkDoc->GetSdPage(nBMSdPage, PK_STANDARD)->TRG_GetMasterPage()));
342             }
343         }
344 
345         // successfully determined valid (bookmarked) page?
346         if( pBMMPage )
347         {
348             // yes, call functor
349             rPageIterator( *this, pBMMPage );
350         }
351     }
352 }
353 
354 class InsertBookmarkAsPage_FindDuplicateLayouts : public SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase
355 {
356 public:
357     InsertBookmarkAsPage_FindDuplicateLayouts( List* pLayoutsToTransfer, SdDrawDocument* pBookmarkDoc,
358                                                List* pBookmarkList, sal_uInt16 nBMSdPageCount ) :
359         mpLayoutsToTransfer(pLayoutsToTransfer), mpBookmarkDoc(pBookmarkDoc),
360         mpBookmarkList(pBookmarkList), mnBMSdPageCount(nBMSdPageCount) {}
361     virtual ~InsertBookmarkAsPage_FindDuplicateLayouts() {};
362     virtual void operator()( SdDrawDocument&, SdPage* );
363 private:
364     List* 			mpLayoutsToTransfer;
365     SdDrawDocument* mpBookmarkDoc;
366     List* 			mpBookmarkList;
367     sal_uInt16 			mnBMSdPageCount;
368 };
369 
370 void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage* pBMMPage )
371 {
372     // now check for duplicate masterpage and layout names
373     // ===================================================
374 
375     String  sFullLayoutName( pBMMPage->GetLayoutName() );
376     String* pLayout = new String(sFullLayoutName);
377     pLayout->Erase( pLayout->SearchAscii( SD_LT_SEPARATOR ));
378 
379     String* pTest = (String*) mpLayoutsToTransfer->First();
380     sal_Bool bFound = sal_False;
381 
382     while (pTest && !bFound)	// found yet?
383     {
384         if (*pLayout == *pTest)
385             bFound = sal_True;
386         else
387             pTest = (String*)mpLayoutsToTransfer->Next();
388     }
389 
390     const sal_uInt16 nMPageCount = rDoc.GetMasterPageCount();
391     for (sal_uInt16 nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++)
392     {
393         /**************************************************************
394          * Gibt es die Layouts schon im Dokument?
395          **************************************************************/
396         SdPage* pTestPage = (SdPage*) rDoc.GetMasterPage(nMPage);
397         String aTest(pTestPage->GetLayoutName());
398         aTest.Erase( aTest.SearchAscii( SD_LT_SEPARATOR ));
399 
400         if (aTest == *pLayout)
401             bFound = sal_True;
402     }
403 
404     if (!bFound)
405         mpLayoutsToTransfer->Insert(pLayout, LIST_APPEND);
406     else
407         delete pLayout;
408 }
409 
410 /** Just add one page to the container given to the constructor.
411 */
412 class InsertBookmarkAsPage_AddBookmarkedPages
413     : public SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase
414 {
415 public:
416     InsertBookmarkAsPage_AddBookmarkedPages(::std::vector<SdPage*>& rContainer)
417         : mrContainer(rContainer) {}
418     ~InsertBookmarkAsPage_AddBookmarkedPages(void) {}
419     void operator() (SdDrawDocument&, SdPage* pPage) { mrContainer.push_back(pPage); }
420 private:
421     ::std::vector<SdPage*>& mrContainer;
422 };
423 
424 
425 sal_Bool SdDrawDocument::InsertBookmarkAsPage(
426 	List* pBookmarkList,
427 	List* pExchangeList,            // Liste der zu verwendenen Namen
428 	sal_Bool bLink,
429 	sal_Bool bReplace,
430 	sal_uInt16 nInsertPos,
431 	sal_Bool bNoDialogs,
432 	::sd::DrawDocShell* pBookmarkDocSh,
433 	sal_Bool bCopy,
434 	sal_Bool bMergeMasterPages,
435     sal_Bool bPreservePageNames)
436 {
437 	sal_Bool bOK = sal_True;
438 	sal_Bool bContinue = sal_True;
439 	sal_Bool bScaleObjects = sal_False;
440 	sal_uInt16 nReplacedStandardPages = 0;
441 
442 	SdDrawDocument* pBookmarkDoc = NULL;
443 	String aBookmarkName;
444 
445 	if (pBookmarkDocSh)
446 	{
447 		pBookmarkDoc = pBookmarkDocSh->GetDoc();
448 
449 		if (pBookmarkDocSh->GetMedium())
450 		{
451 			aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
452 		}
453 	}
454 	else if ( mxBookmarkDocShRef.Is() )
455 	{
456 		pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
457 		aBookmarkName = maBookmarkFile;
458 	}
459 	else
460 	{
461 		return sal_False;
462 	}
463 
464 	const sal_uInt16 nSdPageCount = GetSdPageCount(PK_STANDARD);
465 	const sal_uInt16 nBMSdPageCount = pBookmarkDoc->GetSdPageCount(PK_STANDARD);
466 	const sal_uInt16 nMPageCount = GetMasterPageCount();
467 
468 	if (nSdPageCount==0 || nBMSdPageCount==0 || nMPageCount==0)
469 	{
470 		bContinue = bOK = sal_False;
471 		return(bContinue);
472 	}
473 
474     // Store the size and some other properties of the first page and notes
475     // page so that inserted pages can be properly scaled even when inserted
476     // before the first page.
477     // Note that the pointers are used later on as general page pointers.
478     SdPage* pRefPage = GetSdPage(0, PK_STANDARD);
479     Size  aSize(pRefPage->GetSize());
480     sal_Int32 nLeft  = pRefPage->GetLftBorder();
481     sal_Int32 nRight = pRefPage->GetRgtBorder();
482     sal_Int32 nUpper = pRefPage->GetUppBorder();
483     sal_Int32 nLower = pRefPage->GetLwrBorder();
484     Orientation eOrient = pRefPage->GetOrientation();
485 
486     SdPage* pNPage = GetSdPage(0, PK_NOTES);
487     Size aNSize(GetSdPage(0, PK_NOTES)->GetSize());
488     sal_Int32 nNLeft  = pNPage->GetLftBorder();
489     sal_Int32 nNRight = pNPage->GetRgtBorder();
490     sal_Int32 nNUpper = pNPage->GetUppBorder();
491     sal_Int32 nNLower = pNPage->GetLwrBorder();
492     Orientation eNOrient = pRefPage->GetOrientation();
493 
494 	// Seitengroesse und -raender an die Werte der letzten
495 	// Seiten anpassen?
496 	pRefPage = GetSdPage(nSdPageCount - 1, PK_STANDARD);
497 
498 	if( bNoDialogs )
499 	{
500         if( !pBookmarkList )
501 		    bScaleObjects = pRefPage->IsScaleObjects();
502         else
503             bScaleObjects = sal_True;
504 	}
505 	else
506 	{
507 		SdPage* pBMPage = pBookmarkDoc->GetSdPage(0,PK_STANDARD);
508 
509 		if (pBMPage->GetSize()		  != pRefPage->GetSize()		 ||
510 			pBMPage->GetLftBorder()   != pRefPage->GetLftBorder()	 ||
511 			pBMPage->GetRgtBorder()   != pRefPage->GetRgtBorder()	 ||
512 			pBMPage->GetUppBorder()   != pRefPage->GetUppBorder()	 ||
513 			pBMPage->GetLwrBorder()   != pRefPage->GetLwrBorder())
514 		{
515 			String aStr(SdResId(STR_SCALE_OBJECTS));
516 			sal_uInt16 nBut = QueryBox( NULL, WB_YES_NO_CANCEL, aStr).Execute();
517 
518 			bScaleObjects = nBut == RET_YES;
519 			bContinue	  = nBut != RET_CANCEL;
520 
521 			if (!bContinue)
522 			{
523 				return(bContinue);
524 			}
525 		}
526 	}
527 
528 
529 	/**************************************************************************
530 	|* Die benoetigten Praesentations-StyleSheets ermitteln und vor
531 	|* den Seiten transferieren, sonst verlieren die Textobjekte
532 	|* beim Transfer den Bezug zur Vorlage
533 	\*************************************************************************/
534     ::svl::IUndoManager* pUndoMgr = NULL;
535     if( mpDocSh )
536     {
537         pUndoMgr = mpDocSh->GetUndoManager();
538         pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_INSERTPAGES)), String());
539     }
540 
541 	List* pLayoutsToTransfer = new List;
542 
543     //
544     // #96029# Refactored copy'n'pasted layout name collection into IterateBookmarkPages
545     //
546     InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor( pLayoutsToTransfer, pBookmarkDoc,
547                                                               pBookmarkList, nBMSdPageCount );
548     IterateBookmarkPages( pBookmarkDoc, pBookmarkList, nBMSdPageCount, aSearchFunctor );
549 
550 
551 	/**************************************************************************
552 	* Die tatsaechlich benoetigten Vorlagen kopieren
553 	**************************************************************************/
554 	SdStyleSheetPool* pBookmarkStyleSheetPool =
555 	(SdStyleSheetPool*) pBookmarkDoc->GetStyleSheetPool();
556 	String* pLayout = (String*) pLayoutsToTransfer->First();
557 
558 	// Wenn Vorlagen kopiert werden muessen, dann muessen auch die
559 	// MasterPages kopiert werden!
560 	if( pLayout )
561 		bMergeMasterPages = sal_True;
562 
563 	while (pLayout)
564 	{
565 		SdStyleSheetVector aCreatedStyles;
566 
567 		((SdStyleSheetPool*)GetStyleSheetPool())->CopyLayoutSheets(*pLayout, *pBookmarkStyleSheetPool,aCreatedStyles);
568 
569 		if(!aCreatedStyles.empty())
570 		{
571             if( pUndoMgr )
572             {
573                 SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, sal_True);
574                 pUndoMgr->AddUndoAction(pMovStyles);
575             }
576 		}
577 
578 		delete pLayout;
579 
580 		pLayout = (String*)pLayoutsToTransfer->Next();
581 	}
582 
583 	delete pLayoutsToTransfer;
584 
585 	/**************************************************************************
586 	* Dokument einfuegen
587 	**************************************************************************/
588 
589 	const bool bUndo = IsUndoEnabled();
590 
591 	if( bUndo )
592 		BegUndo(String(SdResId(STR_UNDO_INSERTPAGES)));
593 
594 	if (!pBookmarkList)
595 	{
596 		if (nInsertPos >= GetPageCount())
597 		{
598 			// Seiten werden hinten angefuegt
599 			nInsertPos = GetPageCount();
600 		}
601 
602 		sal_uInt16 nActualInsertPos = nInsertPos;
603 
604 		List aNameList;
605         std::set<sal_uInt16> aRenameSet;
606         sal_uInt16 nBMSdPage;
607 
608         for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
609         {
610             SdPage* pBMPage = pBookmarkDoc->GetSdPage(nBMSdPage, PK_STANDARD);
611             String  pName( pBMPage->GetName() );
612             sal_Bool    bIsMasterPage;
613 
614             if (bLink)
615             {
616                 // Es werden sich die Namen aller Seiten gemerkt
617 				aNameList.Insert(new String(pName), nBMSdPage);
618             }
619 
620             // #95677# Have to check for duplicate names here, too
621             // #67905# don't change name if source and dest model are the same!
622             if( pBookmarkDoc != this &&
623                 GetPageByName(pName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
624             {
625                 // #95991# delay renaming *after* pages are copied (might destroy source otherwise)
626 				aRenameSet.insert(nBMSdPage);
627             }
628         }
629 
630 		Merge(*pBookmarkDoc,
631 			  1,				 // Nicht die Handzettelseite
632 			  0xFFFF,			 // Aber alle anderen
633 			  nActualInsertPos,  // An Position einfuegen
634 			  bMergeMasterPages, // MasterPages mitnehmen
635 			  sal_False,			 // Aber nur die benoetigten MasterPages
636 			  sal_True, 			 // Undo-Aktion erzeugen
637 			  bCopy);			 // Seiten kopieren (oder mergen)
638 
639         for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
640         {
641             SdPage* pPage 		= (SdPage*) GetPage(nActualInsertPos);
642             SdPage* pNotesPage  = (SdPage*) GetPage(nActualInsertPos+1);
643             String* pName 		= (String*) aNameList.GetObject(nBMSdPage);
644 
645             // #95991# delay renaming *after* pages are copied (might destroy source otherwise)
646             if( aRenameSet.find(nBMSdPage) != aRenameSet.end() )
647             {
648                 // Seitenname schon vorhanden -> Defaultname
649                 // fuer Standard & Notizseite
650                 pPage->SetName(String());
651                 pNotesPage->SetName(String());
652             }
653 
654             if (bLink)
655             {
656 				// Nun werden die Link-Namen zusammengestellt
657 				pPage->SetFileName(aBookmarkName);
658 				pPage->SetBookmarkName(*(pName));
659                 delete pName;
660 				pPage->SetModel(this);
661 			}
662 
663             nActualInsertPos += 2;
664 		}
665 	}
666 	else
667 	{
668 		/**********************************************************************
669 		* Ausgewaehlte Seiten einfuegen
670 		**********************************************************************/
671 		SdPage* pBMPage;
672 
673 		if (nInsertPos >= GetPageCount())
674 		{
675 			// Seiten werden hinten angefuegt
676 			bReplace = sal_False;
677 			nInsertPos = GetPageCount();
678 		}
679 
680 		sal_uInt16 nActualInsertPos = nInsertPos;
681 
682         // Collect the bookmarked pages.
683         ::std::vector<SdPage*> aBookmarkedPages (pBookmarkList->Count(), NULL);
684 		for (sal_uInt16 nPos = 0; nPos < pBookmarkList->Count(); nPos++)
685 		{
686 			String  aPgName(*(String*) pBookmarkList->GetObject(nPos));
687             sal_Bool    bIsMasterPage;
688 			sal_uInt16  nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage );
689 
690 			if (nBMPage != SDRPAGE_NOTFOUND)
691 			{
692 				aBookmarkedPages[nPos] =  dynamic_cast<SdPage*>(pBookmarkDoc->GetPage(nBMPage));
693 			}
694         }
695 
696 		for (sal_uInt16 nPos = 0; nPos < pBookmarkList->Count(); nPos++)
697 		{
698             pBMPage = aBookmarkedPages[nPos];
699 			sal_uInt16 nBMPage = pBMPage!=NULL ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND;
700 
701 			if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage())
702 			{
703 				/**************************************************************
704 				* Es muss eine StandardSeite sein
705 				**************************************************************/
706                 sal_Bool bMustRename = sal_False;
707 
708                 // #95991# delay renaming *after* pages are copied (might destroy source otherwise)
709                 // #67905# don't change name if source and dest model are the same!
710                 // #96029# avoid renaming if replacing the same page
711                 String  aPgName(*(String*) pBookmarkList->GetObject(nPos));
712                 sal_Bool    bIsMasterPage;
713                 sal_uInt16 nPageSameName = GetPageByName(aPgName, bIsMasterPage);
714                 if( pBookmarkDoc != this &&
715                     nPageSameName != SDRPAGE_NOTFOUND &&
716                     ( !bReplace ||
717                       nPageSameName != nActualInsertPos ) )
718                 {
719                     bMustRename = sal_True;
720                 }
721 
722 				SdPage* pBookmarkPage = pBMPage;
723 				if (bReplace )
724 				{
725 					ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage );
726 				}
727 
728 				Merge(*pBookmarkDoc,
729 					  nBMPage,			 // Von Seite (Standard)
730 					  nBMPage+1,		 // Bis Seite (Notizen)
731 					  nActualInsertPos,  // An Position einfuegen
732 					  bMergeMasterPages, // MasterPages mitnehmen
733 					  sal_False,			 // Aber nur die benoetigten MasterPages
734 					  sal_True, 			 // Undo-Aktion erzeugen
735 					  bCopy);			 // Seiten kopieren (oder mergen)
736 
737 				if( bReplace )
738 				{
739 					if( GetPage( nActualInsertPos ) != pBookmarkPage )
740 					{
741 						// bookmark page was not moved but cloned, so update custom shows again
742 						ReplacePageInCustomShows( pBookmarkPage, dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ) );
743 					}
744 				}
745 
746 				if( bMustRename )
747                 {
748 					// Seitenname schon vorhanden -> Defaultname
749 					// fuer Standard & Notizseite
750 					SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
751 					pPage->SetName(String());
752 					SdPage* pNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
753 					pNotesPage->SetName(String());
754                 }
755 
756 				if (bLink)
757 				{
758 					SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
759 					pPage->SetFileName(aBookmarkName);
760 					pPage->SetBookmarkName(aPgName);
761 					pPage->SetModel(this);
762 				}
763 
764 				if (bReplace)
765 				{
766 					// Seite & Notizseite ausfuegen
767 					const sal_uInt16 nDestPageNum(nActualInsertPos + 2);
768 					SdPage* pStandardPage = 0L;
769 
770 					if(nDestPageNum < GetPageCount())
771 					{
772 						pStandardPage = (SdPage*)GetPage(nDestPageNum);
773 					}
774 
775 					if (pStandardPage)
776 					{
777                         if( bPreservePageNames )
778                         {
779                             // #96029# Take old slide names for inserted pages
780                             SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
781                             pPage->SetName( pStandardPage->GetRealName() );
782                         }
783 
784 						if( bUndo )
785 							AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage));
786 
787 						RemovePage(nDestPageNum);
788 
789 						if( !bUndo )
790 							delete pStandardPage;
791 					}
792 
793 					SdPage* pNotesPage = 0L;
794 
795 					if(nDestPageNum < GetPageCount())
796 					{
797 						pNotesPage = (SdPage*)GetPage(nDestPageNum);
798 					}
799 
800 					if (pNotesPage)
801 					{
802                         if( bPreservePageNames )
803                         {
804                             // #96029# Take old slide names for inserted pages
805                             SdPage* pNewNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
806 							if( pNewNotesPage )
807 	                            pNewNotesPage->SetName( pStandardPage->GetRealName() );
808                         }
809 
810 						if( bUndo )
811 							AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
812 
813 						RemovePage(nDestPageNum);
814 
815 						if( !bUndo )
816 							delete pNotesPage;
817 					}
818 
819 					nReplacedStandardPages++;
820 				}
821 
822 				nActualInsertPos += 2;
823 			}
824 		}
825 	}
826 
827 
828 	/**************************************************************************
829 	|* Dabei sind evtl. zu viele Masterpages ruebergekommen, da die
830 	|* DrawingEngine gleiche Praesentationslayouts nicht erkennen kann.
831 	|* Ueberzaehlige MasterPages entfernen.
832 	\*************************************************************************/
833 	sal_uInt16 nNewMPageCount = GetMasterPageCount();
834 
835 	// rueckwaerts, damit Nummern nicht durcheinander geraten
836 	for (sal_uInt16 nPage = nNewMPageCount - 1; nPage >= nMPageCount; nPage--)
837 	{
838 		pRefPage = (SdPage*) GetMasterPage(nPage);
839 		String aMPLayout(pRefPage->GetLayoutName());
840 		PageKind eKind = pRefPage->GetPageKind();
841 
842 		// gibt's den schon?
843 		for (sal_uInt16 nTest = 0; nTest < nMPageCount; nTest++)
844 		{
845 			SdPage* pTest = (SdPage*) GetMasterPage(nTest);
846 			String aTest(pTest->GetLayoutName());
847 
848             // #96029# nInsertPos > 2 is always true when inserting into non-empty models
849 			if ( nInsertPos > 2 &&
850 			     aTest == aMPLayout &&
851 				 eKind == pTest->GetPageKind() )
852 			{
853 				if( bUndo )
854 					AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage));
855 
856                 RemoveMasterPage(nPage);
857 
858 				if( !bUndo )
859 					delete pRefPage;
860                 nNewMPageCount--;
861 				break;
862 			}
863 		}
864 	}
865 
866     // #96029# nInsertPos > 2 is always true when inserting into non-empty models
867 	if (nInsertPos > 0)
868 	{
869 		sal_uInt16 nSdPageStart = (nInsertPos - 1) / 2;
870 		sal_uInt16 nSdPageEnd = GetSdPageCount(PK_STANDARD) - nSdPageCount +
871 							nSdPageStart - 1;
872 		const bool bRemoveEmptyPresObj = pBookmarkDoc &&
873 				(pBookmarkDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
874 				(GetDocumentType() == DOCUMENT_TYPE_DRAW);
875 
876 		if( bReplace )
877 		{
878 			nSdPageEnd = nSdPageStart + nReplacedStandardPages - 1;
879 		}
880 
881 		for (sal_uInt16 nSdPage = nSdPageStart; nSdPage <= nSdPageEnd; nSdPage++)
882 		{
883 			pRefPage = GetSdPage(nSdPage, PK_STANDARD);
884 
885 			if (pExchangeList)
886 			{
887 				// Zuverwendener Name aus Exchange-Liste holen
888 				if (pExchangeList->GetCurObject())
889 				{
890 					String aExchangeName (*(String*) pExchangeList->GetCurObject());
891 					pRefPage->SetName(aExchangeName);
892 					SdrHint aHint(HINT_PAGEORDERCHG);
893 					aHint.SetPage(pRefPage);
894 					Broadcast(aHint);
895 					SdPage* pNewNotesPage = GetSdPage(nSdPage, PK_NOTES);
896 					pNewNotesPage->SetName(aExchangeName);
897 					aHint.SetPage(pNewNotesPage);
898 					Broadcast(aHint);
899 				}
900 
901 				pExchangeList->Next();
902 			}
903 
904 			String aLayout(pRefPage->GetLayoutName());
905 			aLayout.Erase(aLayout.SearchAscii( SD_LT_SEPARATOR ));
906 
907             // update layout and referred master page
908 			pRefPage->SetPresentationLayout(aLayout);
909 			if( bUndo )
910 				AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
911 
912 			if (bScaleObjects)
913 			{
914 				Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
915 				pRefPage->ScaleObjects(aSize, aBorderRect, sal_True);
916 			}
917 			pRefPage->SetSize(aSize);
918 			pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
919 			pRefPage->SetOrientation( eOrient );
920 
921 			if( bRemoveEmptyPresObj )
922 				pRefPage->RemoveEmptyPresentationObjects();
923 
924 			pRefPage = GetSdPage(nSdPage, PK_NOTES);
925 
926             // update layout and referred master page
927 			pRefPage->SetPresentationLayout(aLayout);
928 			if( bUndo )
929 				AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
930 
931 			if (bScaleObjects)
932 			{
933 				Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
934 				pRefPage->ScaleObjects(aNSize, aBorderRect, sal_True);
935 			}
936 
937 			pRefPage->SetSize(aNSize);
938 			pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
939 			pRefPage->SetOrientation( eNOrient );
940 
941 			if( bRemoveEmptyPresObj )
942 				pRefPage->RemoveEmptyPresentationObjects();
943 		}
944 
945 		for (sal_uInt16 nPage = nMPageCount; nPage < nNewMPageCount; nPage++)
946 		{
947 			pRefPage = (SdPage*) GetMasterPage(nPage);
948 			if (pRefPage->GetPageKind() == PK_STANDARD)
949 			{
950 				if (bScaleObjects)
951 				{
952 					Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
953 					pRefPage->ScaleObjects(aSize, aBorderRect, sal_True);
954 				}
955 				pRefPage->SetSize(aSize);
956 				pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
957 				pRefPage->SetOrientation( eOrient );
958 			}
959 			else        // kann nur noch NOTES sein
960 			{
961 				if (bScaleObjects)
962 				{
963 					Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
964 					pRefPage->ScaleObjects(aNSize, aBorderRect, sal_True);
965 				}
966 				pRefPage->SetSize(aNSize);
967 				pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
968 				pRefPage->SetOrientation( eNOrient );
969 			}
970 
971 			if( bRemoveEmptyPresObj )
972 				pRefPage->RemoveEmptyPresentationObjects();
973 		}
974 	}
975 
976     // #91146# Make absolutely sure no double masterpages are there
977     RemoveUnnecessaryMasterPages(NULL, sal_True, sal_True);
978 
979 	if( bUndo )
980 		EndUndo();
981 	pUndoMgr->LeaveListAction();
982 
983 	return bContinue;
984 }
985 
986 /*************************************************************************
987 |*
988 |* Fuegt ein Bookmark als Objekt ein
989 |*
990 \************************************************************************/
991 
992 sal_Bool SdDrawDocument::InsertBookmarkAsObject(
993 	List* pBookmarkList,
994 	List* pExchangeList,            // Liste der zu verwendenen Namen
995 	sal_Bool /* bLink */,
996 	::sd::DrawDocShell* pBookmarkDocSh,
997 	Point* pObjPos)
998 {
999 	sal_Bool bOK = sal_True;
1000 	sal_Bool bOLEObjFound = sal_False;
1001 	::sd::View* pBMView = NULL;
1002 
1003 	SdDrawDocument* pBookmarkDoc = NULL;
1004 	String aBookmarkName;
1005 
1006 	if (pBookmarkDocSh)
1007 	{
1008 		pBookmarkDoc = pBookmarkDocSh->GetDoc();
1009 
1010 		if (pBookmarkDocSh->GetMedium())
1011 		{
1012 			aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
1013 		}
1014 	}
1015 	else if ( mxBookmarkDocShRef.Is() )
1016 	{
1017 		pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
1018 		aBookmarkName = maBookmarkFile;
1019 	}
1020 	else
1021 	{
1022 		return sal_False;
1023 	}
1024 
1025 	if (!pBookmarkList)
1026 	{
1027 		pBMView = new ::sd::View(pBookmarkDoc, (OutputDevice*) NULL);
1028 		pBMView->EndListening(*pBookmarkDoc);
1029 		pBMView->MarkAll();
1030 	}
1031 	else
1032 	{
1033 		SdrPage* pPage;
1034 		SdrPageView* pPV;
1035 
1036 		for (sal_uInt16 nPos = 0; nPos < pBookmarkList->Count(); nPos++)
1037 		{
1038 			/******************************************************************
1039 			* Namen der Bookmarks aus Liste holen
1040 			******************************************************************/
1041 			String aBMName (*(String*) pBookmarkList->GetObject(nPos));
1042 
1043 			SdrObject* pObj = pBookmarkDoc->GetObj(aBMName);
1044 
1045 			if (pObj)
1046 			{
1047 				// Objekt gefunden
1048 
1049 				if (pObj->GetObjInventor() == SdrInventor &&
1050 					pObj->GetObjIdentifier() == OBJ_OLE2)
1051 				{
1052 					bOLEObjFound = sal_True;
1053 				}
1054 
1055 				if (!pBMView)
1056 				{
1057 					// View erstmalig erzeugen
1058 					pBMView = new ::sd::View(pBookmarkDoc, (OutputDevice*) NULL);
1059 					pBMView->EndListening(*pBookmarkDoc);
1060 				}
1061 
1062 				pPage = pObj->GetPage();
1063 
1064 				if (pPage->IsMasterPage())
1065 				{
1066 					pPV = pBMView->ShowSdrPage(pBMView->GetModel()->GetMasterPage(pPage->GetPageNum()));
1067 				}
1068 				else
1069 				{
1070 					pPV = pBMView->GetSdrPageView();
1071 					if( !pPV || (pPV->GetPage() != pPage))
1072 						pPV = pBMView->ShowSdrPage(pPage);
1073 				}
1074 
1075 				pBMView->MarkObj(pObj, pPV, sal_False);
1076 			}
1077 		}
1078 	}
1079 
1080 	if (pBMView)
1081 	{
1082 		/**********************************************************************
1083 		* Selektierte Objekte einfuegen
1084 		**********************************************************************/
1085 		::sd::View* pView = new ::sd::View(this, (OutputDevice*) NULL);
1086 		pView->EndListening(*this);
1087 
1088 		// Seite bestimmen, auf der die Objekte eingefuegt werden sollen
1089 		SdrPage* pPage = GetSdPage(0, PK_STANDARD);
1090 
1091 		if (mpDocSh)
1092 		{
1093 			::sd::ViewShell* pViewSh = mpDocSh->GetViewShell();
1094 
1095 			if (pViewSh)
1096 			{
1097 				// Welche Seite wird denn aktuell angezeigt?
1098 				SdrPageView* pPV = pViewSh->GetView()->GetSdrPageView();
1099 
1100 				if (pPV)
1101 				{
1102 					pPage = pPV->GetPage();
1103 				}
1104 				else if (pViewSh->GetActualPage())
1105 				{
1106 					pPage = pViewSh->GetActualPage();
1107 				}
1108 			}
1109 		}
1110 
1111 		Point aObjPos;
1112 
1113 		if (pObjPos)
1114 		{
1115 			aObjPos = *pObjPos;
1116 		}
1117 		else
1118 		{
1119 			aObjPos = Rectangle(Point(), pPage->GetSize()).Center();
1120 		}
1121 
1122 		sal_uLong nCountBefore = 0;
1123 
1124 		if (pExchangeList)
1125 		{
1126 			// OrdNums sortieren und Anzahl Objekte vor dem Einfuegen bestimmen
1127 			pPage->RecalcObjOrdNums();
1128 			nCountBefore = pPage->GetObjCount();
1129 		}
1130 
1131 		if (bOLEObjFound)
1132 			pBMView->GetDoc()->SetAllocDocSh(sal_True);
1133 
1134 		SdDrawDocument* pTmpDoc = (SdDrawDocument*) pBMView->GetAllMarkedModel();
1135 		bOK = pView->Paste(*pTmpDoc, aObjPos, pPage);
1136 
1137 		if (bOLEObjFound)
1138 			pBMView->GetDoc()->SetAllocDocSh(sal_False);
1139 
1140 		if (!bOLEObjFound)
1141 			delete pTmpDoc;             // Wird ansonsten von der DocShell zerstoert
1142 
1143 		delete pView;
1144 
1145 		List* pList = pBookmarkList;
1146 
1147 		if (pExchangeList)
1148 		{
1149 			// Anzahl Objekte nach dem Einfuegen bestimmen
1150 			sal_uLong nCount = pPage->GetObjCount();
1151 
1152 			for (sal_uLong nObj = nCountBefore; nObj < nCount; nObj++)
1153 			{
1154 				// Zuverwendener Name aus Exchange-Liste holen
1155 				if (pExchangeList->GetCurObject())
1156 				{
1157 					String aExchangeName (*(String*) pExchangeList->GetCurObject());
1158 
1159 					if (pPage->GetObj(nObj))
1160 					{
1161 						pPage->GetObj(nObj)->SetName(aExchangeName);
1162 					}
1163 				}
1164 
1165 				pExchangeList->Next();
1166 			}
1167 
1168 			pList = pExchangeList;
1169 		}
1170 	}
1171 
1172 	delete pBMView;
1173 
1174 	return bOK;
1175 }
1176 
1177 /*************************************************************************
1178 |*
1179 |* Beendet das Einfuegen von Bookmarks
1180 |*
1181 \************************************************************************/
1182 
1183 void SdDrawDocument::CloseBookmarkDoc()
1184 {
1185 	if (mxBookmarkDocShRef.Is())
1186 	{
1187 		mxBookmarkDocShRef->DoClose();
1188 	}
1189 
1190 	mxBookmarkDocShRef.Clear();
1191 	maBookmarkFile = String();
1192 }
1193 
1194 /*************************************************************************
1195 |*
1196 |* Dokument laden (fuer gelinkte Objekte)
1197 |*
1198 \************************************************************************/
1199 
1200 const SdrModel* SdDrawDocument::LoadModel(const String& rFileName)
1201 {
1202 	return ( OpenBookmarkDoc(rFileName) );
1203 }
1204 
1205 /*************************************************************************
1206 |*
1207 |* Dokument schliessen (fuer gelinkte Objekte)
1208 |*
1209 \************************************************************************/
1210 
1211 void SdDrawDocument::DisposeLoadedModels()
1212 {
1213 	CloseBookmarkDoc();
1214 }
1215 
1216 /*************************************************************************
1217 |*
1218 |* Ist das Dokument read-only?
1219 |*
1220 \************************************************************************/
1221 
1222 FASTBOOL SdDrawDocument::IsReadOnly() const
1223 {
1224 	return sal_False;
1225 }
1226 
1227 
1228 /*************************************************************************
1229 |*
1230 |* In anschliessendem AllocModel() wird eine DocShell erzeugt
1231 |* (xAllocedDocShRef). Eine bereits bestehende DocShell wird ggf. geloescht
1232 |*
1233 \************************************************************************/
1234 
1235 void SdDrawDocument::SetAllocDocSh(sal_Bool bAlloc)
1236 {
1237 	mbAllocDocSh = bAlloc;
1238 
1239 	if(mxAllocedDocShRef.Is())
1240 	{
1241 		mxAllocedDocShRef->DoClose();
1242 	}
1243 
1244 	mxAllocedDocShRef.Clear();
1245 }
1246 
1247 /*************************************************************************
1248 |*
1249 |* Liste der CustomShows zurueckgeben (ggf. zuerst erzeugen)
1250 |*
1251 \************************************************************************/
1252 
1253 List* SdDrawDocument::GetCustomShowList(sal_Bool bCreate)
1254 {
1255 	if (!mpCustomShowList && bCreate)
1256 	{
1257 		// Liste erzeugen
1258 		mpCustomShowList = new List();
1259 	}
1260 
1261 	return(mpCustomShowList);
1262 }
1263 
1264 /*************************************************************************
1265 |*
1266 |* Document-Stream herausgeben (fuer load-on-demand Graphiken)
1267 |*
1268 \************************************************************************/
1269 
1270 SvStream* SdDrawDocument::GetDocumentStream(SdrDocumentStreamInfo& rStreamInfo) const
1271 {
1272     uno::Reference < embed::XStorage > xStor;
1273     if (mpDocSh)
1274         xStor = mpDocSh->GetStorage();
1275 	SvStream*	pRet = NULL;
1276 
1277     if( xStor.is() )
1278 	{
1279         //TODO/MBA: binary format removed, needs testing
1280 		if( rStreamInfo.maUserData.Len() &&
1281 			( rStreamInfo.maUserData.GetToken( 0, ':' ) ==
1282 			  String( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package" ) ) ) )
1283 		{
1284 			const String aPicturePath( rStreamInfo.maUserData.GetToken( 1, ':' ) );
1285 
1286 			// graphic from picture stream in picture storage in XML package
1287 			if( aPicturePath.GetTokenCount( '/' ) == 2 ) try
1288 			{
1289 				const String aPictureStreamName( aPicturePath.GetToken( 1, '/' ) );
1290                 const String aPictureStorageName( aPicturePath.GetToken( 0, '/' ) );
1291                 if( xStor->isStorageElement( aPictureStorageName )  )
1292                 {
1293 					uno::Reference < embed::XStorage > xPictureStorage =
1294 							xStor->openStorageElement( aPictureStorageName, embed::ElementModes::READ );
1295 					try
1296 					{
1297 						if( xPictureStorage.is() && xPictureStorage->isStreamElement( aPictureStreamName ) )
1298 						{
1299 							uno::Reference < io::XStream > xStream = xPictureStorage->openStreamElement( aPictureStreamName, embed::ElementModes::READ );
1300 							if( xStream.is() )
1301 								pRet = ::utl::UcbStreamHelper::CreateStream( xStream );
1302 						}
1303 					}
1304 					catch( container::NoSuchElementException& )
1305 					{
1306 					}
1307                 }
1308 			}
1309 			catch( uno::Exception& e )
1310 			{
1311 				(void)e;
1312 				DBG_ERROR(
1313 					(rtl::OString("sd::SdDrawDocument::GetDocumentStream(), "
1314 							"exception caught: ") +
1315 					rtl::OUStringToOString(
1316 						comphelper::anyToString( cppu::getCaughtException() ),
1317 						RTL_TEXTENCODING_UTF8 ) +
1318 						rtl::OString("\r\nATTENTION: Graphics may get lost now, please inform CL or KA!") ).getStr() );
1319 			}
1320 
1321 			rStreamInfo.mbDeleteAfterUse = ( pRet != NULL );
1322 		}
1323 	}
1324 
1325 #if OSL_DEBUG_LEVEL > 1
1326 	if( pRet )
1327 	{
1328 		// try to get some information from stream
1329 		const sal_uLong nStartPos = pRet->Tell();
1330 		const sal_uLong nEndPos = pRet->Seek( STREAM_SEEK_TO_END );
1331 		const sal_uLong nStmLen = nEndPos - nStartPos;
1332 		sal_uChar	aTestByte;
1333 
1334 		// try to read one byte
1335 		if( nStmLen )
1336 			*pRet >> aTestByte;
1337 
1338 		pRet->Seek( nStartPos );
1339 	}
1340 #endif
1341 
1342 	return pRet;
1343 }
1344 
1345 
1346 /*************************************************************************
1347 |*
1348 |* Nicht benutzte MasterPages und Layouts entfernen
1349 |*
1350 \************************************************************************/
1351 
1352 void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage* pMasterPage, sal_Bool bOnlyDuplicatePages, sal_Bool bUndo)
1353 {
1354 	::sd::View* pView = NULL;
1355 	::svl::IUndoManager* pUndoMgr = NULL;
1356 
1357 	if( bUndo && !IsUndoEnabled() )
1358 		bUndo = sal_False;
1359 
1360 	if (mpDocSh)
1361 	{
1362 		pUndoMgr = mpDocSh->GetUndoManager();
1363 
1364 		if (mpDocSh->GetViewShell())
1365 			pView = mpDocSh->GetViewShell()->GetView();
1366 	}
1367 
1368 	/***********************************************************
1369 	* Alle MasterPages pruefen
1370 	***********************************************************/
1371 	sal_uInt16 nSdMasterPageCount = GetMasterSdPageCount( PK_STANDARD );
1372 	for (sal_Int32 nMPage = nSdMasterPageCount - 1; nMPage >= 0; nMPage--)
1373 	{
1374 		SdPage* pMaster = pMasterPage;
1375 		SdPage* pNotesMaster = NULL;
1376 
1377 		if (!pMaster)
1378 		{
1379 			pMaster = (SdPage*) GetMasterSdPage( (sal_uInt16) nMPage, PK_STANDARD );
1380 			pNotesMaster = (SdPage*) GetMasterSdPage( (sal_uInt16) nMPage, PK_NOTES );
1381 		}
1382 		else
1383 		{
1384 			for ( sal_uInt16 nMPg = 0; nMPg < GetMasterPageCount(); nMPg++ )
1385 			{
1386 				if ( pMaster == GetMasterPage( nMPg ) )
1387 				{
1388 					pNotesMaster = (SdPage*) GetMasterPage( ++nMPg );
1389 					break;
1390 				}
1391 			}
1392 		}
1393 
1394 		DBG_ASSERT( pMaster->GetPageKind() == PK_STANDARD, "wrong page kind" );
1395 
1396 		if ( pMaster->GetPageKind() == PK_STANDARD &&
1397 		     GetMasterPageUserCount( pMaster ) == 0 &&
1398 			 pNotesMaster )
1399 		{
1400             // Do not delete master pages that have their precious flag set.
1401 			sal_Bool bDeleteMaster = !pMaster->IsPrecious();
1402 			String aLayoutName = pMaster->GetLayoutName();
1403 
1404 			if(bOnlyDuplicatePages )
1405 			{
1406 				// remove only duplicate pages
1407 				bDeleteMaster = sal_False;
1408 				for (sal_uInt16 i = 0; i < GetMasterSdPageCount( PK_STANDARD ); i++)
1409 				{
1410 					SdPage* pMPg = (SdPage*) GetMasterSdPage( i, PK_STANDARD );
1411 					if( pMPg != pMaster &&
1412 					    pMPg->GetLayoutName() == aLayoutName )
1413 					{
1414 						// duplicate page found -> remove it
1415 						bDeleteMaster = sal_True;
1416 					}
1417 				}
1418 			}
1419 
1420 			if( bDeleteMaster )
1421 			{
1422 				if (pView)
1423 				{
1424 					// if MasterPage is visible hide on pageview
1425 					SdrPageView* pPgView = pView->GetSdrPageView();
1426 					if (pPgView)
1427 					{
1428 						SdrPage* pShownPage = pPgView->GetPage();
1429 						if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) )
1430 						{
1431 							pView->HideSdrPage();
1432 							pView->ShowSdrPage( GetSdPage( 0, PK_STANDARD ) );
1433 						}
1434 					}
1435 				}
1436 
1437 				if( bUndo )
1438 				{
1439 					BegUndo();
1440 					AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster ) );
1441 				}
1442 
1443 				RemoveMasterPage( pNotesMaster->GetPageNum() );
1444 
1445 				if( !bUndo )
1446 					delete pNotesMaster;
1447 
1448 				if( bUndo )
1449 					AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster));
1450 
1451 				RemoveMasterPage( pMaster->GetPageNum() );
1452 
1453 				if( !bUndo )
1454 					delete pMaster;
1455 
1456 				if( bUndo )
1457 					EndUndo();	// schon hier, damit sich Joes Actions ZWISCHEN unsere eigenen schieben
1458 
1459 				// alte Layoutvorlagen loeschen, wenn sie nicht mehr benoetigt werden
1460 				sal_Bool bDeleteOldStyleSheets = sal_True;
1461 				for ( sal_uInt16 nMPg = 0;
1462    				 	  nMPg < GetMasterPageCount() && bDeleteOldStyleSheets;
1463 				 	  nMPg++ )
1464 				{
1465 					SdPage* pMPg = (SdPage*) GetMasterPage(nMPg);
1466 					if (pMPg->GetLayoutName() == aLayoutName)
1467 					{
1468 						bDeleteOldStyleSheets = sal_False;
1469 					}
1470 				}
1471 
1472 				if (bDeleteOldStyleSheets)
1473 				{
1474 					SdStyleSheetVector aRemove;
1475 					static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList( aLayoutName, aRemove );
1476 
1477 					if( bUndo )
1478 					{
1479 						// die Liste gehoert der UndoAction
1480 						SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aRemove, false );
1481 
1482 						if (pUndoMgr)
1483 							pUndoMgr->AddUndoAction(pMovStyles);
1484 					}
1485 
1486 					for( SdStyleSheetVector::iterator iter = aRemove.begin(); iter != aRemove.end(); iter++ )
1487 						static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->Remove((*iter).get());
1488 				}
1489 			}
1490 		}
1491 
1492 		if (pMasterPage)
1493 			break;			            // Nur diese eine MasterPage!
1494 	}
1495 }
1496 
1497 
1498 /*************************************************************************
1499 |*
1500 |* MasterPage austauschen
1501 |*
1502 |* Entweder erhaelt nSdPageNum eine neue, eigene MasterPage, oder die MasterPage
1503 |* wird komplett ausgetauscht (gilt dann fuer alle Seiten).
1504 |*
1505 |* nSdPageNum   : Nummer der Seite, welche die neue MasterPage erhalten soll
1506 |* rLayoutName  : LayoutName der neuen MasterPage
1507 |* pSourceDoc   : Dokument (Vorlage) aus dem die MasterPage geholt wird
1508 |* bMaster      : Die MasterPage von nSdPageNum soll ausgetauscht werden
1509 |* bCheckMasters: Nicht benutzte MasterPages sollen entfernt werden
1510 |*
1511 |* Ist pSourceDoc == NULL, so wird eine leere MasterPage zugewiesen.
1512 |* Ist rLayoutName leer, so wird die erste MasterPage genommen
1513 \************************************************************************/
1514 
1515 void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum,
1516 								   const String& rLayoutName,
1517 								   SdDrawDocument* pSourceDoc,
1518 								   sal_Bool bMaster,
1519 								   sal_Bool bCheckMasters)
1520 {
1521 	if( mpDocSh )
1522 		mpDocSh->SetWaitCursor( sal_True );
1523 
1524 	::svl::IUndoManager* pUndoMgr = mpDocSh->GetUndoManager();
1525 
1526 	const bool bUndo = IsUndoEnabled();
1527 
1528 	if( bUndo )
1529 	{
1530 		pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());
1531 	}
1532 
1533 	SdPage* pSelectedPage   = GetSdPage(nSdPageNum, PK_STANDARD);
1534 	SdPage* pNotes			= (SdPage*) GetPage(pSelectedPage->GetPageNum()+1);
1535 	SdPage& rOldMaster		= (SdPage&)pSelectedPage->TRG_GetMasterPage();
1536 	SdPage& rOldNotesMaster = (SdPage&)pNotes->TRG_GetMasterPage();
1537 	SdPage* pMaster 		= NULL;
1538 	SdPage* pNotesMaster	= NULL;
1539 	SdPage* pPage			= NULL;
1540 	String aOldPageLayoutName(pSelectedPage->GetLayoutName());
1541 	String aOldLayoutName(aOldPageLayoutName);
1542 	aOldLayoutName.Erase(aOldLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1543 
1544 	String aNewLayoutName( rLayoutName );
1545 
1546 	if (pSourceDoc)
1547 	{
1548 		List* pReplList = NULL;
1549 		sal_Bool bLayoutReloaded = sal_False; 	// Wurde ex. Layout wieder geladen?
1550 
1551 		/*********************************************************************
1552 		|* LayoutName, Page and Notespage
1553 		\*********************************************************************/
1554 		if (rLayoutName.Len() == 0)
1555 		{
1556 			// No LayoutName: take first MasterPage
1557 			pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1558 			pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1559 			aNewLayoutName = pMaster->GetName();
1560 		}
1561 		else
1562 		{
1563 			String aSearchFor(rLayoutName);
1564 			aSearchFor.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
1565 			aSearchFor.Append( String(SdResId(STR_LAYOUT_OUTLINE))) ;
1566 
1567 			for (sal_uInt16 nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); nMP++)
1568 			{
1569 				SdPage* pMP = (SdPage*) pSourceDoc->GetMasterPage(nMP);
1570 
1571 				if (pMP->GetLayoutName() == aSearchFor)
1572 				{
1573 					if (pMP->GetPageKind() == PK_STANDARD)
1574 						pMaster = pMP;
1575 					if (pMP->GetPageKind() == PK_NOTES)
1576 						pNotesMaster = pMP;
1577 				}
1578 				if (pMaster && pNotesMaster)
1579 					break;
1580 			}
1581 			DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
1582 			DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
1583 
1584 			// this should not happen, but looking at crashreports, it does
1585 			if( (pMaster == NULL) || (pNotesMaster == NULL) )
1586 			{
1587 				// so take the first MasterPage
1588 				pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1589 				pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1590 				aNewLayoutName = pMaster->GetName();
1591 			}
1592 		}
1593 
1594 		// we should never reach this, but one never knows....
1595 		if( (pMaster == NULL) || (pNotesMaster == NULL) )
1596 		{
1597 			pUndoMgr->LeaveListAction();
1598 
1599 			if( mpDocSh )
1600 				mpDocSh->SetWaitCursor( sal_False );
1601 
1602 			DBG_ERROR( "SdDrawDocument::SetMasterPage() failed!" );
1603 
1604 			return;
1605 		}
1606 
1607 		if (pSourceDoc != this)
1608 		{
1609 			const sal_uInt16 nMasterPageCount = GetMasterPageCount();
1610 			for ( sal_uInt16 nMPage = 0; nMPage < nMasterPageCount; nMPage++ )
1611 			{
1612 				SdPage* pCheckMaster = (SdPage*)GetMasterPage(nMPage);
1613 				if( pCheckMaster->GetName() == aNewLayoutName )
1614 				{
1615 					bLayoutReloaded = sal_True;
1616 					break;
1617 				}
1618 			}
1619 
1620 			/*****************************************************************
1621 			|* Praesentationsvorlagen korrigieren bzw. neu anlegen
1622 			\****************************************************************/
1623 			// nur die Praesentationsvorlagen beachten
1624 			String aName;
1625 			SdStyleSheetPool* pSourceStyleSheetPool = (SdStyleSheetPool*) pSourceDoc->GetStyleSheetPool();
1626 			pSourceStyleSheetPool->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1627 			static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1628 
1629 			pReplList = new List;         	// Liste fuer ersetzte StyleSheets
1630 			SdStyleSheetVector aCreatedStyles;			// Liste fuer erzeugte StyleSheets
1631 
1632 			SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First();
1633 
1634 			while (pHisSheet)
1635 			{
1636 				aName = pHisSheet->GetName();
1637 
1638 				if( aName.Search( aNewLayoutName ) == 0 )
1639 				{
1640 					SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SD_STYLE_FAMILY_MASTERPAGE) );
1641 
1642 					if (pMySheet)
1643 					{
1644 						// Es ist eine gleichnamige Vorlage vorhanden ist: Inhalte ersetzen
1645 #ifdef DBG_UTIL
1646 						sal_Bool bTest =
1647 #endif
1648 							pMySheet->SetName(pHisSheet->GetName());
1649 						DBG_ASSERT(bTest, "StyleSheet-Umbenennung fehlgeschlagen");
1650 						pMySheet->GetItemSet().ClearItem(0);  // alle loeschen
1651 
1652 						StyleSheetUndoAction* pUndoChStyle = new StyleSheetUndoAction(this,
1653 																 pMySheet, &pHisSheet->GetItemSet());
1654 						pUndoMgr->AddUndoAction(pUndoChStyle);
1655 						pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1656 						pMySheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
1657 					}
1658 					else
1659 					{
1660 					    // create new style
1661                         String aHelpFile;
1662 						pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SD_STYLE_FAMILY_MASTERPAGE, pHisSheet->GetMask()) );
1663                         pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) );
1664 						pMySheet->GetItemSet().ClearItem(0);  // alle loeschen
1665 						pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1666 
1667 						aCreatedStyles.push_back( SdStyleSheetRef( static_cast< SdStyleSheet* >( pMySheet ) ) );
1668 					}
1669 
1670 					StyleReplaceData* pReplData = new StyleReplaceData;
1671 					pReplData->nNewFamily = pMySheet->GetFamily();
1672 					pReplData->nFamily    = pMySheet->GetFamily();
1673 					pReplData->aNewName   = pMySheet->GetName();
1674 
1675 					String aTemp(pMySheet->GetName());
1676 					sal_uInt16 nPos = aTemp.SearchAscii( SD_LT_SEPARATOR );
1677 					aTemp.Erase(0, nPos);
1678 					aTemp.Insert(aOldLayoutName, 0);
1679 					pReplData->aName = aTemp;
1680 					pReplList->Insert(pReplData, LIST_APPEND);
1681 				}
1682 
1683 				pHisSheet = (SfxStyleSheet*) pSourceStyleSheetPool->Next();
1684 			}
1685 
1686 			// wenn neue Vorlagen erzeugt wurden:
1687 			// eventuell bestehende Parent-Verkettung der Itemsets in den
1688 			// Vorlagen wieder aufbauen
1689 			if(!aCreatedStyles.empty())
1690 			{
1691 				StyleReplaceData* pRData = (StyleReplaceData*)pReplList->First();
1692 
1693 				while (pRData)
1694 				{
1695 					SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(pRData->aName);
1696 					SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(pRData->aNewName);
1697 
1698 					if (pSOld && pSNew)
1699 					{
1700 						const String& rParentOfOld = pSOld->GetParent();
1701 						const String& rParentOfNew = pSNew->GetParent();
1702 
1703 						if (rParentOfOld.Len() > 0 && rParentOfNew.Len() == 0)
1704 						{
1705 
1706 							for (sal_uLong i = 0; i < pReplList->Count(); i++)
1707 							{
1708 								StyleReplaceData* pRD = (StyleReplaceData*)pReplList->
1709 																		GetObject(i);
1710 								if ((pRD->aName == rParentOfOld) && (pRD->aName != pRD->aNewName))
1711 								{
1712 									String aParentOfNew(pRD->aNewName);
1713 									pSNew->SetParent(aParentOfNew);
1714 									break;
1715 								}
1716 							}
1717 						}
1718 					}
1719 					pRData = (StyleReplaceData*) pReplList->Next();
1720 				}
1721 
1722 				// ab jetzt beim Suchen alle beachten
1723 				pSourceStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1724 				mxStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1725 			}
1726 
1727 			if( !aCreatedStyles.empty() )
1728 			{
1729 				// UndoAction fuer das Erzeugen und Einfuegen vorn StyleSheets
1730 				// auf den UndoManager legen
1731 				SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aCreatedStyles, sal_True);
1732 				pUndoMgr->AddUndoAction(pMovStyles);
1733 			}
1734 		}
1735 
1736 		// Layoutnamen auf Basis des Seitenlayoutnamens der Masterpage bilden
1737 		String aPageLayoutName(pMaster->GetLayoutName());
1738 		String aLayoutName = aPageLayoutName;
1739 		aLayoutName.Erase( aLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1740 
1741 		if (pSourceDoc != this)
1742 		{
1743 			// Aus dem Source-Dokument austragen
1744 			SdrPage* pTest = NULL;
1745 			pTest = pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1746 			pTest = pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1747 		}
1748 
1749 		/*********************************************************************
1750 		|* Neue MasterPages ins Dokument eintragen und den Standard- und
1751 		|* Notizseiten das Praesentationslayout ueberbraten
1752 		\********************************************************************/
1753 		if (pSourceDoc != this)
1754 		{
1755 			// Die Masterpages einfuegen:
1756 			// Masterpages von neuen Layouts hinten anhaengen; wird ein Layout
1757 			// dagegen ersetzt, so muss vor der Position der alten Masterpage
1758 			// eingefuegt werden, damit ab jetzt beim Suchen (z. B. SdPage::
1759 			// SetPresentationLayout) die neue Masterpage zuerst gefunden wird
1760 			sal_uInt16 nInsertPos = rOldMaster.GetPageNum();
1761 			BegUndo();
1762 
1763 			if (!bLayoutReloaded)
1764 				nInsertPos = 0xFFFF;
1765 			InsertMasterPage(pMaster, nInsertPos);
1766 			if( bUndo )
1767 				AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1768 
1769 			nInsertPos++;
1770 			if (!bLayoutReloaded)
1771 				nInsertPos = 0xFFFF;
1772 			InsertMasterPage(pNotesMaster, nInsertPos);
1773 			if( bUndo )
1774 			{
1775 				AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1776 
1777 				EndUndo(); // schon hier, damit sich Joes Actions ZWISCHEN unsere eigenen schieben
1778 			}
1779 		}
1780 
1781 		// Liste mit Seiten fuellen
1782 		List* pPageList = new List;
1783 
1784 //      #98456, this has to be removed according to CL (KA 07/08/2002)
1785 //		#109884# but we need them again to restore the styles of the presentation objects while undo
1786 		pPageList->Insert(pMaster, LIST_APPEND);
1787 		pPageList->Insert(pNotesMaster, LIST_APPEND);
1788 
1789 		if (bMaster || bLayoutReloaded)
1790 		{
1791 			for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1792 			{
1793 				pPage = (SdPage*) GetPage(nPage);
1794 				String aTest = pPage->GetLayoutName();
1795 				if (aTest == aOldPageLayoutName)
1796 				{
1797 					pPageList->Insert(pPage, LIST_APPEND);
1798 				}
1799 			}
1800 
1801 		}
1802 		else
1803 		{
1804 			pPageList->Insert(pSelectedPage, LIST_APPEND);
1805 			pPageList->Insert(pNotes, LIST_APPEND);
1806 		}
1807 
1808 		pPage = (SdPage*)pPageList->First();
1809 		while (pPage)
1810 		{
1811 			AutoLayout eAutoLayout = pPage->GetAutoLayout();
1812 
1813 			if( bUndo )
1814 			{
1815 				SdPresentationLayoutUndoAction * pPLUndoAction =
1816 					new SdPresentationLayoutUndoAction
1817 						(this,
1818 						pPage->IsMasterPage() ? aLayoutName : aOldLayoutName,
1819 						aLayoutName,
1820 						 eAutoLayout, eAutoLayout, sal_False, pPage);
1821 				pUndoMgr->AddUndoAction(pPLUndoAction);
1822 			}
1823 			pPage->SetPresentationLayout(aLayoutName);
1824 			pPage->SetAutoLayout(eAutoLayout);
1825 
1826 			pPage = (SdPage*)pPageList->Next();
1827 		}
1828 		delete pPageList;
1829 
1830 		/*********************************************************************
1831 		|* Neue Masterpages angleichen
1832 		\********************************************************************/
1833 		if (pSourceDoc != this)
1834 		{
1835 			// die Masterpages angleichen
1836 			Size aSize(rOldMaster.GetSize());
1837 			Rectangle aBorderRect(rOldMaster.GetLftBorder(),
1838 								  rOldMaster.GetUppBorder(),
1839 								  rOldMaster.GetRgtBorder(),
1840 								  rOldMaster.GetLwrBorder());
1841 			pMaster->ScaleObjects(aSize, aBorderRect, sal_True);
1842 			pMaster->SetSize(aSize);
1843 			pMaster->SetBorder(rOldMaster.GetLftBorder(),
1844 							   rOldMaster.GetUppBorder(),
1845 							   rOldMaster.GetRgtBorder(),
1846 							   rOldMaster.GetLwrBorder());
1847 			pMaster->SetOrientation( rOldMaster.GetOrientation() );
1848 			pMaster->SetAutoLayout(pMaster->GetAutoLayout());
1849 
1850 			aSize = rOldNotesMaster.GetSize();
1851 			Rectangle aNotesBorderRect(rOldNotesMaster.GetLftBorder(),
1852 									   rOldNotesMaster.GetUppBorder(),
1853 									   rOldNotesMaster.GetRgtBorder(),
1854 									   rOldNotesMaster.GetLwrBorder());
1855 			pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, sal_True);
1856 			pNotesMaster->SetSize(aSize);
1857 			pNotesMaster->SetBorder(rOldNotesMaster.GetLftBorder(),
1858 									rOldNotesMaster.GetUppBorder(),
1859 									rOldNotesMaster.GetRgtBorder(),
1860 									rOldNotesMaster.GetLwrBorder());
1861 			pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() );
1862 			pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout());
1863 
1864 			// Liste der ersetzten Vorlagen mit Inhalt loeschen
1865 			StyleReplaceData* pReplData = (StyleReplaceData*)pReplList->First();
1866 			while (pReplData)
1867 			{
1868 				delete pReplData;
1869 				pReplData = (StyleReplaceData*)pReplList->Next();
1870 			}
1871 			delete pReplList;
1872 
1873 
1874 			if( (pSourceDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
1875 				(GetDocumentType() == DOCUMENT_TYPE_DRAW) )
1876 			{
1877 				pMaster->RemoveEmptyPresentationObjects();
1878 				pNotesMaster->RemoveEmptyPresentationObjects();
1879 			}
1880 		}
1881 	}
1882 	else
1883 	{
1884 		/*********************************************************************
1885 		|* Einen neuen Layoutnamen ausdenken
1886 		\********************************************************************/
1887 		String aName        = String(SdResId(STR_LAYOUT_DEFAULT_NAME));
1888 		String aTest;
1889 		sal_Bool   bNotANewName = sal_True;
1890 		sal_uInt16 nCount		= 0;
1891 		sal_uInt16 nMPgCount	= GetMasterPageCount();
1892 
1893 		for (nCount = 0; bNotANewName; nCount++)
1894 		{
1895 			// Testnamen bilden
1896 			aTest = aName;				// Standard, Standard1, Standard2, ...
1897 			if (nCount > 0)
1898 				aTest += String::CreateFromInt32( nCount );
1899 
1900 			// gibt's schon eine, die so heisst?
1901 			bNotANewName = sal_False;
1902 			for (sal_uInt16 nMPg = 1; nMPg < nMPgCount; nMPg++)
1903 			{
1904 				const SdrPage* pTest = GetMasterPage(nMPg);
1905 				String aPageLayoutName(pTest->GetLayoutName());
1906 				aPageLayoutName.Erase( aPageLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1907 
1908 				if (aPageLayoutName == aTest)
1909 					bNotANewName = sal_True;
1910 			}
1911 		}
1912 		aName = aTest;
1913 		String aPageLayoutName(aName);
1914 		aPageLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
1915 		aPageLayoutName += String(SdResId(STR_LAYOUT_OUTLINE));
1916 
1917 		/*********************************************************************
1918 		|* Neue StyleSheets erzeugen
1919 		\********************************************************************/
1920 		static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName);
1921 		SdStyleSheetVector aCreatedStyles;
1922 		static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles);
1923 
1924 		if( bUndo )
1925 		{
1926 			SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, sal_True);
1927 			pUndoMgr->AddUndoAction(pMovStyles);
1928 		}
1929 
1930 		/*********************************************************************
1931 		|* Neue MasterPages erzeugen und ins Dokument eintragen
1932 		\********************************************************************/
1933 
1934 		if( bUndo )
1935 			BegUndo();
1936 
1937 		pMaster = (SdPage*) AllocPage(sal_True);
1938 		pMaster->SetSize(pSelectedPage->GetSize());
1939 		pMaster->SetBorder(pSelectedPage->GetLftBorder(),
1940 						   pSelectedPage->GetUppBorder(),
1941 						   pSelectedPage->GetRgtBorder(),
1942 						   pSelectedPage->GetLwrBorder() );
1943 		pMaster->SetName(aName);
1944 		pMaster->SetLayoutName(aPageLayoutName);
1945 		InsertMasterPage(pMaster);
1946 
1947 		if( bUndo )
1948 			AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1949 
1950 		pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
1951 
1952 		pNotesMaster = (SdPage*) AllocPage(sal_True);
1953 		pNotesMaster->SetPageKind(PK_NOTES);
1954 		pNotesMaster->SetSize(pNotes->GetSize());
1955 		pNotesMaster->SetBorder(pNotes->GetLftBorder(),
1956 								pNotes->GetUppBorder(),
1957 								pNotes->GetRgtBorder(),
1958 								pNotes->GetLwrBorder() );
1959 		pNotesMaster->SetName(aName);
1960 		pNotesMaster->SetLayoutName(aPageLayoutName);
1961 		InsertMasterPage(pNotesMaster);
1962 
1963 		if( bUndo )
1964 			AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1965 
1966 		pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
1967 
1968 		if( bUndo )
1969 			EndUndo();
1970 
1971 		/*********************************************************************
1972 		|* Liste der betroffenen Standard- und Notizseiten erstellen
1973 		\********************************************************************/
1974 		List* pPageList = new List;
1975 		if (bMaster)
1976 		{
1977 			for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1978 			{
1979 				pPage = (SdPage*) GetPage(nPage);
1980 				const String s(pPage->GetLayoutName());
1981 				if(s == aOldPageLayoutName)
1982 				{
1983 					pPageList->Insert(pPage, LIST_APPEND);
1984 				}
1985 			}
1986 		}
1987 		else
1988 		{
1989 			pPageList->Insert(pSelectedPage, LIST_APPEND);
1990 			pPageList->Insert(pNotes, LIST_APPEND);
1991 		}
1992 
1993 		/*********************************************************************
1994 		|* An den betroffenen Seiten Praesentations- und Autolayout setzen
1995 		\********************************************************************/
1996 		pPage = (SdPage*)pPageList->First();
1997 		while(pPage)
1998 		{
1999 			AutoLayout eOldAutoLayout = pPage->GetAutoLayout();
2000 			AutoLayout eNewAutoLayout =
2001 				pPage->GetPageKind() == PK_STANDARD ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES;
2002 
2003 			if( bUndo )
2004 			{
2005 				SdPresentationLayoutUndoAction * pPLUndoAction =
2006 					new SdPresentationLayoutUndoAction
2007 							(this, aOldLayoutName, aName,
2008 							 eOldAutoLayout, eNewAutoLayout, sal_True,
2009 							 pPage);
2010 				pUndoMgr->AddUndoAction(pPLUndoAction);
2011 			}
2012 
2013 			pPage->SetPresentationLayout(aName);
2014 			pPage->SetAutoLayout(eNewAutoLayout);
2015 
2016 			pPage = (SdPage*)pPageList->Next();
2017 		}
2018 
2019 		// Seitenliste loeschen
2020 		delete pPageList;
2021 	}
2022 
2023 	/*********************************************************************
2024 	|* falls die alten Masterpages nicht mehr benoetigt werden,
2025 	|* muessen sie und die entsprechenden Praesentationsvorlagen
2026 	|* entfernt werden
2027 	\********************************************************************/
2028 	if (bCheckMasters)
2029 	{
2030 		// Alle pruefen
2031 		RemoveUnnecessaryMasterPages();
2032 	}
2033 	else
2034 	{
2035 		// Nur die ausgetauschte MasterPage pruefen
2036 		RemoveUnnecessaryMasterPages(&rOldMaster);
2037 	}
2038 
2039 	if( bUndo )
2040 		pUndoMgr->LeaveListAction();
2041 
2042 	if( mpDocSh )
2043 		mpDocSh->SetWaitCursor( sal_False );
2044 }
2045 
2046 
2047 
2048 void SdDrawDocument::Merge(SdrModel& rSourceModel,
2049 			   sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
2050 			   sal_uInt16 nDestPos,
2051 			   FASTBOOL bMergeMasterPages, FASTBOOL bAllMasterPages,
2052 			   FASTBOOL bUndo, FASTBOOL bTreadSourceAsConst)
2053 {
2054     sal_uInt16 nMasterPageCount = GetMasterPageCount();
2055 	SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst );
2056 
2057     // add style family for each new master page
2058     for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ )
2059     {
2060         SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) );
2061         if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PK_STANDARD) )
2062         {
2063 		    // new master page created, add its style family
2064             SdStyleSheetPool* pStylePool = (SdStyleSheetPool*) GetStyleSheetPool();
2065             if( pStylePool )
2066                 pStylePool->AddStyleFamily( pPage );
2067         }
2068     }
2069 }
2070