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