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