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