Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/embed/ElementModes.hpp>
21 : #include <com/sun/star/beans/XPropertySet.hpp>
22 :
23 : #include "comphelper/anytostring.hxx"
24 : #include "cppuhelper/exc_hlp.hxx"
25 :
26 : #include <vcl/wrkwin.hxx>
27 : #include <sfx2/docfile.hxx>
28 : #include <sot/storage.hxx>
29 : #include <sfx2/app.hxx>
30 : #include <svl/itemset.hxx>
31 :
32 : #include <unotools/ucbstreamhelper.hxx>
33 : #include <sfx2/fcontnr.hxx>
34 : #include <svx/svdopath.hxx>
35 : #include <svx/svditer.hxx>
36 : #include <svl/style.hxx>
37 : #include <sfx2/linkmgr.hxx>
38 : #include <svx/svdpagv.hxx>
39 : #include <svx/svdogrp.hxx>
40 : #include <svx/svdundo.hxx>
41 : #include <vcl/msgbox.hxx>
42 : #include <sot/formats.hxx>
43 :
44 : #include "glob.hrc"
45 : #include "drawdoc.hxx"
46 : #include "sdpage.hxx"
47 : #include "stlpool.hxx"
48 : #include "sdresid.hxx"
49 : #include "sdiocmpt.hxx"
50 : #include "strmname.h"
51 : #include "anminfo.hxx"
52 : #include "customshowlist.hxx"
53 :
54 : #include "../ui/inc/unmovss.hxx"
55 : #include "../ui/inc/unchss.hxx"
56 : #include "../ui/inc/unprlout.hxx"
57 : #include "../ui/inc/DrawDocShell.hxx"
58 : #include "../ui/inc/GraphicDocShell.hxx"
59 : #include "../ui/inc/ViewShell.hxx"
60 : #include "../ui/inc/View.hxx"
61 : #include "../ui/inc/cfgids.hxx"
62 : #include "../ui/inc/strings.hrc"
63 :
64 : using namespace ::com::sun::star;
65 :
66 : /** Concrete incarnations get called by lcl_IterateBookmarkPages, for
67 : every page in the bookmark document/list
68 : */
69 :
70 : class InsertBookmarkAsPage_FindDuplicateLayouts
71 : {
72 : public:
73 0 : InsertBookmarkAsPage_FindDuplicateLayouts( std::vector<OUString> &rLayoutsToTransfer )
74 0 : : mrLayoutsToTransfer(rLayoutsToTransfer) {}
75 : void operator()( SdDrawDocument&, SdPage* );
76 : private:
77 : std::vector<OUString> &mrLayoutsToTransfer;
78 : };
79 :
80 0 : void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage* pBMMPage )
81 : {
82 : // now check for duplicate masterpage and layout names
83 : // ===================================================
84 :
85 0 : String aFullNameLayout( pBMMPage->GetLayoutName() );
86 0 : aFullNameLayout.Erase( aFullNameLayout.SearchAscii( SD_LT_SEPARATOR ));
87 :
88 0 : OUString aLayout(aFullNameLayout);
89 :
90 : std::vector<OUString>::const_iterator pIter =
91 0 : find(mrLayoutsToTransfer.begin(),mrLayoutsToTransfer.end(),aLayout);
92 :
93 0 : bool bFound = pIter != mrLayoutsToTransfer.end();
94 :
95 0 : const sal_uInt16 nMPageCount = rDoc.GetMasterPageCount();
96 0 : for (sal_uInt16 nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++)
97 : {
98 : // Do the layouts already exist within the document?
99 0 : SdPage* pTestPage = (SdPage*) rDoc.GetMasterPage(nMPage);
100 0 : String aFullTest(pTestPage->GetLayoutName());
101 0 : aFullTest.Erase( aFullTest.SearchAscii( SD_LT_SEPARATOR ));
102 :
103 0 : OUString aTest(aFullTest);
104 :
105 0 : if (aTest == aLayout)
106 0 : bFound = true;
107 0 : }
108 :
109 0 : if (!bFound)
110 0 : mrLayoutsToTransfer.push_back(aLayout);
111 0 : }
112 :
113 : // Inserts a bookmark as a page
114 0 : static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBookmarkDoc,
115 : const std::vector<OUString> &rBookmarkList, sal_uInt16 nBMSdPageCount,
116 : InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator )
117 : {
118 : //
119 : // Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage
120 : //
121 : int nPos, nEndPos;
122 :
123 0 : if( rBookmarkList.empty() )
124 : {
125 : // no list? whole source document
126 0 : nEndPos = nBMSdPageCount;
127 : }
128 : else
129 : {
130 : // bookmark list? number of entries
131 0 : nEndPos = rBookmarkList.size();
132 : }
133 :
134 : SdPage* pBMPage;
135 :
136 : // iterate over number of pages to insert
137 0 : for (nPos = 0; nPos < nEndPos; ++nPos)
138 : {
139 : // the master page associated to the nPos'th page to insert
140 0 : SdPage* pBMMPage = NULL;
141 :
142 0 : if( rBookmarkList.empty() )
143 : {
144 : // simply take master page of nPos'th page in source document
145 0 : pBMMPage = (SdPage*)(&(pBookmarkDoc->GetSdPage((sal_uInt16)nPos, PK_STANDARD)->TRG_GetMasterPage()));
146 : }
147 : else
148 : {
149 : // fetch nPos'th entry from bookmark list, and determine master page
150 0 : String aBMPgName(rBookmarkList[nPos]);
151 : sal_Bool bIsMasterPage;
152 :
153 0 : sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage );
154 :
155 0 : if (nBMPage != SDRPAGE_NOTFOUND)
156 : {
157 0 : pBMPage = (SdPage*) pBookmarkDoc->GetPage(nBMPage);
158 : }
159 : else
160 : {
161 0 : pBMPage = NULL;
162 : }
163 :
164 : // enforce that bookmarked page is a standard page and not already a master page
165 0 : if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage())
166 : {
167 0 : const sal_uInt16 nBMSdPage = (nBMPage - 1) / 2;
168 0 : pBMMPage = (SdPage*) (&(pBookmarkDoc->GetSdPage(nBMSdPage, PK_STANDARD)->TRG_GetMasterPage()));
169 0 : }
170 : }
171 :
172 : // successfully determined valid (bookmarked) page?
173 0 : if( pBMMPage )
174 : {
175 : // yes, call functor
176 0 : rPageIterator( rDoc, pBMMPage );
177 : }
178 : }
179 0 : }
180 :
181 : // Opens a bookmark document
182 0 : SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(SfxMedium& rMedium)
183 : {
184 0 : sal_Bool bOK = sal_True;
185 0 : SdDrawDocument* pBookmarkDoc = NULL;
186 0 : String aBookmarkName = rMedium.GetName();
187 0 : const SfxFilter* pFilter = rMedium.GetFilter();
188 0 : if ( !pFilter )
189 : {
190 0 : rMedium.UseInteractionHandler( sal_True );
191 0 : SFX_APP()->GetFilterMatcher().GuessFilter( rMedium, &pFilter );
192 : }
193 :
194 0 : if ( !pFilter )
195 : {
196 0 : bOK = sal_False;
197 : }
198 0 : else if ( maBookmarkFile != aBookmarkName && aBookmarkName.Len() )
199 : {
200 0 : sal_Bool bCreateGraphicShell = pFilter->GetServiceName() == "com.sun.star.drawing.DrawingDocument";
201 0 : sal_Bool bCreateImpressShell = pFilter->GetServiceName() == "com.sun.star.presentation.PresentationDocument";
202 0 : if ( bCreateGraphicShell || bCreateImpressShell )
203 : {
204 0 : CloseBookmarkDoc();
205 :
206 : // Create a DocShell, as OLE objects might be contained in the
207 : // document. (Persist)
208 : // If that wasn't the case, we could load the model directly.
209 0 : if ( bCreateGraphicShell )
210 : // Draw
211 0 : mxBookmarkDocShRef = new ::sd::GraphicDocShell(SFX_CREATE_MODE_STANDARD, sal_True);
212 : else
213 : // Impress
214 0 : mxBookmarkDocShRef = new ::sd::DrawDocShell(SFX_CREATE_MODE_STANDARD, sal_True);
215 :
216 0 : bOK = mxBookmarkDocShRef->DoLoad(&rMedium);
217 0 : if( bOK )
218 : {
219 0 : maBookmarkFile = aBookmarkName;
220 0 : pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
221 : }
222 : }
223 : }
224 :
225 : DBG_ASSERT(aBookmarkName.Len(), "Empty document name!");
226 :
227 0 : if (!bOK)
228 : {
229 0 : ErrorBox aErrorBox( NULL, (WinBits)WB_OK, String(SdResId(STR_READ_DATA_ERROR)));
230 0 : aErrorBox.Execute();
231 :
232 0 : CloseBookmarkDoc();
233 0 : pBookmarkDoc = NULL;
234 : }
235 0 : else if (mxBookmarkDocShRef.Is())
236 : {
237 0 : pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
238 : }
239 :
240 0 : return(pBookmarkDoc);
241 : }
242 :
243 : // Opens a bookmark document
244 0 : SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(const String& rBookmarkFile)
245 : {
246 0 : SdDrawDocument* pBookmarkDoc = NULL;
247 :
248 0 : if (maBookmarkFile != rBookmarkFile && rBookmarkFile.Len())
249 : {
250 0 : SfxMedium* pMedium = new SfxMedium( rBookmarkFile, STREAM_READ );
251 0 : pBookmarkDoc = OpenBookmarkDoc(*pMedium);
252 : }
253 0 : else if (mxBookmarkDocShRef.Is())
254 : {
255 0 : pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
256 : }
257 :
258 0 : return(pBookmarkDoc);
259 : }
260 :
261 : // Inserts a bookmark (page or object)
262 0 : sal_Bool SdDrawDocument::InsertBookmark(
263 : const std::vector<OUString> &rBookmarkList, // List of names of the bookmarks to be inserted
264 : std::vector<OUString> &rExchangeList, // List of the names to be used
265 : sal_Bool bLink, // Insert bookmarks as links?
266 : sal_Bool bReplace, // Replace current default and notes pages?
267 : sal_uInt16 nInsertPos, // Insertion position of pages
268 : sal_Bool bNoDialogs, // Don't show dialogs
269 : ::sd::DrawDocShell* pBookmarkDocSh, // If set, this is the source document
270 : sal_Bool bCopy, // Copy the pages?
271 : Point* pObjPos) // Insertion position of objects
272 : {
273 0 : sal_Bool bOK = sal_True;
274 0 : sal_Bool bInsertPages = sal_False;
275 :
276 0 : if (rBookmarkList.empty())
277 : {
278 : // Insert all pages
279 0 : bInsertPages = sal_True;
280 : }
281 : else
282 : {
283 0 : SdDrawDocument* pBookmarkDoc = NULL;
284 0 : String aBookmarkName;
285 :
286 0 : if (pBookmarkDocSh)
287 : {
288 0 : pBookmarkDoc = pBookmarkDocSh->GetDoc();
289 0 : aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
290 : }
291 0 : else if ( mxBookmarkDocShRef.Is() )
292 : {
293 0 : pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
294 0 : aBookmarkName = maBookmarkFile;
295 : }
296 : else
297 0 : bOK = sal_False;
298 :
299 0 : std::vector<OUString>::const_iterator pIter;
300 0 : for ( pIter = rBookmarkList.begin(); bOK && pIter != rBookmarkList.end() && !bInsertPages; ++pIter )
301 : {
302 : // Is there a page name in the bookmark list?
303 0 : String aBMPgName(*pIter);
304 : sal_Bool bIsMasterPage;
305 :
306 0 : if( pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
307 : {
308 : // Found the page
309 0 : bInsertPages = sal_True;
310 : }
311 0 : }
312 : }
313 :
314 0 : sal_Bool bCalcObjCount = !rExchangeList.empty();
315 :
316 0 : if ( bOK && bInsertPages )
317 : {
318 : // Insert all page bookmarks
319 : bOK = InsertBookmarkAsPage(rBookmarkList, &rExchangeList, bLink, bReplace,
320 0 : nInsertPos, bNoDialogs, pBookmarkDocSh, bCopy, sal_True, sal_False);
321 : }
322 :
323 0 : if ( bOK && !rBookmarkList.empty() )
324 : {
325 : // Insert all object bookmarks
326 : bOK = InsertBookmarkAsObject(rBookmarkList, rExchangeList, bLink,
327 0 : pBookmarkDocSh, pObjPos, bCalcObjCount);
328 : }
329 :
330 0 : return bOK;
331 : }
332 :
333 : namespace
334 : {
335 :
336 : void
337 0 : lcl_removeUnusedStyles(SfxStyleSheetBasePool* const pStyleSheetPool, SdStyleSheetVector& rStyles)
338 : {
339 0 : SdStyleSheetVector aUsedStyles;
340 0 : aUsedStyles.reserve(rStyles.size());
341 0 : for (SdStyleSheetVector::const_iterator aIt(rStyles.begin()), aLast(rStyles.end()); aIt != aLast; ++aIt)
342 : {
343 0 : if ((*aIt)->IsUsed())
344 0 : aUsedStyles.push_back(*aIt);
345 : else
346 0 : pStyleSheetPool->Remove((*aIt).get());
347 : }
348 0 : rStyles = aUsedStyles;
349 0 : }
350 :
351 : }
352 :
353 0 : sal_Bool SdDrawDocument::InsertBookmarkAsPage(
354 : const std::vector<OUString> &rBookmarkList,
355 : std::vector<OUString> *pExchangeList, // List of names to be used
356 : sal_Bool bLink,
357 : sal_Bool bReplace,
358 : sal_uInt16 nInsertPos,
359 : sal_Bool bNoDialogs,
360 : ::sd::DrawDocShell* pBookmarkDocSh,
361 : sal_Bool bCopy,
362 : sal_Bool bMergeMasterPages,
363 : sal_Bool bPreservePageNames)
364 : {
365 0 : sal_Bool bOK = sal_True;
366 0 : sal_Bool bContinue = sal_True;
367 0 : sal_Bool bScaleObjects = sal_False;
368 0 : sal_uInt16 nReplacedStandardPages = 0;
369 :
370 0 : SdDrawDocument* pBookmarkDoc = NULL;
371 0 : String aBookmarkName;
372 :
373 0 : if (pBookmarkDocSh)
374 : {
375 0 : pBookmarkDoc = pBookmarkDocSh->GetDoc();
376 :
377 0 : if (pBookmarkDocSh->GetMedium())
378 : {
379 0 : aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
380 : }
381 : }
382 0 : else if ( mxBookmarkDocShRef.Is() )
383 : {
384 0 : pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
385 0 : aBookmarkName = maBookmarkFile;
386 : }
387 : else
388 : {
389 0 : return sal_False;
390 : }
391 :
392 0 : const sal_uInt16 nSdPageCount = GetSdPageCount(PK_STANDARD);
393 0 : const sal_uInt16 nBMSdPageCount = pBookmarkDoc->GetSdPageCount(PK_STANDARD);
394 0 : const sal_uInt16 nMPageCount = GetMasterPageCount();
395 :
396 0 : if (nSdPageCount==0 || nBMSdPageCount==0 || nMPageCount==0)
397 : {
398 0 : bContinue = bOK = sal_False;
399 0 : return(bContinue);
400 : }
401 :
402 : // Store the size and some other properties of the first page and notes
403 : // page so that inserted pages can be properly scaled even when inserted
404 : // before the first page.
405 : // Note that the pointers are used later on as general page pointers.
406 0 : SdPage* pRefPage = GetSdPage(0, PK_STANDARD);
407 0 : Size aSize(pRefPage->GetSize());
408 0 : sal_Int32 nLeft = pRefPage->GetLftBorder();
409 0 : sal_Int32 nRight = pRefPage->GetRgtBorder();
410 0 : sal_Int32 nUpper = pRefPage->GetUppBorder();
411 0 : sal_Int32 nLower = pRefPage->GetLwrBorder();
412 0 : Orientation eOrient = pRefPage->GetOrientation();
413 :
414 0 : SdPage* pNPage = GetSdPage(0, PK_NOTES);
415 0 : Size aNSize(pNPage->GetSize());
416 0 : sal_Int32 nNLeft = pNPage->GetLftBorder();
417 0 : sal_Int32 nNRight = pNPage->GetRgtBorder();
418 0 : sal_Int32 nNUpper = pNPage->GetUppBorder();
419 0 : sal_Int32 nNLower = pNPage->GetLwrBorder();
420 0 : Orientation eNOrient = pRefPage->GetOrientation();
421 :
422 : // Adapt page size and margins to those of the later pages?
423 0 : pRefPage = GetSdPage(nSdPageCount - 1, PK_STANDARD);
424 :
425 0 : if( bNoDialogs )
426 : {
427 0 : if( rBookmarkList.empty() )
428 0 : bScaleObjects = pRefPage->IsScaleObjects();
429 : else
430 0 : bScaleObjects = sal_True;
431 : }
432 : else
433 : {
434 0 : SdPage* pBMPage = pBookmarkDoc->GetSdPage(0,PK_STANDARD);
435 :
436 0 : if (pBMPage->GetSize() != pRefPage->GetSize() ||
437 0 : pBMPage->GetLftBorder() != pRefPage->GetLftBorder() ||
438 0 : pBMPage->GetRgtBorder() != pRefPage->GetRgtBorder() ||
439 0 : pBMPage->GetUppBorder() != pRefPage->GetUppBorder() ||
440 0 : pBMPage->GetLwrBorder() != pRefPage->GetLwrBorder())
441 : {
442 0 : String aStr(SdResId(STR_SCALE_OBJECTS));
443 0 : sal_uInt16 nBut = QueryBox( NULL, WB_YES_NO_CANCEL, aStr).Execute();
444 :
445 0 : bScaleObjects = nBut == RET_YES;
446 0 : bContinue = nBut != RET_CANCEL;
447 :
448 0 : if (!bContinue)
449 : {
450 0 : return(bContinue);
451 0 : }
452 : }
453 : }
454 :
455 :
456 : // Get the necessary presentation stylesheets and transfer them before
457 : // the pages, else, the text objects won't reference their styles anymore.
458 0 : ::svl::IUndoManager* pUndoMgr = NULL;
459 0 : if( mpDocSh )
460 : {
461 0 : pUndoMgr = mpDocSh->GetUndoManager();
462 0 : pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_INSERTPAGES)), String());
463 : }
464 :
465 : //
466 : // Refactored copy'n'pasted layout name collection into IterateBookmarkPages
467 : //
468 0 : std::vector<OUString> aLayoutsToTransfer;
469 0 : InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor( aLayoutsToTransfer );
470 0 : lcl_IterateBookmarkPages( *this, pBookmarkDoc, rBookmarkList, nBMSdPageCount, aSearchFunctor );
471 :
472 :
473 : // Copy the style that we actually need.
474 0 : SdStyleSheetPool* pBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool*>(pBookmarkDoc->GetStyleSheetPool());
475 0 : SdStyleSheetPool* pStyleSheetPool = dynamic_cast<SdStyleSheetPool*>(GetStyleSheetPool());
476 :
477 : // When copying styles, also copy the master pages!
478 0 : if( !aLayoutsToTransfer.empty() )
479 0 : bMergeMasterPages = sal_True;
480 :
481 0 : std::vector<OUString>::const_iterator pIter;
482 0 : for ( pIter = aLayoutsToTransfer.begin(); pIter != aLayoutsToTransfer.end(); ++pIter )
483 : {
484 0 : SdStyleSheetVector aCreatedStyles;
485 0 : String layoutName = *pIter;
486 :
487 0 : pStyleSheetPool->CopyLayoutSheets(layoutName, *pBookmarkStyleSheetPool,aCreatedStyles);
488 :
489 0 : if(!aCreatedStyles.empty())
490 : {
491 0 : if( pUndoMgr )
492 : {
493 0 : SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, sal_True);
494 0 : pUndoMgr->AddUndoAction(pMovStyles);
495 : }
496 : }
497 0 : }
498 :
499 : // Copy styles. This unconditionally copies all styles, even those
500 : // that are not used in any of the inserted pages. The unused styles
501 : // are then removed at the end of the function, where we also create
502 : // undo records for the inserted styles.
503 0 : SdStyleSheetVector aNewGraphicStyles;
504 0 : pStyleSheetPool->CopyGraphicSheets(*pBookmarkStyleSheetPool, aNewGraphicStyles);
505 0 : SdStyleSheetVector aNewCellStyles;
506 0 : pStyleSheetPool->CopyCellSheets(*pBookmarkStyleSheetPool, aNewCellStyles);
507 :
508 : // TODO handle undo of table styles too
509 0 : pStyleSheetPool->CopyTableStyles(*pBookmarkStyleSheetPool);
510 :
511 : // Insert document
512 :
513 0 : const bool bUndo = IsUndoEnabled();
514 :
515 0 : if( bUndo )
516 0 : BegUndo(String(SdResId(STR_UNDO_INSERTPAGES)));
517 :
518 0 : if (rBookmarkList.empty())
519 : {
520 0 : if (nInsertPos >= GetPageCount())
521 : {
522 : // Add pages to the end
523 0 : nInsertPos = GetPageCount();
524 : }
525 :
526 0 : sal_uInt16 nActualInsertPos = nInsertPos;
527 :
528 : sal_uInt16 nBMSdPage;
529 0 : std::set<sal_uInt16> aRenameSet;
530 0 : std::map<sal_uInt16,OUString> aNameMap;
531 :
532 0 : for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
533 : {
534 0 : SdPage* pBMPage = pBookmarkDoc->GetSdPage(nBMSdPage, PK_STANDARD);
535 0 : String sName( pBMPage->GetName() );
536 : sal_Bool bIsMasterPage;
537 :
538 0 : if (bLink)
539 : {
540 : // Remember the names of all pages
541 0 : aNameMap.insert(std::make_pair(nBMSdPage,sName));
542 : }
543 :
544 : // Have to check for duplicate names here, too
545 : // don't change name if source and dest model are the same!
546 0 : if( pBookmarkDoc != this &&
547 0 : GetPageByName(sName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
548 : {
549 : // delay renaming *after* pages are copied (might destroy source otherwise)
550 0 : aRenameSet.insert(nBMSdPage);
551 : }
552 0 : }
553 :
554 : Merge(*pBookmarkDoc,
555 : 1, // Not the handout page
556 : 0xFFFF, // But all others
557 : nActualInsertPos, // Insert at position ...
558 : bMergeMasterPages, // Move master pages?
559 : sal_False, // But only the master pages used
560 : sal_True, // Create an undo action
561 0 : bCopy); // Copy (or merge) pages?
562 :
563 0 : for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
564 : {
565 0 : SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
566 0 : SdPage* pNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
567 :
568 : // delay renaming *after* pages are copied (might destroy source otherwise)
569 0 : if( aRenameSet.find(nBMSdPage) != aRenameSet.end() )
570 : {
571 : // Page name already in use -> Use default name for default and
572 : // notes page
573 0 : pPage->SetName(String());
574 0 : pNotesPage->SetName(String());
575 : }
576 :
577 0 : if (bLink)
578 : {
579 0 : String aName(aNameMap[nBMSdPage]);
580 :
581 : // Assemble all link names
582 0 : pPage->SetFileName(aBookmarkName);
583 0 : pPage->SetBookmarkName(aName);
584 0 : pPage->SetModel(this);
585 : }
586 :
587 0 : nActualInsertPos += 2;
588 0 : }
589 : }
590 : else
591 : {
592 : // Insert selected pages
593 : SdPage* pBMPage;
594 :
595 0 : if (nInsertPos >= GetPageCount())
596 : {
597 : // Add pages to the end
598 0 : bReplace = sal_False;
599 0 : nInsertPos = GetPageCount();
600 : }
601 :
602 0 : sal_uInt16 nActualInsertPos = nInsertPos;
603 :
604 : // Collect the bookmarked pages
605 0 : ::std::vector<SdPage*> aBookmarkedPages (rBookmarkList.size(), NULL);
606 0 : for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos)
607 : {
608 0 : String aPgName(rBookmarkList[nPos]);
609 : sal_Bool bIsMasterPage;
610 0 : sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage );
611 :
612 0 : if (nBMPage != SDRPAGE_NOTFOUND)
613 : {
614 0 : aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(pBookmarkDoc->GetPage(nBMPage));
615 : }
616 0 : }
617 :
618 0 : for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos)
619 : {
620 0 : pBMPage = aBookmarkedPages[nPos];
621 0 : sal_uInt16 nBMPage = pBMPage!=NULL ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND;
622 :
623 0 : if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage())
624 : {
625 : // It has to be a default page
626 0 : sal_Bool bMustRename = sal_False;
627 :
628 : // delay renaming *after* pages are copied (might destroy source otherwise)
629 : // don't change name if source and dest model are the same!
630 : // avoid renaming if replacing the same page
631 0 : String aPgName(rBookmarkList[nPos]);
632 : sal_Bool bIsMasterPage;
633 0 : sal_uInt16 nPageSameName = GetPageByName(aPgName, bIsMasterPage);
634 0 : if( pBookmarkDoc != this &&
635 0 : nPageSameName != SDRPAGE_NOTFOUND &&
636 0 : ( !bReplace ||
637 : nPageSameName != nActualInsertPos ) )
638 : {
639 0 : bMustRename = sal_True;
640 : }
641 :
642 0 : SdPage* pBookmarkPage = pBMPage;
643 0 : if (bReplace )
644 : {
645 0 : ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage );
646 : }
647 :
648 : Merge(*pBookmarkDoc,
649 : nBMPage, // From page (default page)
650 : nBMPage+1, // To page (notes page)
651 : nActualInsertPos, // Insert at position
652 : bMergeMasterPages, // Move master pages?
653 : sal_False, // But only the master pages used
654 : sal_True, // Create undo action
655 0 : bCopy); // Copy (or merge) pages?
656 :
657 0 : if( bReplace )
658 : {
659 0 : if( GetPage( nActualInsertPos ) != pBookmarkPage )
660 : {
661 : // bookmark page was not moved but cloned, so update custom shows again
662 0 : ReplacePageInCustomShows( pBookmarkPage, dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ) );
663 : }
664 : }
665 :
666 0 : if( bMustRename )
667 : {
668 : // Page name already in use -> use default name for default and
669 : // notes page
670 0 : SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
671 0 : pPage->SetName(String());
672 0 : SdPage* pNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
673 0 : pNotesPage->SetName(String());
674 : }
675 :
676 0 : if (bLink)
677 : {
678 0 : SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
679 0 : pPage->SetFileName(aBookmarkName);
680 0 : pPage->SetBookmarkName(aPgName);
681 0 : pPage->SetModel(this);
682 : }
683 :
684 0 : if (bReplace)
685 : {
686 : // Remove page and notes page.
687 0 : const sal_uInt16 nDestPageNum(nActualInsertPos + 2);
688 0 : SdPage* pStandardPage = 0L;
689 :
690 0 : if(nDestPageNum < GetPageCount())
691 : {
692 0 : pStandardPage = (SdPage*)GetPage(nDestPageNum);
693 : }
694 :
695 0 : if (pStandardPage)
696 : {
697 0 : if( bPreservePageNames )
698 : {
699 : // Take old slide names for inserted pages
700 0 : SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
701 0 : pPage->SetName( pStandardPage->GetRealName() );
702 : }
703 :
704 0 : if( bUndo )
705 0 : AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage));
706 :
707 0 : RemovePage(nDestPageNum);
708 :
709 0 : if( !bUndo )
710 0 : delete pStandardPage;
711 : }
712 :
713 0 : SdPage* pNotesPage = 0L;
714 :
715 0 : if(nDestPageNum < GetPageCount())
716 : {
717 0 : pNotesPage = (SdPage*)GetPage(nDestPageNum);
718 : }
719 :
720 0 : if (pNotesPage)
721 : {
722 0 : if( bPreservePageNames )
723 : {
724 : // Take old slide names for inserted pages
725 0 : SdPage* pNewNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
726 0 : if( pNewNotesPage )
727 0 : pNewNotesPage->SetName( pStandardPage->GetRealName() );
728 : }
729 :
730 0 : if( bUndo )
731 0 : AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
732 :
733 0 : RemovePage(nDestPageNum);
734 :
735 0 : if( !bUndo )
736 0 : delete pNotesPage;
737 : }
738 :
739 0 : nReplacedStandardPages++;
740 : }
741 :
742 0 : nActualInsertPos += 2;
743 : }
744 0 : }
745 : }
746 :
747 :
748 : // We might have duplicate master pages now, as the drawing engine does not
749 : // recognize duplicates. Remove these now.
750 0 : sal_uInt16 nNewMPageCount = GetMasterPageCount();
751 :
752 : // Go backwards, so the numbers don't become messed up
753 0 : for (sal_uInt16 nPage = nNewMPageCount - 1; nPage >= nMPageCount; nPage--)
754 : {
755 0 : pRefPage = (SdPage*) GetMasterPage(nPage);
756 0 : String aMPLayout(pRefPage->GetLayoutName());
757 0 : PageKind eKind = pRefPage->GetPageKind();
758 :
759 : // Does this already exist?
760 0 : for (sal_uInt16 nTest = 0; nTest < nMPageCount; nTest++)
761 : {
762 0 : SdPage* pTest = (SdPage*) GetMasterPage(nTest);
763 0 : String aTest(pTest->GetLayoutName());
764 :
765 : // nInsertPos > 2 is always true when inserting into non-empty models
766 0 : if ( nInsertPos > 2 &&
767 0 : aTest == aMPLayout &&
768 0 : eKind == pTest->GetPageKind() )
769 : {
770 0 : if( bUndo )
771 0 : AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage));
772 :
773 0 : RemoveMasterPage(nPage);
774 :
775 0 : if( !bUndo )
776 0 : delete pRefPage;
777 0 : nNewMPageCount--;
778 0 : break;
779 : }
780 0 : }
781 0 : }
782 :
783 : // nInsertPos > 2 is always true when inserting into non-empty models
784 0 : if (nInsertPos > 0)
785 : {
786 0 : sal_uInt16 nSdPageStart = (nInsertPos - 1) / 2;
787 0 : sal_uInt16 nSdPageEnd = GetSdPageCount(PK_STANDARD) - nSdPageCount +
788 0 : nSdPageStart - 1;
789 0 : const bool bRemoveEmptyPresObj = pBookmarkDoc &&
790 0 : (pBookmarkDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
791 0 : (GetDocumentType() == DOCUMENT_TYPE_DRAW);
792 :
793 0 : if( bReplace )
794 : {
795 0 : nSdPageEnd = nSdPageStart + nReplacedStandardPages - 1;
796 : }
797 :
798 0 : std::vector<OUString>::iterator pExchangeIter;
799 :
800 0 : if (pExchangeList)
801 0 : pExchangeIter = pExchangeList->begin();
802 :
803 0 : for (sal_uInt16 nSdPage = nSdPageStart; nSdPage <= nSdPageEnd; nSdPage++)
804 : {
805 0 : pRefPage = GetSdPage(nSdPage, PK_STANDARD);
806 :
807 0 : if (pExchangeList && pExchangeIter != pExchangeList->end())
808 : {
809 : // Get the name to use from Exchange list
810 0 : String aExchangeName (*pExchangeIter);
811 0 : pRefPage->SetName(aExchangeName);
812 0 : SdrHint aHint(HINT_PAGEORDERCHG);
813 0 : aHint.SetPage(pRefPage);
814 0 : Broadcast(aHint);
815 0 : SdPage* pNewNotesPage = GetSdPage(nSdPage, PK_NOTES);
816 0 : pNewNotesPage->SetName(aExchangeName);
817 0 : aHint.SetPage(pNewNotesPage);
818 0 : Broadcast(aHint);
819 :
820 0 : ++pExchangeIter;
821 : }
822 :
823 0 : String aLayout(pRefPage->GetLayoutName());
824 0 : aLayout.Erase(aLayout.SearchAscii( SD_LT_SEPARATOR ));
825 :
826 : // update layout and referred master page
827 0 : pRefPage->SetPresentationLayout(aLayout);
828 0 : if( bUndo )
829 0 : AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
830 :
831 0 : if (bScaleObjects)
832 : {
833 0 : Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
834 0 : pRefPage->ScaleObjects(aSize, aBorderRect, sal_True);
835 : }
836 0 : pRefPage->SetSize(aSize);
837 0 : pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
838 0 : pRefPage->SetOrientation( eOrient );
839 :
840 0 : if( bRemoveEmptyPresObj )
841 0 : pRefPage->RemoveEmptyPresentationObjects();
842 :
843 0 : pRefPage = GetSdPage(nSdPage, PK_NOTES);
844 :
845 : // update layout and referred master page
846 0 : pRefPage->SetPresentationLayout(aLayout);
847 0 : if( bUndo )
848 0 : AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
849 :
850 0 : if (bScaleObjects)
851 : {
852 0 : Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
853 0 : pRefPage->ScaleObjects(aNSize, aBorderRect, sal_True);
854 : }
855 :
856 0 : pRefPage->SetSize(aNSize);
857 0 : pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
858 0 : pRefPage->SetOrientation( eNOrient );
859 :
860 0 : if( bRemoveEmptyPresObj )
861 0 : pRefPage->RemoveEmptyPresentationObjects();
862 0 : }
863 :
864 : ///Remove processed elements, to avoid doings hacks in InsertBookmarkAsObject
865 0 : if ( pExchangeList )
866 0 : pExchangeList->erase(pExchangeList->begin(),pExchangeIter);
867 :
868 0 : for (sal_uInt16 nPage = nMPageCount; nPage < nNewMPageCount; nPage++)
869 : {
870 0 : pRefPage = (SdPage*) GetMasterPage(nPage);
871 0 : if (pRefPage->GetPageKind() == PK_STANDARD)
872 : {
873 0 : if (bScaleObjects)
874 : {
875 0 : Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
876 0 : pRefPage->ScaleObjects(aSize, aBorderRect, sal_True);
877 : }
878 0 : pRefPage->SetSize(aSize);
879 0 : pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
880 0 : pRefPage->SetOrientation( eOrient );
881 : }
882 : else // Can only be notes
883 : {
884 0 : if (bScaleObjects)
885 : {
886 0 : Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
887 0 : pRefPage->ScaleObjects(aNSize, aBorderRect, sal_True);
888 : }
889 0 : pRefPage->SetSize(aNSize);
890 0 : pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
891 0 : pRefPage->SetOrientation( eNOrient );
892 : }
893 :
894 0 : if( bRemoveEmptyPresObj )
895 0 : pRefPage->RemoveEmptyPresentationObjects();
896 : }
897 : }
898 :
899 : // Make absolutely sure no double masterpages are there
900 0 : RemoveUnnecessaryMasterPages(NULL, sal_True, sal_True);
901 :
902 : // remove copied styles not used on any inserted page and create
903 : // undo records
904 : // WARNING: SdMoveStyleSheetsUndoAction clears the passed list of
905 : // styles, so it cannot be used after this point
906 0 : lcl_removeUnusedStyles(GetStyleSheetPool(), aNewGraphicStyles);
907 0 : if (!aNewGraphicStyles.empty() && pUndoMgr)
908 0 : pUndoMgr->AddUndoAction(new SdMoveStyleSheetsUndoAction(this, aNewGraphicStyles, sal_True));
909 0 : lcl_removeUnusedStyles(GetStyleSheetPool(), aNewCellStyles);
910 0 : if (!aNewCellStyles.empty() && pUndoMgr)
911 0 : pUndoMgr->AddUndoAction(new SdMoveStyleSheetsUndoAction(this, aNewCellStyles, sal_True));
912 :
913 0 : if( bUndo )
914 0 : EndUndo();
915 0 : pUndoMgr->LeaveListAction();
916 :
917 0 : return bContinue;
918 : }
919 :
920 : // Inserts a bookmark as an object
921 0 : sal_Bool SdDrawDocument::InsertBookmarkAsObject(
922 : const std::vector<OUString> &rBookmarkList,
923 : const std::vector<OUString> &rExchangeList, // List of names to use
924 : sal_Bool /* bLink */,
925 : ::sd::DrawDocShell* pBookmarkDocSh,
926 : Point* pObjPos, bool bCalcObjCount)
927 : {
928 0 : sal_Bool bOK = sal_True;
929 0 : sal_Bool bOLEObjFound = sal_False;
930 0 : ::sd::View* pBMView = NULL;
931 :
932 0 : SdDrawDocument* pBookmarkDoc = NULL;
933 0 : String aBookmarkName;
934 :
935 0 : if (pBookmarkDocSh)
936 : {
937 0 : pBookmarkDoc = pBookmarkDocSh->GetDoc();
938 :
939 0 : if (pBookmarkDocSh->GetMedium())
940 : {
941 0 : aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
942 : }
943 : }
944 0 : else if ( mxBookmarkDocShRef.Is() )
945 : {
946 0 : pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
947 0 : aBookmarkName = maBookmarkFile;
948 : }
949 : else
950 : {
951 0 : return sal_False;
952 : }
953 :
954 0 : if (rBookmarkList.empty())
955 : {
956 0 : pBMView = new ::sd::View(*pBookmarkDoc, (OutputDevice*) NULL);
957 0 : pBMView->EndListening(*pBookmarkDoc);
958 0 : pBMView->MarkAll();
959 : }
960 : else
961 : {
962 : SdrPage* pPage;
963 : SdrPageView* pPV;
964 :
965 0 : std::vector<OUString>::const_iterator pIter;
966 0 : for ( pIter = rBookmarkList.begin(); pIter != rBookmarkList.end(); ++pIter )
967 : {
968 : // Get names of bookmarks from the list
969 0 : String aBMName (*pIter);
970 :
971 0 : SdrObject* pObj = pBookmarkDoc->GetObj(aBMName);
972 :
973 0 : if (pObj)
974 : {
975 : // Found an object
976 0 : if (pObj->GetObjInventor() == SdrInventor &&
977 0 : pObj->GetObjIdentifier() == OBJ_OLE2)
978 : {
979 0 : bOLEObjFound = sal_True;
980 : }
981 :
982 0 : if (!pBMView)
983 : {
984 : // Create View for the first time
985 0 : pBMView = new ::sd::View(*pBookmarkDoc, (OutputDevice*) NULL);
986 0 : pBMView->EndListening(*pBookmarkDoc);
987 : }
988 :
989 0 : pPage = pObj->GetPage();
990 :
991 0 : if (pPage->IsMasterPage())
992 : {
993 0 : pPV = pBMView->ShowSdrPage(pBMView->GetModel()->GetMasterPage(pPage->GetPageNum()));
994 : }
995 : else
996 : {
997 0 : pPV = pBMView->GetSdrPageView();
998 0 : if( !pPV || (pPV->GetPage() != pPage))
999 0 : pPV = pBMView->ShowSdrPage(pPage);
1000 : }
1001 :
1002 0 : pBMView->MarkObj(pObj, pPV, sal_False);
1003 : }
1004 0 : }
1005 : }
1006 :
1007 0 : if (pBMView)
1008 : {
1009 : // Insert selected objects
1010 0 : ::sd::View* pView = new ::sd::View(*this, (OutputDevice*) NULL);
1011 0 : pView->EndListening(*this);
1012 :
1013 : // Look for the page into which the objects are supposed to be inserted
1014 0 : SdrPage* pPage = GetSdPage(0, PK_STANDARD);
1015 :
1016 0 : if (mpDocSh)
1017 : {
1018 0 : ::sd::ViewShell* pViewSh = mpDocSh->GetViewShell();
1019 :
1020 0 : if (pViewSh)
1021 : {
1022 : // Which page is currently in view?
1023 0 : SdrPageView* pPV = pViewSh->GetView()->GetSdrPageView();
1024 :
1025 0 : if (pPV)
1026 : {
1027 0 : pPage = pPV->GetPage();
1028 : }
1029 0 : else if (pViewSh->GetActualPage())
1030 : {
1031 0 : pPage = pViewSh->GetActualPage();
1032 : }
1033 : }
1034 : }
1035 :
1036 0 : Point aObjPos;
1037 :
1038 0 : if (pObjPos)
1039 : {
1040 0 : aObjPos = *pObjPos;
1041 : }
1042 : else
1043 : {
1044 0 : aObjPos = Rectangle(Point(), pPage->GetSize()).Center();
1045 : }
1046 :
1047 0 : sal_uLong nCountBefore = 0;
1048 :
1049 0 : if (!rExchangeList.empty() || bCalcObjCount)
1050 : {
1051 : // Sort OrdNums and get the number of objects before inserting
1052 0 : pPage->RecalcObjOrdNums();
1053 0 : nCountBefore = pPage->GetObjCount();
1054 : }
1055 :
1056 0 : if (bOLEObjFound)
1057 0 : pBMView->GetDoc().SetAllocDocSh(sal_True);
1058 :
1059 0 : SdDrawDocument* pTmpDoc = (SdDrawDocument*) pBMView->GetMarkedObjModel();
1060 0 : bOK = pView->Paste(*pTmpDoc, aObjPos, pPage);
1061 :
1062 0 : if (bOLEObjFound)
1063 0 : pBMView->GetDoc().SetAllocDocSh(sal_False);
1064 :
1065 0 : if (!bOLEObjFound)
1066 0 : delete pTmpDoc; // Would otherwise be destroyed by DocShell
1067 :
1068 0 : delete pView;
1069 :
1070 0 : if (!rExchangeList.empty())
1071 : {
1072 : // Get number of objects after inserting.
1073 0 : sal_uLong nCount = pPage->GetObjCount();
1074 :
1075 0 : std::vector<OUString>::const_iterator pIter = rExchangeList.begin();
1076 0 : for (sal_uLong nObj = nCountBefore; nObj < nCount; nObj++)
1077 : {
1078 : // Get the name to use from the Exchange list
1079 0 : if (pIter != rExchangeList.end())
1080 : {
1081 0 : String aExchangeName (*pIter);
1082 :
1083 0 : if (pPage->GetObj(nObj))
1084 : {
1085 0 : pPage->GetObj(nObj)->SetName(aExchangeName);
1086 : }
1087 :
1088 0 : ++pIter;
1089 : }
1090 : }
1091 : }
1092 : }
1093 :
1094 0 : delete pBMView;
1095 :
1096 0 : return bOK;
1097 : }
1098 :
1099 : // Stops the bookmark insertion
1100 88 : void SdDrawDocument::CloseBookmarkDoc()
1101 : {
1102 88 : if (mxBookmarkDocShRef.Is())
1103 : {
1104 0 : mxBookmarkDocShRef->DoClose();
1105 : }
1106 :
1107 88 : mxBookmarkDocShRef.Clear();
1108 88 : maBookmarkFile = String();
1109 88 : }
1110 :
1111 : // Is this document read-only?
1112 1 : bool SdDrawDocument::IsReadOnly() const
1113 : {
1114 1 : return sal_False;
1115 : }
1116 :
1117 :
1118 : // In the subsequent AllocModel() a DocShell (xAllocedDocShRef) is created.
1119 : // Any pre-existing DocShell is deleted
1120 88 : void SdDrawDocument::SetAllocDocSh(sal_Bool bAlloc)
1121 : {
1122 88 : mbAllocDocSh = bAlloc;
1123 :
1124 88 : if(mxAllocedDocShRef.Is())
1125 : {
1126 0 : mxAllocedDocShRef->DoClose();
1127 : }
1128 :
1129 88 : mxAllocedDocShRef.Clear();
1130 88 : }
1131 :
1132 : // Return list of CustomShows (create it, too, if necessary)
1133 6 : SdCustomShowList* SdDrawDocument::GetCustomShowList(sal_Bool bCreate)
1134 : {
1135 6 : if (!mpCustomShowList && bCreate)
1136 : {
1137 3 : mpCustomShowList = new SdCustomShowList;
1138 : }
1139 :
1140 6 : return mpCustomShowList;
1141 : }
1142 :
1143 : // Remove unused master pages and layouts
1144 0 : void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage* pMasterPage, sal_Bool bOnlyDuplicatePages, sal_Bool bUndo)
1145 : {
1146 0 : ::sd::View* pView = NULL;
1147 0 : ::svl::IUndoManager* pUndoMgr = NULL;
1148 :
1149 0 : if( bUndo && !IsUndoEnabled() )
1150 0 : bUndo = sal_False;
1151 :
1152 0 : if (mpDocSh)
1153 : {
1154 0 : pUndoMgr = mpDocSh->GetUndoManager();
1155 :
1156 0 : if (mpDocSh->GetViewShell())
1157 0 : pView = mpDocSh->GetViewShell()->GetView();
1158 : }
1159 :
1160 : // Check all master pages
1161 0 : sal_uInt16 nSdMasterPageCount = GetMasterSdPageCount( PK_STANDARD );
1162 0 : for (sal_Int32 nMPage = nSdMasterPageCount - 1; nMPage >= 0; nMPage--)
1163 : {
1164 0 : SdPage* pMaster = pMasterPage;
1165 0 : SdPage* pNotesMaster = NULL;
1166 :
1167 0 : if (!pMaster)
1168 : {
1169 0 : pMaster = (SdPage*) GetMasterSdPage( (sal_uInt16) nMPage, PK_STANDARD );
1170 0 : pNotesMaster = (SdPage*) GetMasterSdPage( (sal_uInt16) nMPage, PK_NOTES );
1171 : }
1172 : else
1173 : {
1174 0 : for ( sal_uInt16 nMPg = 0; nMPg < GetMasterPageCount(); nMPg++ )
1175 : {
1176 0 : if ( pMaster == GetMasterPage( nMPg ) )
1177 : {
1178 0 : pNotesMaster = (SdPage*) GetMasterPage( ++nMPg );
1179 0 : break;
1180 : }
1181 : }
1182 : }
1183 :
1184 : DBG_ASSERT( pMaster->GetPageKind() == PK_STANDARD, "wrong page kind" );
1185 :
1186 0 : if ( pMaster->GetPageKind() == PK_STANDARD &&
1187 0 : GetMasterPageUserCount( pMaster ) == 0 &&
1188 : pNotesMaster )
1189 : {
1190 : // Do not delete master pages that have their precious flag set
1191 0 : sal_Bool bDeleteMaster = !pMaster->IsPrecious();
1192 0 : OUString aLayoutName = pMaster->GetLayoutName();
1193 :
1194 0 : if(bOnlyDuplicatePages )
1195 : {
1196 : // remove only duplicate pages
1197 0 : bDeleteMaster = sal_False;
1198 0 : for (sal_uInt16 i = 0; i < GetMasterSdPageCount( PK_STANDARD ); i++)
1199 : {
1200 0 : SdPage* pMPg = (SdPage*) GetMasterSdPage( i, PK_STANDARD );
1201 0 : if( pMPg != pMaster &&
1202 0 : pMPg->GetLayoutName() == aLayoutName )
1203 : {
1204 : // duplicate page found -> remove it
1205 0 : bDeleteMaster = sal_True;
1206 : }
1207 : }
1208 : }
1209 :
1210 0 : if( bDeleteMaster )
1211 : {
1212 0 : if (pView)
1213 : {
1214 : // if MasterPage is visible hide on pageview
1215 0 : SdrPageView* pPgView = pView->GetSdrPageView();
1216 0 : if (pPgView)
1217 : {
1218 0 : SdrPage* pShownPage = pPgView->GetPage();
1219 0 : if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) )
1220 : {
1221 0 : pView->HideSdrPage();
1222 0 : pView->ShowSdrPage( GetSdPage( 0, PK_STANDARD ) );
1223 : }
1224 : }
1225 : }
1226 :
1227 0 : if( bUndo )
1228 : {
1229 0 : BegUndo();
1230 0 : AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster ) );
1231 : }
1232 :
1233 0 : RemoveMasterPage( pNotesMaster->GetPageNum() );
1234 :
1235 0 : if( !bUndo )
1236 0 : delete pNotesMaster;
1237 :
1238 0 : if( bUndo )
1239 0 : AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster));
1240 :
1241 0 : RemoveMasterPage( pMaster->GetPageNum() );
1242 :
1243 0 : if( !bUndo )
1244 0 : delete pMaster;
1245 :
1246 0 : if( bUndo )
1247 0 : EndUndo(); // do this here already, so Joe's actions happen _between_ our own
1248 :
1249 : // Delete old, unused layout stylesheets
1250 0 : sal_Bool bDeleteOldStyleSheets = sal_True;
1251 0 : for ( sal_uInt16 nMPg = 0;
1252 0 : nMPg < GetMasterPageCount() && bDeleteOldStyleSheets;
1253 : nMPg++ )
1254 : {
1255 0 : SdPage* pMPg = (SdPage*) GetMasterPage(nMPg);
1256 0 : if (pMPg->GetLayoutName() == aLayoutName)
1257 : {
1258 0 : bDeleteOldStyleSheets = sal_False;
1259 : }
1260 : }
1261 :
1262 0 : if (bDeleteOldStyleSheets)
1263 : {
1264 0 : SdStyleSheetVector aRemove;
1265 0 : static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList( aLayoutName, aRemove );
1266 :
1267 0 : if( bUndo )
1268 : {
1269 : // This list belongs to UndoAction
1270 0 : SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aRemove, false );
1271 :
1272 0 : if (pUndoMgr)
1273 0 : pUndoMgr->AddUndoAction(pMovStyles);
1274 : }
1275 :
1276 0 : for( SdStyleSheetVector::iterator iter = aRemove.begin(); iter != aRemove.end(); ++iter )
1277 0 : static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->Remove((*iter).get());
1278 : }
1279 0 : }
1280 : }
1281 :
1282 0 : if (pMasterPage)
1283 0 : break; // Just this one master page!
1284 : }
1285 0 : }
1286 :
1287 :
1288 : /** Exchange master page
1289 : *
1290 : * Either the nSdPageNum gets a new, own master page or the master page is
1291 : * exchanged completely (which then applies to all pages).
1292 : *
1293 : * nSdPageNum : page number that the new master page should get.
1294 : * rLayoutName : LayoutName of the new master page
1295 : * pSourceDoc : document (template) to get the master page from
1296 : * bMaster : exchange the master page of nSdPageNum
1297 : * bCheckMasters: remove unused master pages
1298 : *
1299 : * If pSourceDoc == NULL, an empty master page is applied.
1300 : * If rLayoutName is empty, the first master page is used.
1301 : */
1302 : // #i121863# factored out functionality
1303 0 : bool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, const String& rCandidate)
1304 : {
1305 0 : if(!rCandidate.Len())
1306 : {
1307 0 : return false;
1308 : }
1309 :
1310 0 : const sal_uInt16 nPageCount(rDoc.GetMasterPageCount());
1311 :
1312 0 : for(sal_uInt16 a(0); a < nPageCount; a++)
1313 : {
1314 0 : const SdrPage* pCandidate = rDoc.GetMasterPage(a);
1315 0 : String aPageLayoutName(pCandidate->GetLayoutName());
1316 0 : aPageLayoutName.Erase(aPageLayoutName.SearchAscii(SD_LT_SEPARATOR));
1317 :
1318 0 : if(aPageLayoutName == rCandidate)
1319 : {
1320 0 : return false;
1321 : }
1322 0 : }
1323 :
1324 0 : return true;
1325 : }
1326 :
1327 : // #i121863# factored out functinality
1328 0 : String createNewMasterPageLayoutName(const SdDrawDocument& rDoc)
1329 : {
1330 0 : const String aBaseName(SdResId(STR_LAYOUT_DEFAULT_NAME));
1331 0 : String aRetval;
1332 0 : sal_uInt16 nCount(0);
1333 :
1334 0 : while(!aRetval.Len())
1335 : {
1336 0 : aRetval = aBaseName;
1337 :
1338 0 : if(nCount)
1339 : {
1340 0 : aRetval += OUString::number(nCount);
1341 : }
1342 :
1343 0 : nCount++;
1344 :
1345 0 : if(!isMasterPageLayoutNameUnique(rDoc, aRetval))
1346 : {
1347 0 : aRetval.Erase();
1348 : }
1349 : }
1350 :
1351 0 : return aRetval;
1352 : }
1353 :
1354 0 : void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum,
1355 : const String& rLayoutName,
1356 : SdDrawDocument* pSourceDoc,
1357 : sal_Bool bMaster,
1358 : sal_Bool bCheckMasters)
1359 : {
1360 0 : if( mpDocSh )
1361 0 : mpDocSh->SetWaitCursor( sal_True );
1362 :
1363 0 : ::svl::IUndoManager* pUndoMgr = mpDocSh->GetUndoManager();
1364 :
1365 0 : const bool bUndo = IsUndoEnabled();
1366 :
1367 0 : if( bUndo )
1368 : {
1369 0 : pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());
1370 : }
1371 :
1372 0 : SdPage* pSelectedPage = GetSdPage(nSdPageNum, PK_STANDARD);
1373 0 : SdPage* pNotes = (SdPage*) GetPage(pSelectedPage->GetPageNum()+1);
1374 0 : SdPage& rOldMaster = (SdPage&)pSelectedPage->TRG_GetMasterPage();
1375 0 : SdPage& rOldNotesMaster = (SdPage&)pNotes->TRG_GetMasterPage();
1376 0 : SdPage* pMaster = NULL;
1377 0 : SdPage* pNotesMaster = NULL;
1378 0 : SdPage* pPage = NULL;
1379 0 : String aOldPageLayoutName(pSelectedPage->GetLayoutName());
1380 0 : String aOldLayoutName(aOldPageLayoutName);
1381 0 : aOldLayoutName.Erase(aOldLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1382 :
1383 0 : if (pSourceDoc)
1384 : {
1385 0 : std::vector<StyleReplaceData> aReplList; // List of replaced stylesheets
1386 0 : sal_Bool bLayoutReloaded = sal_False; // Wurde ex. Layout wieder geladen?
1387 :
1388 : // LayoutName, Page and Notes page
1389 0 : if (rLayoutName.Len() == 0)
1390 : {
1391 : // No LayoutName: take first MasterPage
1392 0 : pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1393 0 : pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1394 : }
1395 : else
1396 : {
1397 0 : OUStringBuffer aBuf(rLayoutName);
1398 0 : aBuf.append(SD_LT_SEPARATOR).append(SdResId(STR_LAYOUT_OUTLINE).toString());
1399 0 : OUString aSearchFor(aBuf.makeStringAndClear());
1400 :
1401 0 : for (sal_uInt16 nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); ++nMP)
1402 : {
1403 0 : SdPage* pMP = (SdPage*) pSourceDoc->GetMasterPage(nMP);
1404 :
1405 0 : if (pMP->GetLayoutName() == aSearchFor)
1406 : {
1407 0 : if (pMP->GetPageKind() == PK_STANDARD)
1408 0 : pMaster = pMP;
1409 0 : if (pMP->GetPageKind() == PK_NOTES)
1410 0 : pNotesMaster = pMP;
1411 : }
1412 0 : if (pMaster && pNotesMaster)
1413 0 : break;
1414 : }
1415 : DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
1416 : DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
1417 :
1418 : // this should not happen, but looking at crashreports, it does
1419 0 : if( (pMaster == NULL) || (pNotesMaster == NULL) )
1420 : {
1421 : // so take the first MasterPage
1422 0 : pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1423 0 : pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1424 0 : }
1425 : }
1426 :
1427 : // we should never reach this, but one never knows...
1428 0 : if( (pMaster == NULL) || (pNotesMaster == NULL) )
1429 : {
1430 0 : pUndoMgr->LeaveListAction();
1431 :
1432 0 : if( mpDocSh )
1433 0 : mpDocSh->SetWaitCursor( sal_False );
1434 :
1435 : OSL_FAIL( "SdDrawDocument::SetMasterPage() failed!" );
1436 :
1437 0 : return;
1438 : }
1439 :
1440 0 : const String aOriginalNewLayoutName( pMaster->GetName() );
1441 0 : String aTargetNewLayoutName(aOriginalNewLayoutName);
1442 :
1443 0 : if (pSourceDoc != this)
1444 : {
1445 : // #i121863# clone masterpages, they are from another model (!)
1446 0 : SdPage* pNewNotesMaster = dynamic_cast< SdPage* >(pNotesMaster->Clone(this));
1447 0 : SdPage* pNewMaster = dynamic_cast< SdPage* >(pMaster->Clone(this));
1448 :
1449 0 : if(!pNewNotesMaster || !pNewMaster)
1450 : {
1451 0 : delete pNewNotesMaster;
1452 0 : delete pNewMaster;
1453 : OSL_ASSERT("SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" );
1454 0 : return;
1455 : }
1456 :
1457 0 : pNotesMaster = pNewNotesMaster;
1458 0 : pMaster = pNewMaster;
1459 :
1460 : // layout name needs to be unique
1461 0 : aTargetNewLayoutName = pMaster->GetLayoutName();
1462 0 : aTargetNewLayoutName.Erase(aTargetNewLayoutName.SearchAscii(SD_LT_SEPARATOR));
1463 :
1464 0 : if(!isMasterPageLayoutNameUnique(*this, aTargetNewLayoutName))
1465 : {
1466 0 : aTargetNewLayoutName = createNewMasterPageLayoutName(*this);
1467 :
1468 0 : String aTemp(aTargetNewLayoutName);
1469 0 : aTemp.AppendAscii(RTL_CONSTASCII_STRINGPARAM(SD_LT_SEPARATOR));
1470 0 : aTemp.Append(String(SdResId(STR_LAYOUT_OUTLINE)));
1471 :
1472 0 : pMaster->SetName(aTargetNewLayoutName);
1473 0 : pMaster->SetLayoutName(aTemp);
1474 :
1475 0 : pNotesMaster->SetName(aTargetNewLayoutName);
1476 0 : pNotesMaster->SetLayoutName(aTemp);
1477 : }
1478 : }
1479 :
1480 0 : if (pSourceDoc != this)
1481 : {
1482 0 : const sal_uInt16 nMasterPageCount = GetMasterPageCount();
1483 0 : for ( sal_uInt16 nMPage = 0; nMPage < nMasterPageCount; nMPage++ )
1484 : {
1485 0 : SdPage* pCheckMaster = (SdPage*)GetMasterPage(nMPage);
1486 0 : if( pCheckMaster->GetName() == aTargetNewLayoutName )
1487 : {
1488 0 : bLayoutReloaded = sal_True;
1489 0 : break;
1490 : }
1491 : }
1492 :
1493 : // Correct or create presentation templates --
1494 : // only worry about presentation templates
1495 0 : String aName;
1496 0 : SdStyleSheetPool* pSourceStyleSheetPool = (SdStyleSheetPool*) pSourceDoc->GetStyleSheetPool();
1497 0 : pSourceStyleSheetPool->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1498 0 : static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1499 :
1500 0 : SdStyleSheetVector aCreatedStyles; // List of created stylesheets
1501 0 : SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First();
1502 :
1503 0 : while (pHisSheet)
1504 : {
1505 0 : aName = pHisSheet->GetName();
1506 :
1507 : // #i121863# search in source styles with original style name from source of
1508 : // evtl. cloned master (not-cloned, renamed for uniqueness)
1509 0 : if( aName.Search( aOriginalNewLayoutName ) == 0 )
1510 : {
1511 : // #i121863# build name of evtl. cloned master style to search for
1512 0 : if(aOriginalNewLayoutName != aTargetNewLayoutName)
1513 : {
1514 0 : const sal_uInt16 nPos(aName.SearchAscii(SD_LT_SEPARATOR));
1515 0 : aName.Erase(0, nPos);
1516 0 : aName.Insert(aTargetNewLayoutName, 0);
1517 : }
1518 :
1519 0 : SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SD_STYLE_FAMILY_MASTERPAGE) );
1520 :
1521 0 : if (pMySheet)
1522 : {
1523 : // A stylesheet of the same name already exists -> overwrite contents
1524 : #ifdef DBG_UTIL
1525 : sal_Bool bTest =
1526 : #endif
1527 0 : pMySheet->SetName(pHisSheet->GetName());
1528 : DBG_ASSERT(bTest, "Renaming StyleSheet failed.");
1529 0 : pMySheet->GetItemSet().ClearItem(0); // Delete all
1530 :
1531 : StyleSheetUndoAction* pUndoChStyle = new StyleSheetUndoAction(this,
1532 0 : pMySheet, &pHisSheet->GetItemSet());
1533 0 : pUndoMgr->AddUndoAction(pUndoChStyle);
1534 0 : pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1535 0 : pMySheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
1536 : }
1537 : else
1538 : {
1539 : // create new style
1540 0 : OUString aHelpFile;
1541 0 : pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SD_STYLE_FAMILY_MASTERPAGE, pHisSheet->GetMask()) );
1542 0 : pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) );
1543 0 : pMySheet->GetItemSet().ClearItem(0); // Delete all
1544 0 : pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1545 :
1546 0 : aCreatedStyles.push_back( SdStyleSheetRef( static_cast< SdStyleSheet* >( pMySheet ) ) );
1547 : }
1548 :
1549 0 : StyleReplaceData aReplData;
1550 0 : aReplData.nNewFamily = pMySheet->GetFamily();
1551 0 : aReplData.nFamily = pMySheet->GetFamily();
1552 0 : aReplData.aNewName = pMySheet->GetName();
1553 :
1554 : // #i121863# re-create original name of styte used at page where to replace with
1555 : // this new style
1556 0 : String aTemp(pMySheet->GetName());
1557 0 : const sal_uInt16 nPos(aTemp.SearchAscii(SD_LT_SEPARATOR));
1558 0 : aTemp.Erase(0, nPos);
1559 0 : aTemp.Insert(aOldLayoutName, 0);
1560 0 : aReplData.aName = aTemp;
1561 0 : aReplList.push_back(aReplData);
1562 : }
1563 :
1564 0 : pHisSheet = (SfxStyleSheet*) pSourceStyleSheetPool->Next();
1565 : }
1566 :
1567 : // If new styles were created: re-create parent chaining of the item
1568 : // sets in the styles.
1569 0 : if(!aCreatedStyles.empty())
1570 : {
1571 0 : std::vector<StyleReplaceData>::iterator pRDataIter;
1572 0 : for ( pRDataIter = aReplList.begin(); pRDataIter != aReplList.end(); ++pRDataIter )
1573 : {
1574 0 : SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(pRDataIter->aName);
1575 0 : SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(pRDataIter->aNewName);
1576 :
1577 0 : if (pSOld && pSNew)
1578 : {
1579 0 : const String& rParentOfOld = pSOld->GetParent();
1580 0 : const String& rParentOfNew = pSNew->GetParent();
1581 :
1582 0 : if (rParentOfOld.Len() > 0 && rParentOfNew.Len() == 0)
1583 : {
1584 0 : std::vector<StyleReplaceData>::iterator pRDIter;
1585 0 : for ( pRDIter = aReplList.begin(); pRDIter != aReplList.end(); ++pRDIter )
1586 : {
1587 0 : if ((pRDIter->aName == rParentOfOld) && (pRDIter->aName != pRDIter->aNewName))
1588 : {
1589 0 : String aParentOfNew(pRDIter->aNewName);
1590 0 : pSNew->SetParent(aParentOfNew);
1591 0 : break;
1592 : }
1593 : }
1594 0 : }
1595 : }
1596 : }
1597 :
1598 : // Now look for all of them when searching
1599 0 : pSourceStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1600 0 : mxStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1601 : }
1602 :
1603 0 : if( !aCreatedStyles.empty() )
1604 : {
1605 : // Add UndoAction for creating and inserting the stylesheets to
1606 : // the top of the UndoManager
1607 0 : SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aCreatedStyles, sal_True);
1608 0 : pUndoMgr->AddUndoAction(pMovStyles);
1609 0 : }
1610 : }
1611 :
1612 : // Create layout name based upon the name of the page layout of the
1613 : // master page
1614 0 : String aPageLayoutName(pMaster->GetLayoutName());
1615 0 : String aLayoutName = aPageLayoutName;
1616 0 : aLayoutName.Erase( aLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1617 :
1618 : // #i121863# Do *not* remove from original document any longer, it is potentially used there
1619 : // and would lead to crashes. Rely on the automatic process of removing unused masterpages
1620 : // (see RemoveUnnecessaryMasterPages)
1621 : //if (pSourceDoc != this)
1622 : //{
1623 : // // Remove from the source document
1624 : // pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1625 : // pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1626 : //}
1627 :
1628 : // Register the new master pages with the document and then use the
1629 : // the new presentation layout for the default and notes pages
1630 0 : if (pSourceDoc != this)
1631 : {
1632 : // Insert the master pages:
1633 : // Insert master pages from new layouts at the end.
1634 : // If a layout is being replaced, however, insert them before the
1635 : // position of the old master page, so from now on the new master
1636 : // page will be found when searching (e.g.
1637 : // SdPage::SetPresentationLayout).
1638 0 : sal_uInt16 nInsertPos = rOldMaster.GetPageNum();
1639 0 : BegUndo();
1640 :
1641 0 : if (!bLayoutReloaded)
1642 0 : nInsertPos = 0xFFFF;
1643 0 : InsertMasterPage(pMaster, nInsertPos);
1644 0 : if( bUndo )
1645 0 : AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1646 :
1647 0 : nInsertPos++;
1648 0 : if (!bLayoutReloaded)
1649 0 : nInsertPos = 0xFFFF;
1650 0 : InsertMasterPage(pNotesMaster, nInsertPos);
1651 0 : if( bUndo )
1652 : {
1653 0 : AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1654 :
1655 0 : EndUndo(); // do this here already, so Joe's actions happen _between_ our own.
1656 : }
1657 : }
1658 :
1659 : // Fill list with pages
1660 0 : std::vector<SdPage*> aPageList;
1661 :
1662 : // #98456, this has to be removed according to CL (KA 07/08/2002)
1663 : // #109884# but we need them again to restore the styles of the presentation objects while undo
1664 0 : aPageList.push_back(pMaster);
1665 0 : aPageList.push_back(pNotesMaster);
1666 :
1667 0 : if (bMaster || bLayoutReloaded)
1668 : {
1669 0 : for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1670 : {
1671 0 : pPage = (SdPage*) GetPage(nPage);
1672 0 : String aTest = pPage->GetLayoutName();
1673 0 : if (aTest == aOldPageLayoutName)
1674 : {
1675 0 : aPageList.push_back(pPage);
1676 : }
1677 0 : }
1678 :
1679 : }
1680 : else
1681 : {
1682 0 : aPageList.push_back(pSelectedPage);
1683 0 : aPageList.push_back(pNotes);
1684 : }
1685 :
1686 0 : for (std::vector<SdPage*>::iterator pIter = aPageList.begin(); pIter != aPageList.end(); ++pIter)
1687 : {
1688 0 : AutoLayout eAutoLayout = (*pIter)->GetAutoLayout();
1689 :
1690 0 : if( bUndo )
1691 : {
1692 : SdPresentationLayoutUndoAction * pPLUndoAction =
1693 : new SdPresentationLayoutUndoAction
1694 : (this,
1695 0 : ( pPage && pPage->IsMasterPage() ) ? aLayoutName : aOldLayoutName,
1696 : aLayoutName,
1697 0 : eAutoLayout, eAutoLayout, sal_False, *pIter);
1698 0 : pUndoMgr->AddUndoAction(pPLUndoAction);
1699 : }
1700 0 : (*pIter)->SetPresentationLayout(aLayoutName);
1701 0 : (*pIter)->SetAutoLayout(eAutoLayout);
1702 : }
1703 :
1704 : // Adapt new master pages
1705 0 : if (pSourceDoc != this)
1706 : {
1707 0 : Size aSize(rOldMaster.GetSize());
1708 0 : Rectangle aBorderRect(rOldMaster.GetLftBorder(),
1709 0 : rOldMaster.GetUppBorder(),
1710 0 : rOldMaster.GetRgtBorder(),
1711 0 : rOldMaster.GetLwrBorder());
1712 0 : pMaster->ScaleObjects(aSize, aBorderRect, sal_True);
1713 0 : pMaster->SetSize(aSize);
1714 0 : pMaster->SetBorder(rOldMaster.GetLftBorder(),
1715 0 : rOldMaster.GetUppBorder(),
1716 0 : rOldMaster.GetRgtBorder(),
1717 0 : rOldMaster.GetLwrBorder());
1718 0 : pMaster->SetOrientation( rOldMaster.GetOrientation() );
1719 0 : pMaster->SetAutoLayout(pMaster->GetAutoLayout());
1720 :
1721 0 : aSize = rOldNotesMaster.GetSize();
1722 0 : Rectangle aNotesBorderRect(rOldNotesMaster.GetLftBorder(),
1723 0 : rOldNotesMaster.GetUppBorder(),
1724 0 : rOldNotesMaster.GetRgtBorder(),
1725 0 : rOldNotesMaster.GetLwrBorder());
1726 0 : pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, sal_True);
1727 0 : pNotesMaster->SetSize(aSize);
1728 0 : pNotesMaster->SetBorder(rOldNotesMaster.GetLftBorder(),
1729 0 : rOldNotesMaster.GetUppBorder(),
1730 0 : rOldNotesMaster.GetRgtBorder(),
1731 0 : rOldNotesMaster.GetLwrBorder());
1732 0 : pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() );
1733 0 : pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout());
1734 :
1735 0 : if( (pSourceDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
1736 0 : (GetDocumentType() == DOCUMENT_TYPE_DRAW) )
1737 : {
1738 0 : pMaster->RemoveEmptyPresentationObjects();
1739 0 : pNotesMaster->RemoveEmptyPresentationObjects();
1740 : }
1741 0 : }
1742 : }
1743 : else
1744 : {
1745 : // Find a new name for the layout
1746 0 : OUString aName(createNewMasterPageLayoutName(*this));
1747 0 : String aPageLayoutName(aName);
1748 0 : aPageLayoutName.AppendAscii( SD_LT_SEPARATOR );
1749 0 : aPageLayoutName += String(SdResId(STR_LAYOUT_OUTLINE));
1750 :
1751 : // Generate new stylesheets
1752 0 : static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName);
1753 0 : SdStyleSheetVector aCreatedStyles;
1754 0 : static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles);
1755 :
1756 0 : if( bUndo )
1757 : {
1758 0 : SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, sal_True);
1759 0 : pUndoMgr->AddUndoAction(pMovStyles);
1760 : }
1761 :
1762 : // Generate new master pages and register them with the document
1763 0 : if( bUndo )
1764 0 : BegUndo();
1765 :
1766 0 : pMaster = (SdPage*) AllocPage(sal_True);
1767 0 : pMaster->SetSize(pSelectedPage->GetSize());
1768 0 : pMaster->SetBorder(pSelectedPage->GetLftBorder(),
1769 0 : pSelectedPage->GetUppBorder(),
1770 0 : pSelectedPage->GetRgtBorder(),
1771 0 : pSelectedPage->GetLwrBorder() );
1772 0 : pMaster->SetName(aName);
1773 0 : pMaster->SetLayoutName(aPageLayoutName);
1774 0 : InsertMasterPage(pMaster);
1775 :
1776 0 : if( bUndo )
1777 0 : AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1778 :
1779 0 : pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
1780 :
1781 0 : pNotesMaster = (SdPage*) AllocPage(sal_True);
1782 0 : pNotesMaster->SetPageKind(PK_NOTES);
1783 0 : pNotesMaster->SetSize(pNotes->GetSize());
1784 0 : pNotesMaster->SetBorder(pNotes->GetLftBorder(),
1785 0 : pNotes->GetUppBorder(),
1786 0 : pNotes->GetRgtBorder(),
1787 0 : pNotes->GetLwrBorder() );
1788 0 : pNotesMaster->SetName(aName);
1789 0 : pNotesMaster->SetLayoutName(aPageLayoutName);
1790 0 : InsertMasterPage(pNotesMaster);
1791 :
1792 0 : if( bUndo )
1793 0 : AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1794 :
1795 0 : pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
1796 :
1797 0 : if( bUndo )
1798 0 : EndUndo();
1799 :
1800 : // Create a list of affected default and notes pages
1801 0 : std::vector<SdPage*> aPageList;
1802 0 : if (bMaster)
1803 : {
1804 0 : for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1805 : {
1806 0 : pPage = (SdPage*) GetPage(nPage);
1807 0 : const String s(pPage->GetLayoutName());
1808 0 : if(s == aOldPageLayoutName)
1809 : {
1810 0 : aPageList.push_back(pPage);
1811 : }
1812 0 : }
1813 : }
1814 : else
1815 : {
1816 0 : aPageList.push_back(pSelectedPage);
1817 0 : aPageList.push_back(pNotes);
1818 : }
1819 :
1820 : // Set presentation layout and AutoLayout for the affected pages
1821 0 : for ( std::vector<SdPage*>::iterator pIter = aPageList.begin(); pIter != aPageList.end(); ++pIter )
1822 : {
1823 0 : AutoLayout eOldAutoLayout = (*pIter)->GetAutoLayout();
1824 : AutoLayout eNewAutoLayout =
1825 0 : (*pIter)->GetPageKind() == PK_STANDARD ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES;
1826 :
1827 0 : if( bUndo )
1828 : {
1829 : SdPresentationLayoutUndoAction * pPLUndoAction =
1830 : new SdPresentationLayoutUndoAction
1831 : (this, aOldLayoutName, aName,
1832 : eOldAutoLayout, eNewAutoLayout, sal_True,
1833 0 : *pIter);
1834 0 : pUndoMgr->AddUndoAction(pPLUndoAction);
1835 : }
1836 :
1837 0 : (*pIter)->SetPresentationLayout(aName);
1838 0 : (*pIter)->SetAutoLayout(eNewAutoLayout);
1839 0 : }
1840 : }
1841 :
1842 : // If the old master pages aren't used anymore, they and their styles have
1843 : // to be removed.
1844 0 : if (bCheckMasters)
1845 : {
1846 : // Check all
1847 0 : RemoveUnnecessaryMasterPages();
1848 : }
1849 : else
1850 : {
1851 : // Check only the master page that was replaced
1852 0 : RemoveUnnecessaryMasterPages(&rOldMaster);
1853 : }
1854 :
1855 0 : if( bUndo )
1856 0 : pUndoMgr->LeaveListAction();
1857 :
1858 0 : if( mpDocSh )
1859 0 : mpDocSh->SetWaitCursor( sal_False );
1860 : }
1861 :
1862 :
1863 :
1864 0 : void SdDrawDocument::Merge(SdrModel& rSourceModel,
1865 : sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1866 : sal_uInt16 nDestPos,
1867 : bool bMergeMasterPages, bool bAllMasterPages,
1868 : bool bUndo, bool bTreadSourceAsConst)
1869 : {
1870 0 : sal_uInt16 nMasterPageCount = GetMasterPageCount();
1871 0 : SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst );
1872 :
1873 : // add style family for each new master page
1874 0 : for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ )
1875 : {
1876 0 : SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) );
1877 0 : if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PK_STANDARD) )
1878 : {
1879 : // new master page created, add its style family
1880 0 : SdStyleSheetPool* pStylePool = (SdStyleSheetPool*) GetStyleSheetPool();
1881 0 : if( pStylePool )
1882 0 : pStylePool->AddStyleFamily( pPage );
1883 : }
1884 : }
1885 33 : }
1886 :
1887 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|