nss: upgrade to release 3.73
[LibreOffice.git] / sd / source / core / drawdoc3.cxx
blob02c6054751b28530c091044b5c9b6740e75d7a4e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <memory>
22 #include <string_view>
24 #include <sfx2/docfile.hxx>
25 #include <sfx2/docfilt.hxx>
26 #include <sfx2/app.hxx>
27 #include <svl/itemset.hxx>
28 #include <tools/debug.hxx>
30 #include <sfx2/fcontnr.hxx>
31 #include <svl/style.hxx>
32 #include <svx/svdpagv.hxx>
33 #include <svx/svdundo.hxx>
34 #include <vcl/stdtext.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/weld.hxx>
37 #include <xmloff/autolayout.hxx>
39 #include <strings.hrc>
40 #include <drawdoc.hxx>
41 #include <sdmod.hxx>
42 #include <sdpage.hxx>
43 #include <stlpool.hxx>
44 #include <sdresid.hxx>
45 #include <customshowlist.hxx>
46 #include <sdxfer.hxx>
48 #include <unmovss.hxx>
49 #include <unchss.hxx>
50 #include <unprlout.hxx>
51 #include <DrawDocShell.hxx>
52 #include <GraphicDocShell.hxx>
53 #include <ViewShell.hxx>
54 #include <View.hxx>
55 #include <ViewShellBase.hxx>
56 #include <strings.hxx>
58 using namespace ::com::sun::star;
60 /** Concrete incarnations get called by lcl_IterateBookmarkPages, for
61 every page in the bookmark document/list
64 namespace {
66 class InsertBookmarkAsPage_FindDuplicateLayouts
68 public:
69 explicit InsertBookmarkAsPage_FindDuplicateLayouts( std::vector<OUString> &rLayoutsToTransfer )
70 : mrLayoutsToTransfer(rLayoutsToTransfer) {}
71 void operator()( SdDrawDocument&, SdPage const *, bool, SdDrawDocument* );
72 private:
73 std::vector<OUString> &mrLayoutsToTransfer;
78 void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage const * pBMMPage, bool bRenameDuplicates, SdDrawDocument* pBookmarkDoc )
80 // now check for duplicate masterpage and layout names
82 OUString aLayout( pBMMPage->GetLayoutName() );
83 sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR );
84 if( nIndex != -1 )
85 aLayout = aLayout.copy(0, nIndex);
87 std::vector<OUString>::const_iterator pIter =
88 find(mrLayoutsToTransfer.begin(),mrLayoutsToTransfer.end(),aLayout);
90 bool bFound = pIter != mrLayoutsToTransfer.end();
92 const sal_uInt16 nMPageCount = rDoc.GetMasterPageCount();
93 for (sal_uInt16 nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++)
95 // Do the layouts already exist within the document?
96 SdPage* pTestPage = static_cast<SdPage*>( rDoc.GetMasterPage(nMPage) );
97 OUString aTest(pTestPage->GetLayoutName());
98 sal_Int32 nIndex2 = aTest.indexOf( SD_LT_SEPARATOR );
99 if( nIndex2 != -1 )
100 aTest = aTest.copy(0, nIndex2);
102 if (aTest == aLayout && pBMMPage->GetPageKind() == pTestPage->GetPageKind())
104 // Ignore Layouts with "Default" these seem to be special - in the sense that there are lot of assumption all over Impress
105 // about this
106 if( bRenameDuplicates && aTest != SdResId( STR_LAYOUT_DEFAULT_NAME ) && !(pTestPage->Equals(*pBMMPage)) )
108 pBookmarkDoc->RenameLayoutTemplate(
109 pBMMPage->GetLayoutName(), pBMMPage->GetName() + "_");
110 aLayout = pBMMPage->GetName();
112 break;
114 else
115 bFound = true;
119 if (!bFound)
120 mrLayoutsToTransfer.push_back(aLayout);
123 // Inserts a bookmark as a page
124 static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBookmarkDoc,
125 const std::vector<OUString> &rBookmarkList, sal_uInt16 nBMSdPageCount,
126 InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator, bool bRenameDuplicates )
129 // Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage
131 int nPos, nEndPos;
133 if( rBookmarkList.empty() )
135 // no list? whole source document
136 nEndPos = nBMSdPageCount;
138 else
140 // bookmark list? number of entries
141 nEndPos = rBookmarkList.size();
144 SdPage* pBMPage;
146 // iterate over number of pages to insert
147 for (nPos = 0; nPos < nEndPos; ++nPos)
149 // the master page associated to the nPos'th page to insert
150 SdPage* pBMMPage = nullptr;
152 if( rBookmarkList.empty() )
154 // simply take master page of nPos'th page in source document
155 pBMMPage = static_cast<SdPage*>(&(pBookmarkDoc->GetSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard)->TRG_GetMasterPage()));
157 else
159 // fetch nPos'th entry from bookmark list, and determine master page
160 OUString aBMPgName(rBookmarkList[nPos]);
161 bool bIsMasterPage;
163 sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage );
165 if (nBMPage != SDRPAGE_NOTFOUND)
167 pBMPage = static_cast<SdPage*>( pBookmarkDoc->GetPage(nBMPage) );
169 else
171 pBMPage = nullptr;
174 // enforce that bookmarked page is a standard page and not already a master page
175 if (pBMPage && pBMPage->GetPageKind()==PageKind::Standard && !pBMPage->IsMasterPage())
177 const sal_uInt16 nBMSdPage = (nBMPage - 1) / 2;
178 pBMMPage = static_cast<SdPage*> (&(pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard)->TRG_GetMasterPage()));
182 // successfully determined valid (bookmarked) page?
183 if( pBMMPage )
185 // yes, call functor
186 rPageIterator( rDoc, pBMMPage, bRenameDuplicates, pBookmarkDoc );
191 // Opens a bookmark document
192 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(SfxMedium* pMedium)
194 bool bOK = true;
195 SdDrawDocument* pBookmarkDoc = nullptr;
196 OUString aBookmarkName = pMedium->GetName();
197 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
198 if ( !pFilter )
200 pMedium->UseInteractionHandler( true );
201 SfxGetpApp()->GetFilterMatcher().GuessFilter(*pMedium, pFilter);
204 if ( !pFilter )
206 bOK = false;
208 else if ( !aBookmarkName.isEmpty() && maBookmarkFile != aBookmarkName )
210 bool bCreateGraphicShell = pFilter->GetServiceName() == "com.sun.star.drawing.DrawingDocument";
211 bool bCreateImpressShell = pFilter->GetServiceName() == "com.sun.star.presentation.PresentationDocument";
212 if ( bCreateGraphicShell || bCreateImpressShell )
214 CloseBookmarkDoc();
216 // Create a DocShell, as OLE objects might be contained in the
217 // document. (Persist)
218 // If that wasn't the case, we could load the model directly.
219 if ( bCreateGraphicShell )
220 // Draw
221 mxBookmarkDocShRef = new ::sd::GraphicDocShell(SfxObjectCreateMode::STANDARD);
222 else
223 // Impress
224 mxBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress);
226 bOK = mxBookmarkDocShRef->DoLoad(pMedium);
227 if( bOK )
229 maBookmarkFile = aBookmarkName;
230 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
235 DBG_ASSERT(!aBookmarkName.isEmpty(), "Empty document name!");
237 if (!bOK)
239 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr,
240 VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
241 xErrorBox->run();
243 CloseBookmarkDoc();
244 pBookmarkDoc = nullptr;
246 else if (mxBookmarkDocShRef.is())
248 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
251 return pBookmarkDoc;
254 // Opens a bookmark document
255 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(const OUString& rBookmarkFile)
257 SdDrawDocument* pBookmarkDoc = nullptr;
259 if (!rBookmarkFile.isEmpty() && maBookmarkFile != rBookmarkFile)
261 std::unique_ptr<SfxMedium> xMedium(new SfxMedium(rBookmarkFile, StreamMode::READ));
262 pBookmarkDoc = OpenBookmarkDoc(xMedium.release());
264 else if (mxBookmarkDocShRef.is())
266 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
269 return pBookmarkDoc;
272 // Inserts a bookmark (page or object)
273 void SdDrawDocument::InsertBookmark(
274 const std::vector<OUString> &rBookmarkList, // List of names of the bookmarks to be inserted
275 std::vector<OUString> &rExchangeList, // List of the names to be used
276 bool bLink, // Insert bookmarks as links?
277 sal_uInt16 nInsertPos, // Insertion position of pages
278 ::sd::DrawDocShell* pBookmarkDocSh, // If set, this is the source document
279 Point const * pObjPos) // Insertion position of objects
281 bool bOK = true;
282 bool bInsertPages = false;
284 if (rBookmarkList.empty())
286 // Insert all pages
287 bInsertPages = true;
289 else
291 SdDrawDocument* pBookmarkDoc = nullptr;
293 if (pBookmarkDocSh)
295 pBookmarkDoc = pBookmarkDocSh->GetDoc();
297 else if ( mxBookmarkDocShRef.is() )
299 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
301 else
302 bOK = false;
304 bInsertPages = bOK && std::any_of(rBookmarkList.begin(), rBookmarkList.end(),
305 [&pBookmarkDoc](const OUString& rBookmark) {
306 // Is there a page name in the bookmark list?
307 bool bIsMasterPage;
308 return pBookmarkDoc->GetPageByName(rBookmark, bIsMasterPage) != SDRPAGE_NOTFOUND;
312 bool bCalcObjCount = !rExchangeList.empty();
314 if ( bOK && bInsertPages )
316 // Insert all page bookmarks
317 bOK = InsertBookmarkAsPage(rBookmarkList, &rExchangeList, bLink, false/*bReplace*/,
318 nInsertPos, false/*bNoDialogs*/, pBookmarkDocSh, true/*bCopy*/, true, false);
321 if ( bOK && !rBookmarkList.empty() )
323 // Insert all object bookmarks
324 InsertBookmarkAsObject(rBookmarkList, rExchangeList,
325 pBookmarkDocSh, pObjPos, bCalcObjCount);
329 namespace
332 void
333 lcl_removeUnusedStyles(SfxStyleSheetBasePool* const pStyleSheetPool, StyleSheetCopyResultVector& rStyles)
335 StyleSheetCopyResultVector aUsedStyles;
336 aUsedStyles.reserve(rStyles.size());
337 for (const auto& a : rStyles)
339 if (a.m_xStyleSheet->IsUsed())
340 aUsedStyles.push_back(a);
341 else
342 pStyleSheetPool->Remove(a.m_xStyleSheet.get());
344 rStyles = aUsedStyles;
347 SfxStyleSheet *lcl_findStyle(StyleSheetCopyResultVector& rStyles, std::u16string_view aStyleName)
349 for (const auto& a : rStyles)
351 if (a.m_xStyleSheet->GetName().startsWith(aStyleName))
352 return a.m_xStyleSheet.get();
354 return nullptr;
359 bool SdDrawDocument::InsertBookmarkAsPage(
360 const std::vector<OUString> &rBookmarkList,
361 std::vector<OUString> *pExchangeList, // List of names to be used
362 bool bLink,
363 bool bReplace,
364 sal_uInt16 nInsertPos,
365 bool bNoDialogs,
366 ::sd::DrawDocShell* pBookmarkDocSh,
367 bool bCopy,
368 bool bMergeMasterPages,
369 bool bPreservePageNames)
371 bool bContinue = true;
372 bool bScaleObjects = false;
373 sal_uInt16 nReplacedStandardPages = 0;
375 SdDrawDocument* pBookmarkDoc = nullptr;
376 OUString aBookmarkName;
378 if (pBookmarkDocSh)
380 pBookmarkDoc = pBookmarkDocSh->GetDoc();
382 if (pBookmarkDocSh->GetMedium())
384 aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
387 else if ( mxBookmarkDocShRef.is() )
389 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
390 aBookmarkName = maBookmarkFile;
392 else
394 return false;
397 const sal_uInt16 nSdPageCount = GetSdPageCount(PageKind::Standard);
398 const sal_uInt16 nBMSdPageCount = pBookmarkDoc->GetSdPageCount(PageKind::Standard);
399 const sal_uInt16 nMPageCount = GetMasterPageCount();
401 if (nSdPageCount==0 || nBMSdPageCount==0 || nMPageCount==0)
403 return false;
406 // Store the size and some other properties of the first page and notes
407 // page so that inserted pages can be properly scaled even when inserted
408 // before the first page.
409 // Note that the pointers are used later on as general page pointers.
410 SdPage* pRefPage = GetSdPage(0, PageKind::Standard);
411 Size aSize(pRefPage->GetSize());
412 sal_Int32 nLeft = pRefPage->GetLeftBorder();
413 sal_Int32 nRight = pRefPage->GetRightBorder();
414 sal_Int32 nUpper = pRefPage->GetUpperBorder();
415 sal_Int32 nLower = pRefPage->GetLowerBorder();
416 Orientation eOrient = pRefPage->GetOrientation();
418 SdPage* pNPage = GetSdPage(0, PageKind::Notes);
419 Size aNSize(pNPage->GetSize());
420 sal_Int32 nNLeft = pNPage->GetLeftBorder();
421 sal_Int32 nNRight = pNPage->GetRightBorder();
422 sal_Int32 nNUpper = pNPage->GetUpperBorder();
423 sal_Int32 nNLower = pNPage->GetLowerBorder();
424 Orientation eNOrient = pNPage->GetOrientation();
426 // Adapt page size and margins to those of the later pages?
427 pRefPage = GetSdPage(nSdPageCount - 1, PageKind::Standard);
429 if( bNoDialogs )
431 // If this is clipboard, then no need to scale objects:
432 // this will make copied masters to differ from the originals,
433 // and thus InsertBookmarkAsPage_FindDuplicateLayouts will
434 // duplicate masters on insert to same document
435 m_bTransportContainer = (SD_MOD()->pTransferClip &&
436 SD_MOD()->pTransferClip->GetWorkDocument() == this);
437 if (!m_bTransportContainer)
439 if (rBookmarkList.empty())
440 bScaleObjects = pRefPage->IsScaleObjects();
441 else
442 bScaleObjects = true;
445 else
447 SdPage* pBMPage = pBookmarkDoc->GetSdPage(0,PageKind::Standard);
449 if (pBMPage->GetSize() != pRefPage->GetSize() ||
450 pBMPage->GetLeftBorder() != pRefPage->GetLeftBorder() ||
451 pBMPage->GetRightBorder() != pRefPage->GetRightBorder() ||
452 pBMPage->GetUpperBorder() != pRefPage->GetUpperBorder() ||
453 pBMPage->GetLowerBorder() != pRefPage->GetLowerBorder())
455 OUString aStr(SdResId(STR_SCALE_OBJECTS));
456 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr,
457 VclMessageType::Question, VclButtonsType::YesNo,
458 aStr));
459 xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
460 sal_uInt16 nBut = xQueryBox->run();
462 bScaleObjects = nBut == RET_YES;
463 bContinue = nBut != RET_CANCEL;
465 if (!bContinue)
467 return bContinue;
472 // Get the necessary presentation stylesheets and transfer them before
473 // the pages, else, the text objects won't reference their styles anymore.
474 SfxUndoManager* pUndoMgr = nullptr;
475 if( mpDocSh )
477 pUndoMgr = mpDocSh->GetUndoManager();
478 ViewShellId nViewShellId(-1);
479 if (sd::ViewShell* pViewShell = mpDocSh->GetViewShell())
480 nViewShellId = pViewShell->GetViewShellBase().GetViewShellId();
481 pUndoMgr->EnterListAction(SdResId(STR_UNDO_INSERTPAGES), "", 0, nViewShellId);
484 // Refactored copy'n'pasted layout name collection into IterateBookmarkPages
486 std::vector<OUString> aLayoutsToTransfer;
487 InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor( aLayoutsToTransfer );
488 lcl_IterateBookmarkPages( *this, pBookmarkDoc, rBookmarkList, nBMSdPageCount, aSearchFunctor, ( rBookmarkList.empty() && pBookmarkDoc != this ) );
490 // Copy the style that we actually need.
491 SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*pBookmarkDoc->GetStyleSheetPool());
492 SdStyleSheetPool& rStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*GetStyleSheetPool());
494 // When copying styles, also copy the master pages!
495 if( !aLayoutsToTransfer.empty() )
496 bMergeMasterPages = true;
498 for ( const OUString& layoutName : aLayoutsToTransfer )
500 StyleSheetCopyResultVector aCreatedStyles;
502 rStyleSheetPool.CopyLayoutSheets(layoutName, rBookmarkStyleSheetPool,aCreatedStyles);
504 if(!aCreatedStyles.empty())
506 if( pUndoMgr )
508 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aCreatedStyles, true));
513 // Copy styles. This unconditionally copies all styles, even those
514 // that are not used in any of the inserted pages. The unused styles
515 // are then removed at the end of the function, where we also create
516 // undo records for the inserted styles.
517 StyleSheetCopyResultVector aNewGraphicStyles;
518 OUString aRenameStr;
519 if(!bReplace && !bNoDialogs)
520 aRenameStr = "_";
521 rStyleSheetPool.RenameAndCopyGraphicSheets(rBookmarkStyleSheetPool, aNewGraphicStyles, aRenameStr);
522 StyleSheetCopyResultVector aNewCellStyles;
523 rStyleSheetPool.CopyCellSheets(rBookmarkStyleSheetPool, aNewCellStyles);
525 // TODO handle undo of table styles too
526 rStyleSheetPool.CopyTableStyles(rBookmarkStyleSheetPool);
528 // Insert document
530 const bool bUndo = IsUndoEnabled();
532 if( bUndo )
533 BegUndo(SdResId(STR_UNDO_INSERTPAGES));
535 if (rBookmarkList.empty())
537 if (nInsertPos >= GetPageCount())
539 // Add pages to the end
540 nInsertPos = GetPageCount();
543 sal_uInt16 nActualInsertPos = nInsertPos;
545 sal_uInt16 nBMSdPage;
546 std::set<sal_uInt16> aRenameSet;
547 std::map<sal_uInt16,OUString> aNameMap;
549 for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
551 SdPage* pBMPage = pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard);
552 OUString sName(pBMPage->GetName());
553 bool bIsMasterPage;
555 if (bLink)
557 // Remember the names of all pages
558 aNameMap.insert(std::make_pair(nBMSdPage,sName));
561 // Have to check for duplicate names here, too
562 // don't change name if source and dest model are the same!
563 if( pBookmarkDoc != this &&
564 GetPageByName(sName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
566 // delay renaming *after* pages are copied (might destroy source otherwise)
567 aRenameSet.insert(nBMSdPage);
571 Merge(*pBookmarkDoc,
572 1, // Not the handout page
573 0xFFFF, // But all others
574 nActualInsertPos, // Insert at position ...
575 bMergeMasterPages, // Move master pages?
576 false, // But only the master pages used
577 true, // Create an undo action
578 bCopy); // Copy (or merge) pages?
580 for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
582 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
583 SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) );
585 // delay renaming *after* pages are copied (might destroy source otherwise)
586 if( aRenameSet.find(nBMSdPage) != aRenameSet.end() )
588 // Page name already in use -> Use default name for default and
589 // notes page
590 pPage->SetName(OUString());
591 pNotesPage->SetName(OUString());
594 if (bLink)
596 OUString aName(aNameMap[nBMSdPage]);
598 // Assemble all link names
599 pPage->SetFileName(aBookmarkName);
600 pPage->SetBookmarkName(aName);
603 nActualInsertPos += 2;
606 else
608 // Insert selected pages
609 SdPage* pBMPage;
611 if (nInsertPos >= GetPageCount())
613 // Add pages to the end
614 bReplace = false;
615 nInsertPos = GetPageCount();
618 sal_uInt16 nActualInsertPos = nInsertPos;
620 // Collect the bookmarked pages
621 ::std::vector<SdPage*> aBookmarkedPages (rBookmarkList.size(), nullptr);
622 for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos)
624 OUString aPgName(rBookmarkList[nPos]);
625 bool bIsMasterPage;
626 sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage );
628 if (nBMPage != SDRPAGE_NOTFOUND)
630 aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(pBookmarkDoc->GetPage(nBMPage));
634 for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos)
636 pBMPage = aBookmarkedPages[nPos];
637 sal_uInt16 nBMPage = pBMPage!=nullptr ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND;
639 if (pBMPage && pBMPage->GetPageKind()==PageKind::Standard && !pBMPage->IsMasterPage())
641 // It has to be a default page
642 bool bMustRename = false;
644 // delay renaming *after* pages are copied (might destroy source otherwise)
645 // don't change name if source and dest model are the same!
646 // avoid renaming if replacing the same page
647 OUString aPgName(rBookmarkList[nPos]);
648 bool bIsMasterPage;
649 sal_uInt16 nPageSameName = GetPageByName(aPgName, bIsMasterPage);
650 if( pBookmarkDoc != this &&
651 nPageSameName != SDRPAGE_NOTFOUND &&
652 ( !bReplace ||
653 nPageSameName != nActualInsertPos ) )
655 bMustRename = true;
658 SdPage* pBookmarkPage = pBMPage;
659 if (bReplace )
661 ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage );
664 Merge(*pBookmarkDoc,
665 nBMPage, // From page (default page)
666 nBMPage+1, // To page (notes page)
667 nActualInsertPos, // Insert at position
668 bMergeMasterPages, // Move master pages?
669 false, // But only the master pages used
670 true, // Create undo action
671 bCopy); // Copy (or merge) pages?
673 if( bReplace )
675 if( GetPage( nActualInsertPos ) != pBookmarkPage )
677 // bookmark page was not moved but cloned, so update custom shows again
678 ReplacePageInCustomShows( pBookmarkPage, dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ) );
682 if( bMustRename )
684 // Page name already in use -> use default name for default and
685 // notes page
686 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
687 pPage->SetName(OUString());
688 SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) );
689 pNotesPage->SetName(OUString());
692 if (bLink)
694 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
695 pPage->SetFileName(aBookmarkName);
696 pPage->SetBookmarkName(aPgName);
699 if (bReplace)
701 // Remove page and notes page.
702 const sal_uInt16 nDestPageNum(nActualInsertPos + 2);
703 SdPage* pStandardPage = nullptr;
705 if(nDestPageNum < GetPageCount())
707 pStandardPage = static_cast<SdPage*>(GetPage(nDestPageNum));
710 if (pStandardPage)
712 if( bPreservePageNames )
714 // Take old slide names for inserted pages
715 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
716 pPage->SetName( pStandardPage->GetRealName() );
719 if( bUndo )
720 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage));
722 RemovePage(nDestPageNum);
724 if( !bUndo )
725 delete pStandardPage;
728 SdPage* pNotesPage = nullptr;
730 if(nDestPageNum < GetPageCount())
732 pNotesPage = static_cast<SdPage*>(GetPage(nDestPageNum));
735 if (pNotesPage)
737 if( bPreservePageNames )
739 // Take old slide names for inserted pages
740 SdPage* pNewNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1));
741 if( pNewNotesPage )
742 pNewNotesPage->SetName( pStandardPage->GetRealName() );
745 if( bUndo )
746 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
748 RemovePage(nDestPageNum);
750 if( !bUndo )
751 delete pNotesPage;
754 nReplacedStandardPages++;
757 nActualInsertPos += 2;
762 // We might have duplicate master pages now, as the drawing engine does not
763 // recognize duplicates. Remove these now.
764 sal_uInt16 nNewMPageCount = GetMasterPageCount();
766 // Go backwards, so the numbers don't become messed up
767 for (sal_uInt16 nPage = nNewMPageCount - 1; nPage >= nMPageCount; nPage--)
769 pRefPage = static_cast<SdPage*>( GetMasterPage(nPage) );
770 OUString aMPLayout(pRefPage->GetLayoutName());
771 PageKind eKind = pRefPage->GetPageKind();
773 // Does this already exist?
774 for (sal_uInt16 nTest = 0; nTest < nMPageCount; nTest++)
776 SdPage* pTest = static_cast<SdPage*>( GetMasterPage(nTest) );
777 OUString aTest(pTest->GetLayoutName());
779 // nInsertPos > 2 is always true when inserting into non-empty models
780 if ( nInsertPos > 2 &&
781 aTest == aMPLayout &&
782 eKind == pTest->GetPageKind() )
784 if( bUndo )
785 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage));
787 RemoveMasterPage(nPage);
789 if( !bUndo )
790 delete pRefPage;
791 nNewMPageCount--;
792 break;
797 // nInsertPos > 2 is always true when inserting into non-empty models
798 if (nInsertPos > 0)
800 sal_uInt16 nSdPageStart = (nInsertPos - 1) / 2;
801 sal_uInt16 nSdPageEnd = bReplace
802 ? nSdPageStart + nReplacedStandardPages - 1
803 : GetSdPageCount(PageKind::Standard) - nSdPageCount + nSdPageStart - 1;
804 const bool bRemoveEmptyPresObj =
805 (pBookmarkDoc->GetDocumentType() == DocumentType::Impress) &&
806 (GetDocumentType() == DocumentType::Draw);
808 std::vector<OUString>::iterator pExchangeIter;
810 if (pExchangeList)
811 pExchangeIter = pExchangeList->begin();
813 for (sal_uInt16 nSdPage = nSdPageStart; nSdPage <= nSdPageEnd; nSdPage++)
815 pRefPage = GetSdPage(nSdPage, PageKind::Standard);
817 if (pExchangeList && pExchangeIter != pExchangeList->end())
819 // Get the name to use from Exchange list
820 OUString aExchangeName(*pExchangeIter);
821 pRefPage->SetName(aExchangeName);
822 Broadcast(SdrHint(SdrHintKind::PageOrderChange, pRefPage));
824 SdPage* pNewNotesPage = GetSdPage(nSdPage, PageKind::Notes);
825 pNewNotesPage->SetName(aExchangeName);
826 Broadcast(SdrHint(SdrHintKind::PageOrderChange, pNewNotesPage));
828 ++pExchangeIter;
831 OUString aLayout(pRefPage->GetLayoutName());
832 sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR );
833 if( nIndex != -1 )
834 aLayout = aLayout.copy(0, nIndex);
836 // update layout and referred master page
837 pRefPage->SetPresentationLayout(aLayout);
838 if( bUndo )
839 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
841 if (bScaleObjects)
843 ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
844 pRefPage->ScaleObjects(aSize, aBorderRect, true);
846 pRefPage->SetSize(aSize);
847 pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
848 pRefPage->SetOrientation( eOrient );
850 if( bRemoveEmptyPresObj )
851 pRefPage->RemoveEmptyPresentationObjects();
853 pRefPage = GetSdPage(nSdPage, PageKind::Notes);
855 // update layout and referred master page
856 pRefPage->SetPresentationLayout(aLayout);
857 if( bUndo )
858 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
860 if (bScaleObjects)
862 ::tools::Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
863 pRefPage->ScaleObjects(aNSize, aBorderRect, true);
866 pRefPage->SetSize(aNSize);
867 pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
868 pRefPage->SetOrientation( eNOrient );
870 if( bRemoveEmptyPresObj )
871 pRefPage->RemoveEmptyPresentationObjects();
874 ///Remove processed elements, to avoid doing hacks in InsertBookmarkAsObject
875 if ( pExchangeList )
876 pExchangeList->erase(pExchangeList->begin(),pExchangeIter);
878 for (sal_uInt16 nPage = nMPageCount; nPage < nNewMPageCount; nPage++)
880 pRefPage = static_cast<SdPage*>( GetMasterPage(nPage) );
881 if (pRefPage->GetPageKind() == PageKind::Standard)
883 if (bScaleObjects)
885 ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
886 pRefPage->ScaleObjects(aSize, aBorderRect, true);
888 pRefPage->SetSize(aSize);
889 pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
890 pRefPage->SetOrientation( eOrient );
892 else // Can only be notes
894 if (bScaleObjects)
896 ::tools::Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
897 pRefPage->ScaleObjects(aNSize, aBorderRect, true);
899 pRefPage->SetSize(aNSize);
900 pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
901 pRefPage->SetOrientation( eNOrient );
904 if( bRemoveEmptyPresObj )
905 pRefPage->RemoveEmptyPresentationObjects();
909 // Make absolutely sure no double masterpages are there
910 RemoveUnnecessaryMasterPages(nullptr, true);
912 // Rename object styles if necessary
913 if(!aRenameStr.isEmpty())
917 for(sal_uInt32 p = nInsertPos; p < sal_uInt32(nInsertPos) + sal_uInt32(nBMSdPageCount); p++)
919 SdPage *pPg = static_cast<SdPage *>( GetPage(p) );
920 for(size_t i = 0; pPg && (i < pPg->GetObjCount()); ++i)
922 if(pPg->GetObj(i)->GetStyleSheet())
924 OUString aStyleName = pPg->GetObj(i)->GetStyleSheet()->GetName();
925 SfxStyleSheet *pSheet = lcl_findStyle(aNewGraphicStyles, OUString(aStyleName + aRenameStr));
926 if(pSheet != nullptr)
927 pPg->GetObj(i)->SetStyleSheet(pSheet, true);
932 catch(...)
934 OSL_FAIL("Exception while renaming styles @ SdDrawDocument::InsertBookmarkAsPage");
937 // remove copied styles not used on any inserted page and create
938 // undo records
939 // WARNING: SdMoveStyleSheetsUndoAction clears the passed list of
940 // styles, so it cannot be used after this point
941 lcl_removeUnusedStyles(GetStyleSheetPool(), aNewGraphicStyles);
942 if (!aNewGraphicStyles.empty() && pUndoMgr)
943 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aNewGraphicStyles, true));
944 lcl_removeUnusedStyles(GetStyleSheetPool(), aNewCellStyles);
945 if (!aNewCellStyles.empty() && pUndoMgr)
946 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aNewCellStyles, true));
948 if( bUndo )
949 EndUndo();
951 if (pUndoMgr)
952 pUndoMgr->LeaveListAction();
954 return bContinue;
957 // Inserts a bookmark as an object
958 bool SdDrawDocument::InsertBookmarkAsObject(
959 const std::vector<OUString> &rBookmarkList,
960 const std::vector<OUString> &rExchangeList, // List of names to use
961 ::sd::DrawDocShell* pBookmarkDocSh,
962 Point const * pObjPos,
963 bool bCalcObjCount)
965 bool bOK = true;
966 bool bOLEObjFound = false;
967 std::unique_ptr<::sd::View> pBMView;
969 SdDrawDocument* pBookmarkDoc = nullptr;
971 if (pBookmarkDocSh)
973 pBookmarkDoc = pBookmarkDocSh->GetDoc();
975 else if ( mxBookmarkDocShRef.is() )
977 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
979 else
981 return false;
984 if (rBookmarkList.empty())
986 pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr));
987 pBMView->EndListening(*pBookmarkDoc);
988 pBMView->MarkAll();
990 else
992 SdrPage* pPage;
993 SdrPageView* pPV;
995 for ( const auto& rBookmark : rBookmarkList )
997 // Get names of bookmarks from the list
998 SdrObject* pObj = pBookmarkDoc->GetObj(rBookmark);
1000 if (pObj)
1002 // Found an object
1003 if (pObj->GetObjInventor() == SdrInventor::Default &&
1004 pObj->GetObjIdentifier() == OBJ_OLE2)
1006 bOLEObjFound = true;
1009 if (!pBMView)
1011 // Create View for the first time
1012 pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr));
1013 pBMView->EndListening(*pBookmarkDoc);
1016 pPage = pObj->getSdrPageFromSdrObject();
1018 if (pPage->IsMasterPage())
1020 pPV = pBMView->ShowSdrPage(pBMView->GetModel()->GetMasterPage(pPage->GetPageNum()));
1022 else
1024 pPV = pBMView->GetSdrPageView();
1025 if( !pPV || (pPV->GetPage() != pPage))
1026 pPV = pBMView->ShowSdrPage(pPage);
1029 pBMView->MarkObj(pObj, pPV);
1034 if (pBMView)
1036 // Insert selected objects
1037 std::unique_ptr<::sd::View> pView(new ::sd::View(*this, nullptr));
1038 pView->EndListening(*this);
1040 // Look for the page into which the objects are supposed to be inserted
1041 SdrPage* pPage = GetSdPage(0, PageKind::Standard);
1043 if (mpDocSh)
1045 ::sd::ViewShell* pViewSh = mpDocSh->GetViewShell();
1047 if (pViewSh)
1049 // Which page is currently in view?
1050 SdrPageView* pPV = pViewSh->GetView()->GetSdrPageView();
1052 if (pPV)
1054 pPage = pPV->GetPage();
1056 else if (pViewSh->GetActualPage())
1058 pPage = pViewSh->GetActualPage();
1063 Point aObjPos;
1065 if (pObjPos)
1067 aObjPos = *pObjPos;
1069 else
1071 aObjPos = ::tools::Rectangle(Point(), pPage->GetSize()).Center();
1074 size_t nCountBefore = 0;
1076 if (!rExchangeList.empty() || bCalcObjCount)
1078 // Sort OrdNums and get the number of objects before inserting
1079 pPage->RecalcObjOrdNums();
1080 nCountBefore = pPage->GetObjCount();
1083 if (bOLEObjFound)
1084 pBMView->GetDoc().SetAllocDocSh(true);
1086 SdDrawDocument* pTmpDoc = static_cast<SdDrawDocument*>( pBMView->CreateMarkedObjModel().release() );
1087 bOK = pView->Paste(*pTmpDoc, aObjPos, pPage, SdrInsertFlags::NONE);
1089 if (bOLEObjFound)
1090 pBMView->GetDoc().SetAllocDocSh(false);
1092 if (!bOLEObjFound)
1093 delete pTmpDoc; // Would otherwise be destroyed by DocShell
1095 pView.reset();
1097 // Get number of objects after inserting.
1098 const size_t nCount = pPage->GetObjCount();
1099 if (nCountBefore < nCount)
1101 size_t nObj = nCountBefore;
1102 for (const auto& rExchange : rExchangeList)
1104 // Get the name to use from the Exchange list
1105 if (pPage->GetObj(nObj))
1107 pPage->GetObj(nObj)->SetName(rExchange);
1110 ++nObj;
1111 if (nObj >= nCount)
1112 break;
1117 return bOK;
1120 // Stops the bookmark insertion
1121 void SdDrawDocument::CloseBookmarkDoc()
1123 if (mxBookmarkDocShRef.is())
1125 mxBookmarkDocShRef->DoClose();
1128 mxBookmarkDocShRef.clear();
1129 maBookmarkFile.clear();
1132 // Is this document read-only?
1133 bool SdDrawDocument::IsReadOnly() const
1135 return false;
1138 // In the subsequent AllocModel() a DocShell (xAllocedDocShRef) is created.
1139 // Any pre-existing DocShell is deleted
1140 void SdDrawDocument::SetAllocDocSh(bool bAlloc)
1142 mbAllocDocSh = bAlloc;
1144 if(mxAllocedDocShRef.is())
1146 mxAllocedDocShRef->DoClose();
1149 mxAllocedDocShRef.clear();
1152 // Return list of CustomShows (create it, too, if necessary)
1153 SdCustomShowList* SdDrawDocument::GetCustomShowList(bool bCreate)
1155 if (!mpCustomShowList && bCreate)
1157 mpCustomShowList.reset(new SdCustomShowList);
1160 return mpCustomShowList.get();
1163 // Remove unused master pages and layouts
1164 void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage* pMasterPage, bool bOnlyDuplicatePages, bool bUndo)
1166 ::sd::View* pView = nullptr;
1167 SfxUndoManager* pUndoMgr = nullptr;
1169 if( bUndo && !IsUndoEnabled() )
1170 bUndo = false;
1172 if (mpDocSh)
1174 pUndoMgr = mpDocSh->GetUndoManager();
1176 if (mpDocSh->GetViewShell())
1177 pView = mpDocSh->GetViewShell()->GetView();
1180 // Check all master pages
1181 sal_uInt16 nSdMasterPageCount = GetMasterSdPageCount( PageKind::Standard );
1182 for (sal_Int32 nMPage = nSdMasterPageCount - 1; nMPage >= 0; nMPage--)
1184 SdPage* pMaster = pMasterPage;
1185 SdPage* pNotesMaster = nullptr;
1187 if (!pMaster)
1189 pMaster = GetMasterSdPage( static_cast<sal_uInt16>(nMPage), PageKind::Standard );
1190 pNotesMaster = GetMasterSdPage( static_cast<sal_uInt16>(nMPage), PageKind::Notes );
1192 else
1194 for ( sal_uInt16 nMPg = 0; nMPg < GetMasterPageCount(); nMPg++ )
1196 if ( pMaster == GetMasterPage( nMPg ) )
1198 pNotesMaster = static_cast<SdPage*>( GetMasterPage( ++nMPg ) );
1199 break;
1204 DBG_ASSERT( pMaster->GetPageKind() == PageKind::Standard, "wrong page kind" );
1206 if ( pMaster->GetPageKind() == PageKind::Standard &&
1207 GetMasterPageUserCount( pMaster ) == 0 &&
1208 pNotesMaster )
1210 // Do not delete master pages that have their precious flag set
1211 bool bDeleteMaster = !pMaster->IsPrecious();
1212 OUString aLayoutName = pMaster->GetLayoutName();
1214 if(bOnlyDuplicatePages )
1216 // remove only duplicate pages
1217 bDeleteMaster = false;
1218 for (sal_uInt16 i = 0; i < GetMasterSdPageCount( PageKind::Standard ); i++)
1220 SdPage* pMPg = GetMasterSdPage( i, PageKind::Standard );
1221 if( pMPg != pMaster &&
1222 pMPg->GetLayoutName() == aLayoutName )
1224 // duplicate page found -> remove it
1225 bDeleteMaster = true;
1230 if( bDeleteMaster )
1232 if (pView)
1234 // if MasterPage is visible hide on pageview
1235 SdrPageView* pPgView = pView->GetSdrPageView();
1236 if (pPgView)
1238 SdrPage* pShownPage = pPgView->GetPage();
1239 if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) )
1241 pView->HideSdrPage();
1242 pView->ShowSdrPage( GetSdPage( 0, PageKind::Standard ) );
1247 if( bUndo )
1249 BegUndo();
1250 AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster ) );
1253 RemoveMasterPage( pNotesMaster->GetPageNum() );
1255 if( !bUndo )
1256 delete pNotesMaster;
1258 if( bUndo )
1259 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster));
1261 RemoveMasterPage( pMaster->GetPageNum() );
1263 if( !bUndo )
1264 delete pMaster;
1266 if( bUndo )
1267 EndUndo(); // do this here already, so Joe's actions happen _between_ our own
1269 // Delete old, unused layout stylesheets
1270 bool bDeleteOldStyleSheets = true;
1271 for ( sal_uInt16 nMPg = 0;
1272 nMPg < GetMasterPageCount() && bDeleteOldStyleSheets;
1273 nMPg++ )
1275 SdPage* pMPg = static_cast<SdPage*>( GetMasterPage(nMPg) );
1276 if (pMPg->GetLayoutName() == aLayoutName)
1278 bDeleteOldStyleSheets = false;
1282 if (bDeleteOldStyleSheets)
1284 SdStyleSheetVector aRemove;
1285 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList( aLayoutName, aRemove );
1287 if( bUndo )
1289 StyleSheetCopyResultVector aUndoRemove;
1290 aUndoRemove.reserve(aRemove.size());
1291 for (const auto& a : aRemove)
1292 aUndoRemove.emplace_back(a.get(), true);
1294 if (pUndoMgr)
1295 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aUndoRemove, false));
1298 for( const auto& a : aRemove )
1299 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->Remove(a.get());
1304 if (pMasterPage)
1305 break; // Just this one master page!
1309 /** Exchange master page
1311 * Either the nSdPageNum gets a new, own master page or the master page is
1312 * exchanged completely (which then applies to all pages).
1314 * nSdPageNum : page number that the new master page should get.
1315 * rLayoutName : LayoutName of the new master page
1316 * pSourceDoc : document (template) to get the master page from
1317 * bMaster : exchange the master page of nSdPageNum
1318 * bCheckMasters: remove unused master pages
1320 * If pSourceDoc == NULL, an empty master page is applied.
1321 * If rLayoutName is empty, the first master page is used.
1323 // #i121863# factored out functionality
1324 static bool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, const OUString& rCandidate)
1326 if (rCandidate.isEmpty())
1328 return false;
1331 const sal_uInt16 nPageCount(rDoc.GetMasterPageCount());
1333 for(sal_uInt16 a(0); a < nPageCount; a++)
1335 const SdrPage* pCandidate = rDoc.GetMasterPage(a);
1336 OUString aPageLayoutName(pCandidate->GetLayoutName());
1337 sal_Int32 nIndex = aPageLayoutName.indexOf(SD_LT_SEPARATOR);
1338 if( nIndex != -1 )
1339 aPageLayoutName = aPageLayoutName.copy(0, nIndex);
1341 if(aPageLayoutName == rCandidate)
1343 return false;
1347 return true;
1350 // #i121863# factored out functionality
1351 static OUString createNewMasterPageLayoutName(const SdDrawDocument& rDoc)
1353 const OUString aBaseName(SdResId(STR_LAYOUT_DEFAULT_NAME));
1354 sal_uInt16 nCount(0);
1355 for (;;)
1357 OUString aRetval = aBaseName;
1358 if(nCount)
1360 aRetval += OUString::number(nCount);
1362 if (isMasterPageLayoutNameUnique(rDoc, aRetval))
1363 return aRetval;
1364 nCount++;
1368 void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum,
1369 const OUString& rLayoutName,
1370 SdDrawDocument* pSourceDoc,
1371 bool bMaster,
1372 bool bCheckMasters)
1374 SfxUndoManager* pUndoMgr = nullptr;
1376 if( mpDocSh )
1378 mpDocSh->SetWaitCursor( true );
1379 pUndoMgr = mpDocSh->GetUndoManager();
1382 const bool bUndo = pUndoMgr && IsUndoEnabled();
1384 if (bUndo)
1386 ViewShellId nViewShellId(-1);
1387 if (sd::ViewShell* pViewShell = mpDocSh->GetViewShell())
1388 nViewShellId = pViewShell->GetViewShellBase().GetViewShellId();
1389 pUndoMgr->EnterListAction(SdResId(STR_UNDO_SET_PRESLAYOUT), OUString(), 0, nViewShellId);
1392 SdPage* pSelectedPage = GetSdPage(nSdPageNum, PageKind::Standard);
1393 SdPage* pNotes = static_cast<SdPage*>( GetPage(pSelectedPage->GetPageNum()+1) );
1394 SdPage& rOldMaster = static_cast<SdPage&>(pSelectedPage->TRG_GetMasterPage());
1395 SdPage& rOldNotesMaster = static_cast<SdPage&>(pNotes->TRG_GetMasterPage());
1396 SdPage* pMaster = nullptr;
1397 SdPage* pNotesMaster = nullptr;
1398 OUString aOldPageLayoutName(pSelectedPage->GetLayoutName());
1399 OUString aOldLayoutName(aOldPageLayoutName);
1400 sal_Int32 nIndex = aOldLayoutName.indexOf( SD_LT_SEPARATOR );
1401 if( nIndex != -1 )
1402 aOldLayoutName = aOldLayoutName.copy(0, nIndex);
1404 if (pSourceDoc)
1406 std::vector<StyleReplaceData> aReplList; // List of replaced stylesheets
1407 bool bLayoutReloaded = false; // Was ex. layout reloaded?
1409 // LayoutName, Page and Notes page
1410 if (rLayoutName.isEmpty())
1412 // No LayoutName: take first MasterPage
1413 pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard);
1414 pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes);
1416 else
1418 OUString aSearchFor = rLayoutName + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
1420 for (sal_uInt16 nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); ++nMP)
1422 SdPage* pMP = static_cast<SdPage*>( pSourceDoc->GetMasterPage(nMP) );
1424 if (pMP->GetLayoutName() == aSearchFor)
1426 if (pMP->GetPageKind() == PageKind::Standard)
1427 pMaster = pMP;
1428 if (pMP->GetPageKind() == PageKind::Notes)
1429 pNotesMaster = pMP;
1431 if (pMaster && pNotesMaster)
1432 break;
1434 DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
1435 DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
1437 // this should not happen, but looking at crash reports, it does
1438 if( (pMaster == nullptr) || (pNotesMaster == nullptr) )
1440 // so take the first MasterPage
1441 pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard);
1442 pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes);
1446 // we should never reach this, but one never knows...
1447 if( (pMaster == nullptr) || (pNotesMaster == nullptr) )
1449 if (bUndo)
1450 pUndoMgr->LeaveListAction();
1452 if( mpDocSh )
1453 mpDocSh->SetWaitCursor( false );
1455 OSL_FAIL( "SdDrawDocument::SetMasterPage() failed!" );
1457 return;
1460 const OUString aOriginalNewLayoutName( pMaster->GetName() );
1461 OUString aTargetNewLayoutName(aOriginalNewLayoutName);
1463 if (pSourceDoc != this)
1465 // #i121863# clone masterpages, they are from another model (!)
1466 std::unique_ptr<SdPage> pNewNotesMaster(dynamic_cast< SdPage* >(pNotesMaster->CloneSdrPage(*this)));
1467 std::unique_ptr<SdPage> pNewMaster(dynamic_cast< SdPage* >(pMaster->CloneSdrPage(*this)));
1469 if(!pNewNotesMaster || !pNewMaster)
1471 OSL_FAIL("SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" );
1472 return;
1475 pNotesMaster = pNewNotesMaster.release();
1476 pMaster = pNewMaster.release();
1478 // layout name needs to be unique
1479 aTargetNewLayoutName = pMaster->GetLayoutName();
1480 sal_Int32 nIndex2 = aTargetNewLayoutName.indexOf(SD_LT_SEPARATOR);
1481 if( nIndex2 != -1 )
1482 aTargetNewLayoutName = aTargetNewLayoutName.copy(0, nIndex2);
1484 if(!isMasterPageLayoutNameUnique(*this, aTargetNewLayoutName))
1486 aTargetNewLayoutName = createNewMasterPageLayoutName(*this);
1488 OUString aTemp = aTargetNewLayoutName + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
1490 pMaster->SetName(aTargetNewLayoutName);
1491 pMaster->SetLayoutName(aTemp);
1493 pNotesMaster->SetName(aTargetNewLayoutName);
1494 pNotesMaster->SetLayoutName(aTemp);
1498 if (pSourceDoc != this)
1500 const sal_uInt16 nMasterPageCount = GetMasterPageCount();
1501 for ( sal_uInt16 nMPage = 0; nMPage < nMasterPageCount; nMPage++ )
1503 SdPage* pCheckMaster = static_cast<SdPage*>(GetMasterPage(nMPage));
1504 if( pCheckMaster->GetName() == aTargetNewLayoutName )
1506 bLayoutReloaded = true;
1507 break;
1511 // Correct or create presentation templates --
1512 // only worry about presentation templates
1513 OUString aName;
1514 SdStyleSheetPool* pSourceStyleSheetPool = static_cast<SdStyleSheetPool*>( pSourceDoc->GetStyleSheetPool() );
1516 StyleSheetCopyResultVector aCreatedStyles; // List of created stylesheets
1517 SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First(SfxStyleFamily::Page);
1519 while (pHisSheet)
1521 aName = pHisSheet->GetName();
1523 // #i121863# search in source styles with original style name from source of
1524 // evtl. cloned master (not-cloned, renamed for uniqueness)
1525 if( aName.startsWith( aOriginalNewLayoutName ) )
1527 // #i121863# build name of evtl. cloned master style to search for
1528 if(aOriginalNewLayoutName != aTargetNewLayoutName)
1530 const sal_Int32 nPos(aName.indexOf(SD_LT_SEPARATOR));
1531 aName = aTargetNewLayoutName + aName.subView(nPos);
1534 SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SfxStyleFamily::Page) );
1536 if (pMySheet)
1538 // A stylesheet of the same name already exists -> overwrite contents
1539 bool bTest = pMySheet->SetName(pHisSheet->GetName());
1540 DBG_ASSERT(bTest, "Renaming StyleSheet failed.");
1541 pMySheet->GetItemSet().ClearItem(); // Delete all
1543 if (bUndo)
1545 pUndoMgr->AddUndoAction(std::make_unique<StyleSheetUndoAction>(this,
1546 pMySheet, &pHisSheet->GetItemSet()));
1548 pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1549 pMySheet->Broadcast(SfxHint(SfxHintId::DataChanged));
1551 else
1553 // create new style
1554 OUString aHelpFile;
1555 pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SfxStyleFamily::Page, pHisSheet->GetMask()) );
1556 pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) );
1557 pMySheet->GetItemSet().ClearItem(); // Delete all
1558 pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1560 aCreatedStyles.emplace_back(static_cast<SdStyleSheet*>(pMySheet), true);
1563 StyleReplaceData aReplData;
1564 aReplData.nNewFamily = pMySheet->GetFamily();
1565 aReplData.nFamily = pMySheet->GetFamily();
1566 aReplData.aNewName = pMySheet->GetName();
1568 // #i121863# re-create original name of style used at page where to replace with
1569 // this new style
1570 OUString aTemp(pMySheet->GetName());
1571 const sal_Int32 nPos(aTemp.indexOf(SD_LT_SEPARATOR));
1572 aTemp = aOldLayoutName + aTemp.subView(nPos);
1573 aReplData.aName = aTemp;
1574 aReplList.push_back(aReplData);
1577 pHisSheet = pSourceStyleSheetPool->Next();
1580 // If new styles were created: re-create parent chaining of the item
1581 // sets in the styles.
1582 if(!aCreatedStyles.empty())
1584 for ( const auto& rRData : aReplList )
1586 SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(rRData.aName, SfxStyleFamily::Page);
1587 SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(rRData.aNewName, SfxStyleFamily::Page);
1589 if (pSOld && pSNew)
1591 const OUString& rParentOfOld = pSOld->GetParent();
1592 const OUString& rParentOfNew = pSNew->GetParent();
1594 if (!rParentOfOld.isEmpty() && rParentOfNew.isEmpty())
1596 std::vector<StyleReplaceData>::iterator pRDIter = std::find_if(aReplList.begin(), aReplList.end(),
1597 [&rParentOfOld](const StyleReplaceData& rRD) { return (rRD.aName == rParentOfOld) && (rRD.aName != rRD.aNewName); });
1598 if (pRDIter != aReplList.end())
1600 OUString aParentOfNew(pRDIter->aNewName);
1601 pSNew->SetParent(aParentOfNew);
1608 if (bUndo && !aCreatedStyles.empty())
1610 // Add UndoAction for creating and inserting the stylesheets to
1611 // the top of the UndoManager
1612 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>( this, aCreatedStyles, true));
1616 // Create layout name based upon the name of the page layout of the
1617 // master page
1618 OUString aPageLayoutName(pMaster->GetLayoutName());
1619 OUString aLayoutName = aPageLayoutName;
1620 sal_Int32 nIndex2 = aLayoutName.indexOf( SD_LT_SEPARATOR );
1621 if( nIndex2 != -1 )
1622 aLayoutName = aLayoutName.copy( 0, nIndex2);
1624 // #i121863# Do *not* remove from original document any longer, it is potentially used there
1625 // and would lead to crashes. Rely on the automatic process of removing unused masterpages
1626 // (see RemoveUnnecessaryMasterPages)
1627 //if (pSourceDoc != this)
1629 // // Remove from the source document
1630 // pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1631 // pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1634 // Register the new master pages with the document and then use
1635 // the new presentation layout for the default and notes pages
1636 if (pSourceDoc != this)
1638 // Insert the master pages:
1639 // Insert master pages from new layouts at the end.
1640 // If a layout is being replaced, however, insert them before the
1641 // position of the old master page, so from now on the new master
1642 // page will be found when searching (e.g.
1643 // SdPage::SetPresentationLayout).
1644 sal_uInt16 nInsertPos = rOldMaster.GetPageNum();
1645 BegUndo();
1647 if (!bLayoutReloaded)
1648 nInsertPos = 0xFFFF;
1649 InsertMasterPage(pMaster, nInsertPos);
1650 if( bUndo )
1651 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1653 nInsertPos++;
1654 if (!bLayoutReloaded)
1655 nInsertPos = 0xFFFF;
1656 InsertMasterPage(pNotesMaster, nInsertPos);
1657 if( bUndo )
1659 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1661 EndUndo(); // do this here already, so Joe's actions happen _between_ our own.
1665 // Fill list with pages
1666 std::vector<SdPage*> aPageList;
1668 // #98456, this has to be removed according to CL (KA 07/08/2002)
1669 // #109884# but we need them again to restore the styles of the presentation objects while undo
1670 aPageList.push_back(pMaster);
1671 aPageList.push_back(pNotesMaster);
1673 if (bMaster || bLayoutReloaded)
1675 for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1677 SdPage* pPage = static_cast<SdPage*>( GetPage(nPage) );
1678 OUString aTest = pPage->GetLayoutName();
1679 if (aTest == aOldPageLayoutName)
1681 aPageList.push_back(pPage);
1686 else
1688 aPageList.push_back(pSelectedPage);
1689 aPageList.push_back(pNotes);
1692 for (SdPage* pPage : aPageList)
1694 AutoLayout eAutoLayout = pPage->GetAutoLayout();
1696 if( bUndo )
1698 pUndoMgr->AddUndoAction(std::make_unique<SdPresentationLayoutUndoAction>
1699 (this,
1700 pPage->IsMasterPage() ? aLayoutName : aOldLayoutName,
1701 aLayoutName,
1702 eAutoLayout, eAutoLayout, false, pPage));
1704 pPage->SetPresentationLayout(aLayoutName);
1705 pPage->SetAutoLayout(eAutoLayout);
1708 // Adapt new master pages
1709 if (pSourceDoc != this)
1711 Size aSize(rOldMaster.GetSize());
1712 ::tools::Rectangle aBorderRect(rOldMaster.GetLeftBorder(),
1713 rOldMaster.GetUpperBorder(),
1714 rOldMaster.GetRightBorder(),
1715 rOldMaster.GetLowerBorder());
1716 pMaster->ScaleObjects(aSize, aBorderRect, true);
1717 pMaster->SetSize(aSize);
1718 pMaster->SetBorder(rOldMaster.GetLeftBorder(),
1719 rOldMaster.GetUpperBorder(),
1720 rOldMaster.GetRightBorder(),
1721 rOldMaster.GetLowerBorder());
1722 pMaster->SetOrientation( rOldMaster.GetOrientation() );
1723 pMaster->SetAutoLayout(pMaster->GetAutoLayout());
1725 aSize = rOldNotesMaster.GetSize();
1726 ::tools::Rectangle aNotesBorderRect(rOldNotesMaster.GetLeftBorder(),
1727 rOldNotesMaster.GetUpperBorder(),
1728 rOldNotesMaster.GetRightBorder(),
1729 rOldNotesMaster.GetLowerBorder());
1730 pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, true);
1731 pNotesMaster->SetSize(aSize);
1732 pNotesMaster->SetBorder(rOldNotesMaster.GetLeftBorder(),
1733 rOldNotesMaster.GetUpperBorder(),
1734 rOldNotesMaster.GetRightBorder(),
1735 rOldNotesMaster.GetLowerBorder());
1736 pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() );
1737 pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout());
1739 if( (pSourceDoc->GetDocumentType() == DocumentType::Impress) &&
1740 (GetDocumentType() == DocumentType::Draw) )
1742 pMaster->RemoveEmptyPresentationObjects();
1743 pNotesMaster->RemoveEmptyPresentationObjects();
1747 else
1749 // Find a new name for the layout
1750 OUString aName(createNewMasterPageLayoutName(*this));
1751 OUString aPageLayoutName(aName + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE);
1753 // Generate new stylesheets
1754 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName);
1755 SdStyleSheetVector aCreatedStyles;
1756 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles);
1758 if( bUndo )
1760 StyleSheetCopyResultVector aUndoInsert;
1761 aUndoInsert.reserve(aCreatedStyles.size());
1762 for (const auto& a : aCreatedStyles)
1763 aUndoInsert.emplace_back(a.get(), true);
1764 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aUndoInsert, true));
1765 // Generate new master pages and register them with the document
1766 BegUndo();
1769 pMaster = AllocSdPage(true);
1770 pMaster->SetSize(pSelectedPage->GetSize());
1771 pMaster->SetBorder(pSelectedPage->GetLeftBorder(),
1772 pSelectedPage->GetUpperBorder(),
1773 pSelectedPage->GetRightBorder(),
1774 pSelectedPage->GetLowerBorder() );
1775 pMaster->SetName(aName);
1776 pMaster->SetLayoutName(aPageLayoutName);
1777 InsertMasterPage(pMaster);
1779 if( bUndo )
1780 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1782 pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
1784 pNotesMaster = AllocSdPage(true);
1785 pNotesMaster->SetPageKind(PageKind::Notes);
1786 pNotesMaster->SetSize(pNotes->GetSize());
1787 pNotesMaster->SetBorder(pNotes->GetLeftBorder(),
1788 pNotes->GetUpperBorder(),
1789 pNotes->GetRightBorder(),
1790 pNotes->GetLowerBorder() );
1791 pNotesMaster->SetName(aName);
1792 pNotesMaster->SetLayoutName(aPageLayoutName);
1793 InsertMasterPage(pNotesMaster);
1795 if( bUndo )
1796 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1798 pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
1800 if( bUndo )
1801 EndUndo();
1803 // Create a list of affected default and notes pages
1804 std::vector<SdPage*> aPageList;
1805 if (bMaster)
1807 for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1809 SdPage* pPage = static_cast<SdPage*>( GetPage(nPage) );
1810 if (pPage->GetLayoutName() == aOldPageLayoutName)
1812 aPageList.push_back(pPage);
1816 else
1818 aPageList.push_back(pSelectedPage);
1819 aPageList.push_back(pNotes);
1822 // Set presentation layout and AutoLayout for the affected pages
1823 for ( auto& rpPage : aPageList )
1825 AutoLayout eOldAutoLayout = rpPage->GetAutoLayout();
1826 AutoLayout eNewAutoLayout =
1827 rpPage->GetPageKind() == PageKind::Standard ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES;
1829 if( bUndo )
1831 pUndoMgr->AddUndoAction(std::make_unique<SdPresentationLayoutUndoAction>
1832 (this, aOldLayoutName, aName,
1833 eOldAutoLayout, eNewAutoLayout, true,
1834 rpPage));
1837 rpPage->SetPresentationLayout(aName);
1838 rpPage->SetAutoLayout(eNewAutoLayout);
1842 // If the old master pages aren't used anymore, they and their styles have
1843 // to be removed.
1844 if (bCheckMasters)
1846 // Check all
1847 RemoveUnnecessaryMasterPages();
1849 else
1851 // Check only the master page that was replaced
1852 RemoveUnnecessaryMasterPages(&rOldMaster);
1855 if( bUndo )
1856 pUndoMgr->LeaveListAction();
1858 if( mpDocSh )
1859 mpDocSh->SetWaitCursor( false );
1862 void SdDrawDocument::Merge(SdrModel& rSourceModel,
1863 sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1864 sal_uInt16 nDestPos,
1865 bool bMergeMasterPages, bool bAllMasterPages,
1866 bool bUndo, bool bTreadSourceAsConst)
1868 sal_uInt16 nMasterPageCount = GetMasterPageCount();
1869 SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst );
1871 // add style family for each new master page
1872 for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ )
1874 SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) );
1875 if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PageKind::Standard) )
1877 // new master page created, add its style family
1878 SdStyleSheetPool* pStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
1879 if( pStylePool )
1880 pStylePool->AddStyleFamily( pPage );
1885 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */