xref: /trunk/main/sd/source/core/drawdoc3.cxx (revision 26a7fe9c)
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 
OpenBookmarkDoc(SfxMedium & rMedium)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 
OpenBookmarkDoc(const String & rBookmarkFile)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 
InsertBookmark(List * pBookmarkList,List * pExchangeList,sal_Bool bLink,sal_Bool bReplace,sal_uInt16 nInsertPos,sal_Bool bNoDialogs,::sd::DrawDocShell * pBookmarkDocSh,sal_Bool bCopy,Point * pObjPos)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 
~InsertBookmarkAsPage_PageFunctorBase()284 SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase::~InsertBookmarkAsPage_PageFunctorBase()
285 {
286 }
287 
IterateBookmarkPages(SdDrawDocument * pBookmarkDoc,List * pBookmarkList,sal_uInt16 nBMSdPageCount,SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase & rPageIterator)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:
InsertBookmarkAsPage_FindDuplicateLayouts(List * pLayoutsToTransfer,SdDrawDocument * pBookmarkDoc,List * pBookmarkList,sal_uInt16 nBMSdPageCount)357     InsertBookmarkAsPage_FindDuplicateLayouts( List* pLayoutsToTransfer, SdDrawDocument* pBookmarkDoc,
358                                                List* pBookmarkList, sal_uInt16 nBMSdPageCount ) :
359         mpLayoutsToTransfer(pLayoutsToTransfer), mpBookmarkDoc(pBookmarkDoc),
360         mpBookmarkList(pBookmarkList), mnBMSdPageCount(nBMSdPageCount) {}
~InsertBookmarkAsPage_FindDuplicateLayouts()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 
operator ()(SdDrawDocument & rDoc,SdPage * pBMMPage)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:
InsertBookmarkAsPage_AddBookmarkedPages(::std::vector<SdPage * > & rContainer)416     InsertBookmarkAsPage_AddBookmarkedPages(::std::vector<SdPage*>& rContainer)
417         : mrContainer(rContainer) {}
~InsertBookmarkAsPage_AddBookmarkedPages(void)418     ~InsertBookmarkAsPage_AddBookmarkedPages(void) {}
operator ()(SdDrawDocument &,SdPage * pPage)419     void operator() (SdDrawDocument&, SdPage* pPage) { mrContainer.push_back(pPage); }
420 private:
421     ::std::vector<SdPage*>& mrContainer;
422 };
423 
424 
InsertBookmarkAsPage(List * pBookmarkList,List * pExchangeList,sal_Bool bLink,sal_Bool bReplace,sal_uInt16 nInsertPos,sal_Bool bNoDialogs,::sd::DrawDocShell * pBookmarkDocSh,sal_Bool bCopy,sal_Bool bMergeMasterPages,sal_Bool bPreservePageNames)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 
InsertBookmarkAsObject(List * pBookmarkList,List * pExchangeList,sal_Bool,::sd::DrawDocShell * pBookmarkDocSh,Point * pObjPos)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 
CloseBookmarkDoc()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 
LoadModel(const String & rFileName)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 
DisposeLoadedModels()1211 void SdDrawDocument::DisposeLoadedModels()
1212 {
1213 	CloseBookmarkDoc();
1214 }
1215 
1216 /*************************************************************************
1217 |*
1218 |* Ist das Dokument read-only?
1219 |*
1220 \************************************************************************/
1221 
IsReadOnly() const1222 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 
SetAllocDocSh(sal_Bool bAlloc)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 
GetCustomShowList(sal_Bool bCreate)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 
GetDocumentStream(SdrDocumentStreamInfo & rStreamInfo) const1270 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 
RemoveUnnecessaryMasterPages(SdPage * pMasterPage,sal_Bool bOnlyDuplicatePages,sal_Bool bUndo)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 // #121863# factored out functionality
isMasterPageLayoutNameUnique(const SdDrawDocument & rDoc,const String & rCandidate)1516 bool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, const String& rCandidate)
1517 {
1518     if(!rCandidate.Len())
1519     {
1520         return false;
1521     }
1522 
1523     const sal_uInt16 nPageCount(rDoc.GetMasterPageCount());
1524 
1525     for(sal_uInt16 a(0); a < nPageCount; a++)
1526     {
1527         const SdrPage* pCandidate = rDoc.GetMasterPage(a);
1528         String aPageLayoutName(pCandidate->GetLayoutName());
1529         aPageLayoutName.Erase(aPageLayoutName.SearchAscii(SD_LT_SEPARATOR));
1530 
1531         if(aPageLayoutName == rCandidate)
1532         {
1533             return false;
1534         }
1535     }
1536 
1537     return true;
1538 }
1539 
1540 // #121863# factored out functinality
createNewMasterPageLayoutName(const SdDrawDocument & rDoc)1541 String createNewMasterPageLayoutName(const SdDrawDocument& rDoc)
1542 {
1543     const String aBaseName(SdResId(STR_LAYOUT_DEFAULT_NAME));
1544     String aRetval;
1545     sal_uInt16 nCount(0);
1546 
1547     while(!aRetval.Len())
1548     {
1549         aRetval = aBaseName;
1550 
1551         if(nCount)
1552         {
1553             aRetval += String::CreateFromInt32(nCount);
1554         }
1555 
1556         nCount++;
1557 
1558         if(!isMasterPageLayoutNameUnique(rDoc, aRetval))
1559         {
1560             aRetval.Erase();
1561         }
1562     }
1563 
1564     return aRetval;
1565 }
1566 
SetMasterPage(sal_uInt16 nSdPageNum,const String & rLayoutName,SdDrawDocument * pSourceDoc,sal_Bool bMaster,sal_Bool bCheckMasters)1567 void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum,
1568 								   const String& rLayoutName,
1569 								   SdDrawDocument* pSourceDoc,
1570 								   sal_Bool bMaster,
1571 								   sal_Bool bCheckMasters)
1572 {
1573 	if( mpDocSh )
1574 		mpDocSh->SetWaitCursor( sal_True );
1575 
1576 	::svl::IUndoManager* pUndoMgr = mpDocSh->GetUndoManager();
1577 
1578 	const bool bUndo = IsUndoEnabled();
1579 
1580 	if( bUndo )
1581 	{
1582 		pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());
1583 	}
1584 
1585 	SdPage* pSelectedPage   = GetSdPage(nSdPageNum, PK_STANDARD);
1586 	SdPage* pNotes			= (SdPage*) GetPage(pSelectedPage->GetPageNum()+1);
1587 	SdPage& rOldMaster		= (SdPage&)pSelectedPage->TRG_GetMasterPage();
1588 	SdPage& rOldNotesMaster = (SdPage&)pNotes->TRG_GetMasterPage();
1589 	SdPage* pMaster 		= NULL;
1590 	SdPage* pNotesMaster	= NULL;
1591 	SdPage* pPage			= NULL;
1592 	String aOldPageLayoutName(pSelectedPage->GetLayoutName());
1593 	String aOldLayoutName(aOldPageLayoutName);
1594 	aOldLayoutName.Erase(aOldLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1595 
1596 	if (pSourceDoc)
1597 	{
1598 		List* pReplList = NULL;
1599 		sal_Bool bLayoutReloaded = sal_False; 	// Wurde ex. Layout wieder geladen?
1600 
1601 		/*********************************************************************
1602 		|* LayoutName, Page and Notespage
1603 		\*********************************************************************/
1604 		if (rLayoutName.Len() == 0)
1605 		{
1606 			// No LayoutName: take first MasterPage
1607 			pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1608 			pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1609 		}
1610 		else
1611 		{
1612 			String aSearchFor(rLayoutName);
1613 			aSearchFor.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
1614 			aSearchFor.Append( String(SdResId(STR_LAYOUT_OUTLINE))) ;
1615 
1616 			for (sal_uInt16 nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); nMP++)
1617 			{
1618 				SdPage* pMP = (SdPage*) pSourceDoc->GetMasterPage(nMP);
1619 
1620 				if (pMP->GetLayoutName() == aSearchFor)
1621 				{
1622 					if (pMP->GetPageKind() == PK_STANDARD)
1623 						pMaster = pMP;
1624 					if (pMP->GetPageKind() == PK_NOTES)
1625 						pNotesMaster = pMP;
1626 				}
1627 				if (pMaster && pNotesMaster)
1628 					break;
1629 			}
1630 			DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
1631 			DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
1632 
1633 			// this should not happen, but looking at crashreports, it does
1634 			if( (pMaster == NULL) || (pNotesMaster == NULL) )
1635 			{
1636 				// so take the first MasterPage
1637 				pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1638 				pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1639 			}
1640 		}
1641 
1642 		// we should never reach this, but one never knows....
1643 		if( (pMaster == NULL) || (pNotesMaster == NULL) )
1644 		{
1645 			pUndoMgr->LeaveListAction();
1646 
1647 			if( mpDocSh )
1648 				mpDocSh->SetWaitCursor( sal_False );
1649 
1650 			DBG_ERROR( "SdDrawDocument::SetMasterPage() failed!" );
1651 
1652 			return;
1653 		}
1654 
1655         const String aOriginalNewLayoutName( pMaster->GetName() );
1656         String aTargetNewLayoutName(aOriginalNewLayoutName);
1657 
1658         if (pSourceDoc != this)
1659         {
1660             // #121863# clone masterpages, they are from another model (!)
1661             SdPage* pNewNotesMaster = dynamic_cast< SdPage* >(pNotesMaster->Clone(this));
1662             SdPage* pNewMaster = dynamic_cast< SdPage* >(pMaster->Clone(this));
1663 
1664             if(!pNewNotesMaster || !pNewMaster)
1665             {
1666                 delete pNewNotesMaster;
1667                 delete pNewMaster;
1668                 OSL_ASSERT("SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" );
1669                 return;
1670             }
1671 
1672             pNotesMaster = pNewNotesMaster;
1673             pMaster = pNewMaster;
1674 
1675             // layout name needs to be unique
1676             aTargetNewLayoutName = pMaster->GetLayoutName();
1677             aTargetNewLayoutName.Erase(aTargetNewLayoutName.SearchAscii(SD_LT_SEPARATOR));
1678 
1679             if(!isMasterPageLayoutNameUnique(*this, aTargetNewLayoutName))
1680             {
1681                 aTargetNewLayoutName = createNewMasterPageLayoutName(*this);
1682 
1683                 String aTemp(aTargetNewLayoutName);
1684                 aTemp.AppendAscii(RTL_CONSTASCII_STRINGPARAM(SD_LT_SEPARATOR));
1685                 aTemp.Append(String(SdResId(STR_LAYOUT_OUTLINE)));
1686 
1687                 pMaster->SetName(aTargetNewLayoutName);
1688                 pMaster->SetLayoutName(aTemp);
1689 
1690                 pNotesMaster->SetName(aTargetNewLayoutName);
1691                 pNotesMaster->SetLayoutName(aTemp);
1692             }
1693         }
1694 
1695         if (pSourceDoc != this)
1696         {
1697 			const sal_uInt16 nMasterPageCount = GetMasterPageCount();
1698 			for ( sal_uInt16 nMPage = 0; nMPage < nMasterPageCount; nMPage++ )
1699 			{
1700 				SdPage* pCheckMaster = (SdPage*)GetMasterPage(nMPage);
1701 				if( pCheckMaster->GetName() == aTargetNewLayoutName )
1702 				{
1703 					bLayoutReloaded = sal_True;
1704 					break;
1705 				}
1706 			}
1707 
1708 			/*****************************************************************
1709 			|* Praesentationsvorlagen korrigieren bzw. neu anlegen
1710 			\****************************************************************/
1711 			// nur die Praesentationsvorlagen beachten
1712 			String aName;
1713 			SdStyleSheetPool* pSourceStyleSheetPool = (SdStyleSheetPool*) pSourceDoc->GetStyleSheetPool();
1714 			pSourceStyleSheetPool->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1715 			static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1716 
1717 			pReplList = new List;         	// Liste fuer ersetzte StyleSheets
1718 			SdStyleSheetVector aCreatedStyles;			// Liste fuer erzeugte StyleSheets
1719 
1720 			SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First();
1721 
1722 			while (pHisSheet)
1723 			{
1724 				aName = pHisSheet->GetName();
1725 
1726                 // #121863# search in source styles with original style name from source of
1727                 // evtl. cloned master (not-cloned, renamed for uniqueness)
1728 				if( aName.Search( aOriginalNewLayoutName ) == 0 )
1729 				{
1730                     // #121863# build name of evtl. cloned master style to search for
1731                     if(aOriginalNewLayoutName != aTargetNewLayoutName)
1732                     {
1733                         const sal_uInt16 nPos(aName.SearchAscii(SD_LT_SEPARATOR));
1734                         aName.Erase(0, nPos);
1735                         aName.Insert(aTargetNewLayoutName, 0);
1736                     }
1737 
1738                     SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SD_STYLE_FAMILY_MASTERPAGE) );
1739 
1740 					if (pMySheet)
1741 					{
1742 						// Es ist eine gleichnamige Vorlage vorhanden ist: Inhalte ersetzen
1743 #ifdef DBG_UTIL
1744 						sal_Bool bTest =
1745 #endif
1746 							pMySheet->SetName(pHisSheet->GetName());
1747 						DBG_ASSERT(bTest, "StyleSheet-Umbenennung fehlgeschlagen");
1748 						pMySheet->GetItemSet().ClearItem(0);  // alle loeschen
1749 
1750 						StyleSheetUndoAction* pUndoChStyle = new StyleSheetUndoAction(this,
1751 																 pMySheet, &pHisSheet->GetItemSet());
1752 						pUndoMgr->AddUndoAction(pUndoChStyle);
1753 						pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1754 						pMySheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
1755 					}
1756 					else
1757 					{
1758 					    // create new style
1759                         String aHelpFile;
1760 						pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SD_STYLE_FAMILY_MASTERPAGE, pHisSheet->GetMask()) );
1761                         pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) );
1762 						pMySheet->GetItemSet().ClearItem(0);  // alle loeschen
1763 						pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1764 
1765 						aCreatedStyles.push_back( SdStyleSheetRef( static_cast< SdStyleSheet* >( pMySheet ) ) );
1766 					}
1767 
1768 					StyleReplaceData* pReplData = new StyleReplaceData;
1769 					pReplData->nNewFamily = pMySheet->GetFamily();
1770 					pReplData->nFamily    = pMySheet->GetFamily();
1771 					pReplData->aNewName   = pMySheet->GetName();
1772 
1773                     // #121863# re-create original name of styte used at page where to replace with
1774                     // this new style
1775 					String aTemp(pMySheet->GetName());
1776 					const sal_uInt16 nPos(aTemp.SearchAscii(SD_LT_SEPARATOR));
1777 					aTemp.Erase(0, nPos);
1778 					aTemp.Insert(aOldLayoutName, 0);
1779 
1780                     pReplData->aName = aTemp;
1781 					pReplList->Insert(pReplData, LIST_APPEND);
1782 				}
1783 
1784 				pHisSheet = (SfxStyleSheet*) pSourceStyleSheetPool->Next();
1785 			}
1786 
1787 			// wenn neue Vorlagen erzeugt wurden:
1788 			// eventuell bestehende Parent-Verkettung der Itemsets in den
1789 			// Vorlagen wieder aufbauen
1790 			if(!aCreatedStyles.empty())
1791 			{
1792 				StyleReplaceData* pRData = (StyleReplaceData*)pReplList->First();
1793 
1794 				while (pRData)
1795 				{
1796 					SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(pRData->aName);
1797 					SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(pRData->aNewName);
1798 
1799 					if (pSOld && pSNew)
1800 					{
1801 						const String& rParentOfOld = pSOld->GetParent();
1802 						const String& rParentOfNew = pSNew->GetParent();
1803 
1804 						if (rParentOfOld.Len() > 0 && rParentOfNew.Len() == 0)
1805 						{
1806 
1807 							for (sal_uLong i = 0; i < pReplList->Count(); i++)
1808 							{
1809 								StyleReplaceData* pRD = (StyleReplaceData*)pReplList->
1810 																		GetObject(i);
1811 								if ((pRD->aName == rParentOfOld) && (pRD->aName != pRD->aNewName))
1812 								{
1813 									String aParentOfNew(pRD->aNewName);
1814 									pSNew->SetParent(aParentOfNew);
1815 									break;
1816 								}
1817 							}
1818 						}
1819 					}
1820 					pRData = (StyleReplaceData*) pReplList->Next();
1821 				}
1822 
1823 				// ab jetzt beim Suchen alle beachten
1824 				pSourceStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1825 				mxStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1826 			}
1827 
1828 			if( !aCreatedStyles.empty() )
1829 			{
1830 				// UndoAction fuer das Erzeugen und Einfuegen vorn StyleSheets
1831 				// auf den UndoManager legen
1832 				SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aCreatedStyles, sal_True);
1833 				pUndoMgr->AddUndoAction(pMovStyles);
1834 			}
1835 		}
1836 
1837 		// Layoutnamen auf Basis des Seitenlayoutnamens der Masterpage bilden
1838 		String aPageLayoutName(pMaster->GetLayoutName());
1839 		String aLayoutName = aPageLayoutName;
1840 		aLayoutName.Erase( aLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1841 
1842         // #121863# Do *not* remove from original document any longer, it is potentially used there
1843         // and would lead to crashes. Rely on the automatic process of removing unused masterpages
1844         // (see RemoveUnnecessaryMasterPages)
1845 		//if (pSourceDoc != this)
1846 		//{
1847 		//	// Aus dem Source-Dokument austragen
1848 		//	SdrPage* pTest = NULL;
1849 		//	pTest = pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1850 		//	pTest = pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1851 		//}
1852 
1853 		/*********************************************************************
1854 		|* Neue MasterPages ins Dokument eintragen und den Standard- und
1855 		|* Notizseiten das Praesentationslayout ueberbraten
1856 		\********************************************************************/
1857 		if (pSourceDoc != this)
1858 		{
1859 			// Die Masterpages einfuegen:
1860 			// Masterpages von neuen Layouts hinten anhaengen; wird ein Layout
1861 			// dagegen ersetzt, so muss vor der Position der alten Masterpage
1862 			// eingefuegt werden, damit ab jetzt beim Suchen (z. B. SdPage::
1863 			// SetPresentationLayout) die neue Masterpage zuerst gefunden wird
1864 			sal_uInt16 nInsertPos = rOldMaster.GetPageNum();
1865 			BegUndo();
1866 
1867 			if (!bLayoutReloaded)
1868 				nInsertPos = 0xFFFF;
1869 			InsertMasterPage(pMaster, nInsertPos);
1870 			if( bUndo )
1871 				AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1872 
1873 			nInsertPos++;
1874 			if (!bLayoutReloaded)
1875 				nInsertPos = 0xFFFF;
1876 			InsertMasterPage(pNotesMaster, nInsertPos);
1877 			if( bUndo )
1878 			{
1879 				AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1880 
1881 				EndUndo(); // schon hier, damit sich Joes Actions ZWISCHEN unsere eigenen schieben
1882 			}
1883 		}
1884 
1885 		// Liste mit Seiten fuellen
1886 		List* pPageList = new List;
1887 
1888 //      #98456, this has to be removed according to CL (KA 07/08/2002)
1889 //		#109884# but we need them again to restore the styles of the presentation objects while undo
1890 		pPageList->Insert(pMaster, LIST_APPEND);
1891 		pPageList->Insert(pNotesMaster, LIST_APPEND);
1892 
1893 		if (bMaster || bLayoutReloaded)
1894 		{
1895 			for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1896 			{
1897 				pPage = (SdPage*) GetPage(nPage);
1898 				String aTest = pPage->GetLayoutName();
1899 				if (aTest == aOldPageLayoutName)
1900 				{
1901 					pPageList->Insert(pPage, LIST_APPEND);
1902 				}
1903 			}
1904 
1905 		}
1906 		else
1907 		{
1908 			pPageList->Insert(pSelectedPage, LIST_APPEND);
1909 			pPageList->Insert(pNotes, LIST_APPEND);
1910 		}
1911 
1912 		pPage = (SdPage*)pPageList->First();
1913 		while (pPage)
1914 		{
1915 			AutoLayout eAutoLayout = pPage->GetAutoLayout();
1916 
1917 			if( bUndo )
1918 			{
1919 				SdPresentationLayoutUndoAction * pPLUndoAction =
1920 					new SdPresentationLayoutUndoAction
1921 						(this,
1922 						pPage->IsMasterPage() ? aLayoutName : aOldLayoutName,
1923 						aLayoutName,
1924 						 eAutoLayout, eAutoLayout, sal_False, pPage);
1925 				pUndoMgr->AddUndoAction(pPLUndoAction);
1926 			}
1927 			pPage->SetPresentationLayout(aLayoutName);
1928 			pPage->SetAutoLayout(eAutoLayout);
1929 
1930 			pPage = (SdPage*)pPageList->Next();
1931 		}
1932 		delete pPageList;
1933 
1934 		/*********************************************************************
1935 		|* Neue Masterpages angleichen
1936 		\********************************************************************/
1937 		if (pSourceDoc != this)
1938 		{
1939 			// die Masterpages angleichen
1940 			Size aSize(rOldMaster.GetSize());
1941 			Rectangle aBorderRect(rOldMaster.GetLftBorder(),
1942 								  rOldMaster.GetUppBorder(),
1943 								  rOldMaster.GetRgtBorder(),
1944 								  rOldMaster.GetLwrBorder());
1945 			pMaster->ScaleObjects(aSize, aBorderRect, sal_True);
1946 			pMaster->SetSize(aSize);
1947 			pMaster->SetBorder(rOldMaster.GetLftBorder(),
1948 							   rOldMaster.GetUppBorder(),
1949 							   rOldMaster.GetRgtBorder(),
1950 							   rOldMaster.GetLwrBorder());
1951 			pMaster->SetOrientation( rOldMaster.GetOrientation() );
1952 			pMaster->SetAutoLayout(pMaster->GetAutoLayout());
1953 
1954 			aSize = rOldNotesMaster.GetSize();
1955 			Rectangle aNotesBorderRect(rOldNotesMaster.GetLftBorder(),
1956 									   rOldNotesMaster.GetUppBorder(),
1957 									   rOldNotesMaster.GetRgtBorder(),
1958 									   rOldNotesMaster.GetLwrBorder());
1959 			pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, sal_True);
1960 			pNotesMaster->SetSize(aSize);
1961 			pNotesMaster->SetBorder(rOldNotesMaster.GetLftBorder(),
1962 									rOldNotesMaster.GetUppBorder(),
1963 									rOldNotesMaster.GetRgtBorder(),
1964 									rOldNotesMaster.GetLwrBorder());
1965 			pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() );
1966 			pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout());
1967 
1968 			// Liste der ersetzten Vorlagen mit Inhalt loeschen
1969 			StyleReplaceData* pReplData = (StyleReplaceData*)pReplList->First();
1970 			while (pReplData)
1971 			{
1972 				delete pReplData;
1973 				pReplData = (StyleReplaceData*)pReplList->Next();
1974 			}
1975 			delete pReplList;
1976 
1977 
1978 			if( (pSourceDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
1979 				(GetDocumentType() == DOCUMENT_TYPE_DRAW) )
1980 			{
1981 				pMaster->RemoveEmptyPresentationObjects();
1982 				pNotesMaster->RemoveEmptyPresentationObjects();
1983 			}
1984 		}
1985 	}
1986 	else
1987 	{
1988 		/*********************************************************************
1989 		|* Einen neuen Layoutnamen ausdenken
1990 		\********************************************************************/
1991         String aName(createNewMasterPageLayoutName(*this));
1992 		String aPageLayoutName(aName);
1993 		aPageLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
1994 		aPageLayoutName += String(SdResId(STR_LAYOUT_OUTLINE));
1995 
1996 		/*********************************************************************
1997 		|* Neue StyleSheets erzeugen
1998 		\********************************************************************/
1999 		static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName);
2000 		SdStyleSheetVector aCreatedStyles;
2001 		static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles);
2002 
2003 		if( bUndo )
2004 		{
2005 			SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, sal_True);
2006 			pUndoMgr->AddUndoAction(pMovStyles);
2007 		}
2008 
2009 		/*********************************************************************
2010 		|* Neue MasterPages erzeugen und ins Dokument eintragen
2011 		\********************************************************************/
2012 
2013 		if( bUndo )
2014 			BegUndo();
2015 
2016 		pMaster = (SdPage*) AllocPage(sal_True);
2017 		pMaster->SetSize(pSelectedPage->GetSize());
2018 		pMaster->SetBorder(pSelectedPage->GetLftBorder(),
2019 						   pSelectedPage->GetUppBorder(),
2020 						   pSelectedPage->GetRgtBorder(),
2021 						   pSelectedPage->GetLwrBorder() );
2022 		pMaster->SetName(aName);
2023 		pMaster->SetLayoutName(aPageLayoutName);
2024 		InsertMasterPage(pMaster);
2025 
2026 		if( bUndo )
2027 			AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
2028 
2029 		pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
2030 
2031 		pNotesMaster = (SdPage*) AllocPage(sal_True);
2032 		pNotesMaster->SetPageKind(PK_NOTES);
2033 		pNotesMaster->SetSize(pNotes->GetSize());
2034 		pNotesMaster->SetBorder(pNotes->GetLftBorder(),
2035 								pNotes->GetUppBorder(),
2036 								pNotes->GetRgtBorder(),
2037 								pNotes->GetLwrBorder() );
2038 		pNotesMaster->SetName(aName);
2039 		pNotesMaster->SetLayoutName(aPageLayoutName);
2040 		InsertMasterPage(pNotesMaster);
2041 
2042 		if( bUndo )
2043 			AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
2044 
2045 		pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
2046 
2047 		if( bUndo )
2048 			EndUndo();
2049 
2050 		/*********************************************************************
2051 		|* Liste der betroffenen Standard- und Notizseiten erstellen
2052 		\********************************************************************/
2053 		List* pPageList = new List;
2054 		if (bMaster)
2055 		{
2056 			for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
2057 			{
2058 				pPage = (SdPage*) GetPage(nPage);
2059 				const String s(pPage->GetLayoutName());
2060 				if(s == aOldPageLayoutName)
2061 				{
2062 					pPageList->Insert(pPage, LIST_APPEND);
2063 				}
2064 			}
2065 		}
2066 		else
2067 		{
2068 			pPageList->Insert(pSelectedPage, LIST_APPEND);
2069 			pPageList->Insert(pNotes, LIST_APPEND);
2070 		}
2071 
2072 		/*********************************************************************
2073 		|* An den betroffenen Seiten Praesentations- und Autolayout setzen
2074 		\********************************************************************/
2075 		pPage = (SdPage*)pPageList->First();
2076 		while(pPage)
2077 		{
2078 			AutoLayout eOldAutoLayout = pPage->GetAutoLayout();
2079 			AutoLayout eNewAutoLayout =
2080 				pPage->GetPageKind() == PK_STANDARD ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES;
2081 
2082 			if( bUndo )
2083 			{
2084 				SdPresentationLayoutUndoAction * pPLUndoAction =
2085 					new SdPresentationLayoutUndoAction
2086 							(this, aOldLayoutName, aName,
2087 							 eOldAutoLayout, eNewAutoLayout, sal_True,
2088 							 pPage);
2089 				pUndoMgr->AddUndoAction(pPLUndoAction);
2090 			}
2091 
2092 			pPage->SetPresentationLayout(aName);
2093 			pPage->SetAutoLayout(eNewAutoLayout);
2094 
2095 			pPage = (SdPage*)pPageList->Next();
2096 		}
2097 
2098 		// Seitenliste loeschen
2099 		delete pPageList;
2100 	}
2101 
2102 	/*********************************************************************
2103 	|* falls die alten Masterpages nicht mehr benoetigt werden,
2104 	|* muessen sie und die entsprechenden Praesentationsvorlagen
2105 	|* entfernt werden
2106 	\********************************************************************/
2107 	if (bCheckMasters)
2108 	{
2109 		// Alle pruefen
2110 		RemoveUnnecessaryMasterPages();
2111 	}
2112 	else
2113 	{
2114 		// Nur die ausgetauschte MasterPage pruefen
2115 		RemoveUnnecessaryMasterPages(&rOldMaster);
2116 	}
2117 
2118 	if( bUndo )
2119 		pUndoMgr->LeaveListAction();
2120 
2121 	if( mpDocSh )
2122 		mpDocSh->SetWaitCursor( sal_False );
2123 }
2124 
2125 
2126 
Merge(SdrModel & rSourceModel,sal_uInt16 nFirstPageNum,sal_uInt16 nLastPageNum,sal_uInt16 nDestPos,FASTBOOL bMergeMasterPages,FASTBOOL bAllMasterPages,FASTBOOL bUndo,FASTBOOL bTreadSourceAsConst)2127 void SdDrawDocument::Merge(SdrModel& rSourceModel,
2128 			   sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
2129 			   sal_uInt16 nDestPos,
2130 			   FASTBOOL bMergeMasterPages, FASTBOOL bAllMasterPages,
2131 			   FASTBOOL bUndo, FASTBOOL bTreadSourceAsConst)
2132 {
2133     sal_uInt16 nMasterPageCount = GetMasterPageCount();
2134 	SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst );
2135 
2136     // add style family for each new master page
2137     for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ )
2138     {
2139         SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) );
2140         if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PK_STANDARD) )
2141         {
2142 		    // new master page created, add its style family
2143             SdStyleSheetPool* pStylePool = (SdStyleSheetPool*) GetStyleSheetPool();
2144             if( pStylePool )
2145                 pStylePool->AddStyleFamily( pPage );
2146         }
2147     }
2148 }
2149