xref: /trunk/main/sd/source/core/drawdoc3.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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