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