LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sd / source / core / drawdoc3.cxx
blob79f22b4eb864365f82c70cdc05f955f18e029602
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>
29 #include <tools/diagnose_ex.h>
31 #include <sfx2/fcontnr.hxx>
32 #include <svl/style.hxx>
33 #include <svx/svdpagv.hxx>
34 #include <svx/svdundo.hxx>
35 #include <vcl/stdtext.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/weld.hxx>
38 #include <xmloff/autolayout.hxx>
40 #include <strings.hrc>
41 #include <drawdoc.hxx>
42 #include <sdmod.hxx>
43 #include <sdpage.hxx>
44 #include <stlpool.hxx>
45 #include <sdresid.hxx>
46 #include <customshowlist.hxx>
47 #include <sdxfer.hxx>
49 #include <unmovss.hxx>
50 #include <unchss.hxx>
51 #include <unprlout.hxx>
52 #include <DrawDocShell.hxx>
53 #include <GraphicDocShell.hxx>
54 #include <ViewShell.hxx>
55 #include <View.hxx>
56 #include <ViewShellBase.hxx>
57 #include <strings.hxx>
59 using namespace ::com::sun::star;
61 /** Concrete incarnations get called by lcl_IterateBookmarkPages, for
62 every page in the bookmark document/list
65 namespace {
67 class InsertBookmarkAsPage_FindDuplicateLayouts
69 public:
70 explicit InsertBookmarkAsPage_FindDuplicateLayouts( std::vector<OUString> &rLayoutsToTransfer )
71 : mrLayoutsToTransfer(rLayoutsToTransfer) {}
72 void operator()( SdDrawDocument&, SdPage const *, bool, SdDrawDocument* );
73 private:
74 std::vector<OUString> &mrLayoutsToTransfer;
79 void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage const * pBMMPage, bool bRenameDuplicates, SdDrawDocument* pBookmarkDoc )
81 // now check for duplicate masterpage and layout names
83 OUString aLayout( pBMMPage->GetLayoutName() );
84 sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR );
85 if( nIndex != -1 )
86 aLayout = aLayout.copy(0, nIndex);
88 std::vector<OUString>::const_iterator pIter =
89 find(mrLayoutsToTransfer.begin(),mrLayoutsToTransfer.end(),aLayout);
91 bool bFound = pIter != mrLayoutsToTransfer.end();
93 const sal_uInt16 nMPageCount = rDoc.GetMasterPageCount();
94 for (sal_uInt16 nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++)
96 // Do the layouts already exist within the document?
97 SdPage* pTestPage = static_cast<SdPage*>( rDoc.GetMasterPage(nMPage) );
98 OUString aTest(pTestPage->GetLayoutName());
99 sal_Int32 nIndex2 = aTest.indexOf( SD_LT_SEPARATOR );
100 if( nIndex2 != -1 )
101 aTest = aTest.copy(0, nIndex2);
103 if (aTest == aLayout && pBMMPage->GetPageKind() == pTestPage->GetPageKind())
105 // Ignore Layouts with "Default" these seem to be special - in the sense that there are lot of assumption all over Impress
106 // about this
107 if( bRenameDuplicates && aTest != SdResId( STR_LAYOUT_DEFAULT_NAME ) && !(pTestPage->Equals(*pBMMPage)) )
109 pBookmarkDoc->RenameLayoutTemplate(
110 pBMMPage->GetLayoutName(), pBMMPage->GetName() + "_");
111 aLayout = pBMMPage->GetName();
113 break;
115 else
116 bFound = true;
120 if (!bFound)
121 mrLayoutsToTransfer.push_back(aLayout);
124 // Inserts a bookmark as a page
125 static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBookmarkDoc,
126 const std::vector<OUString> &rBookmarkList, sal_uInt16 nBMSdPageCount,
127 InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator, bool bRenameDuplicates )
130 // Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage
132 int nPos, nEndPos;
134 if( rBookmarkList.empty() )
136 // no list? whole source document
137 nEndPos = nBMSdPageCount;
139 else
141 // bookmark list? number of entries
142 nEndPos = rBookmarkList.size();
145 SdPage* pBMPage;
147 // iterate over number of pages to insert
148 for (nPos = 0; nPos < nEndPos; ++nPos)
150 // the master page associated to the nPos'th page to insert
151 SdPage* pBMMPage = nullptr;
153 if( rBookmarkList.empty() )
155 // simply take master page of nPos'th page in source document
156 pBMMPage = static_cast<SdPage*>(&(pBookmarkDoc->GetSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard)->TRG_GetMasterPage()));
158 else
160 // fetch nPos'th entry from bookmark list, and determine master page
161 OUString aBMPgName(rBookmarkList[nPos]);
162 bool bIsMasterPage;
164 sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage );
166 if (nBMPage != SDRPAGE_NOTFOUND)
168 pBMPage = static_cast<SdPage*>( pBookmarkDoc->GetPage(nBMPage) );
170 else
172 pBMPage = nullptr;
175 // enforce that bookmarked page is a standard page and not already a master page
176 if (pBMPage && pBMPage->GetPageKind()==PageKind::Standard && !pBMPage->IsMasterPage())
178 const sal_uInt16 nBMSdPage = (nBMPage - 1) / 2;
179 pBMMPage = static_cast<SdPage*> (&(pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard)->TRG_GetMasterPage()));
183 // successfully determined valid (bookmarked) page?
184 if( pBMMPage )
186 // yes, call functor
187 rPageIterator( rDoc, pBMMPage, bRenameDuplicates, pBookmarkDoc );
192 // Opens a bookmark document
193 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(SfxMedium* pMedium)
195 bool bOK = true;
196 SdDrawDocument* pBookmarkDoc = nullptr;
197 OUString aBookmarkName = pMedium->GetName();
198 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
199 if ( !pFilter )
201 pMedium->UseInteractionHandler( true );
202 SfxGetpApp()->GetFilterMatcher().GuessFilter(*pMedium, pFilter);
205 if ( !pFilter )
207 bOK = false;
209 else if ( !aBookmarkName.isEmpty() && maBookmarkFile != aBookmarkName )
211 bool bCreateGraphicShell = pFilter->GetServiceName() == "com.sun.star.drawing.DrawingDocument";
212 bool bCreateImpressShell = pFilter->GetServiceName() == "com.sun.star.presentation.PresentationDocument";
213 if ( bCreateGraphicShell || bCreateImpressShell )
215 CloseBookmarkDoc();
217 // Create a DocShell, as OLE objects might be contained in the
218 // document. (Persist)
219 // If that wasn't the case, we could load the model directly.
220 if ( bCreateGraphicShell )
221 // Draw
222 mxBookmarkDocShRef = new ::sd::GraphicDocShell(SfxObjectCreateMode::STANDARD);
223 else
224 // Impress
225 mxBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress);
227 bOK = mxBookmarkDocShRef->DoLoad(pMedium);
228 if( bOK )
230 maBookmarkFile = aBookmarkName;
231 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
236 DBG_ASSERT(!aBookmarkName.isEmpty(), "Empty document name!");
238 if (!bOK)
240 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr,
241 VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
242 xErrorBox->run();
244 CloseBookmarkDoc();
245 pBookmarkDoc = nullptr;
247 else if (mxBookmarkDocShRef.is())
249 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
252 return pBookmarkDoc;
255 // Opens a bookmark document
256 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(const OUString& rBookmarkFile)
258 SdDrawDocument* pBookmarkDoc = nullptr;
260 if (!rBookmarkFile.isEmpty() && maBookmarkFile != rBookmarkFile)
262 std::unique_ptr<SfxMedium> xMedium(new SfxMedium(rBookmarkFile, StreamMode::READ));
263 pBookmarkDoc = OpenBookmarkDoc(xMedium.release());
265 else if (mxBookmarkDocShRef.is())
267 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
270 return pBookmarkDoc;
273 // Inserts a bookmark (page or object)
274 void SdDrawDocument::InsertBookmark(
275 const std::vector<OUString> &rBookmarkList, // List of names of the bookmarks to be inserted
276 std::vector<OUString> &rExchangeList, // List of the names to be used
277 bool bLink, // Insert bookmarks as links?
278 sal_uInt16 nInsertPos, // Insertion position of pages
279 ::sd::DrawDocShell* pBookmarkDocSh, // If set, this is the source document
280 Point const * pObjPos) // Insertion position of objects
282 bool bOK = true;
283 bool bInsertPages = false;
285 if (rBookmarkList.empty())
287 // Insert all pages
288 bInsertPages = true;
290 else
292 SdDrawDocument* pBookmarkDoc = nullptr;
294 if (pBookmarkDocSh)
296 pBookmarkDoc = pBookmarkDocSh->GetDoc();
298 else if ( mxBookmarkDocShRef.is() )
300 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
302 else
303 bOK = false;
305 bInsertPages = bOK && std::any_of(rBookmarkList.begin(), rBookmarkList.end(),
306 [&pBookmarkDoc](const OUString& rBookmark) {
307 // Is there a page name in the bookmark list?
308 bool bIsMasterPage;
309 return pBookmarkDoc->GetPageByName(rBookmark, bIsMasterPage) != SDRPAGE_NOTFOUND;
313 bool bCalcObjCount = !rExchangeList.empty();
315 if ( bOK && bInsertPages )
317 // Insert all page bookmarks
318 bOK = InsertBookmarkAsPage(rBookmarkList, &rExchangeList, bLink, false/*bReplace*/,
319 nInsertPos, false/*bNoDialogs*/, pBookmarkDocSh, true/*bCopy*/, true, false);
322 if ( bOK && !rBookmarkList.empty() )
324 // Insert all object bookmarks
325 InsertBookmarkAsObject(rBookmarkList, rExchangeList,
326 pBookmarkDocSh, pObjPos, bCalcObjCount);
330 namespace
333 void
334 lcl_removeUnusedStyles(SfxStyleSheetBasePool* const pStyleSheetPool, StyleSheetCopyResultVector& rStyles)
336 StyleSheetCopyResultVector aUsedStyles;
337 aUsedStyles.reserve(rStyles.size());
338 for (const auto& a : rStyles)
340 if (a.m_xStyleSheet->IsUsed())
341 aUsedStyles.push_back(a);
342 else
343 pStyleSheetPool->Remove(a.m_xStyleSheet.get());
345 rStyles = aUsedStyles;
348 SfxStyleSheet *lcl_findStyle(StyleSheetCopyResultVector& rStyles, std::u16string_view aStyleName)
350 for (const auto& a : rStyles)
352 if (a.m_xStyleSheet->GetName().startsWith(aStyleName))
353 return a.m_xStyleSheet.get();
355 return nullptr;
360 bool SdDrawDocument::InsertBookmarkAsPage(
361 const std::vector<OUString> &rBookmarkList,
362 std::vector<OUString> *pExchangeList, // List of names to be used
363 bool bLink,
364 bool bReplace,
365 sal_uInt16 nInsertPos,
366 bool bNoDialogs,
367 ::sd::DrawDocShell* pBookmarkDocSh,
368 bool bCopy,
369 bool bMergeMasterPages,
370 bool bPreservePageNames)
372 bool bContinue = true;
373 bool bScaleObjects = false;
374 sal_uInt16 nReplacedStandardPages = 0;
376 SdDrawDocument* pBookmarkDoc = nullptr;
377 OUString aBookmarkName;
379 if (pBookmarkDocSh)
381 pBookmarkDoc = pBookmarkDocSh->GetDoc();
383 if (pBookmarkDocSh->GetMedium())
385 aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
388 else if ( mxBookmarkDocShRef.is() )
390 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
391 aBookmarkName = maBookmarkFile;
393 else
395 return false;
398 const sal_uInt16 nSdPageCount = GetSdPageCount(PageKind::Standard);
399 const sal_uInt16 nBMSdPageCount = pBookmarkDoc->GetSdPageCount(PageKind::Standard);
400 const sal_uInt16 nMPageCount = GetMasterPageCount();
402 if (nSdPageCount==0 || nBMSdPageCount==0 || nMPageCount==0)
404 return false;
407 // Store the size and some other properties of the first page and notes
408 // page so that inserted pages can be properly scaled even when inserted
409 // before the first page.
410 // Note that the pointers are used later on as general page pointers.
411 SdPage* pRefPage = GetSdPage(0, PageKind::Standard);
412 Size aSize(pRefPage->GetSize());
413 sal_Int32 nLeft = pRefPage->GetLeftBorder();
414 sal_Int32 nRight = pRefPage->GetRightBorder();
415 sal_Int32 nUpper = pRefPage->GetUpperBorder();
416 sal_Int32 nLower = pRefPage->GetLowerBorder();
417 Orientation eOrient = pRefPage->GetOrientation();
419 SdPage* pNPage = GetSdPage(0, PageKind::Notes);
420 Size aNSize(pNPage->GetSize());
421 sal_Int32 nNLeft = pNPage->GetLeftBorder();
422 sal_Int32 nNRight = pNPage->GetRightBorder();
423 sal_Int32 nNUpper = pNPage->GetUpperBorder();
424 sal_Int32 nNLower = pNPage->GetLowerBorder();
425 Orientation eNOrient = pNPage->GetOrientation();
427 // Adapt page size and margins to those of the later pages?
428 pRefPage = GetSdPage(nSdPageCount - 1, PageKind::Standard);
430 if( bNoDialogs )
432 // If this is clipboard, then no need to scale objects:
433 // this will make copied masters to differ from the originals,
434 // and thus InsertBookmarkAsPage_FindDuplicateLayouts will
435 // duplicate masters on insert to same document
436 m_bTransportContainer = (SD_MOD()->pTransferClip &&
437 SD_MOD()->pTransferClip->GetWorkDocument() == this);
438 if (!m_bTransportContainer)
440 if (rBookmarkList.empty())
441 bScaleObjects = pRefPage->IsScaleObjects();
442 else
443 bScaleObjects = true;
446 else
448 SdPage* pBMPage = pBookmarkDoc->GetSdPage(0,PageKind::Standard);
450 if (pBMPage->GetSize() != pRefPage->GetSize() ||
451 pBMPage->GetLeftBorder() != pRefPage->GetLeftBorder() ||
452 pBMPage->GetRightBorder() != pRefPage->GetRightBorder() ||
453 pBMPage->GetUpperBorder() != pRefPage->GetUpperBorder() ||
454 pBMPage->GetLowerBorder() != pRefPage->GetLowerBorder())
456 OUString aStr(SdResId(STR_SCALE_OBJECTS));
457 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr,
458 VclMessageType::Question, VclButtonsType::YesNo,
459 aStr));
460 xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
461 sal_uInt16 nBut = xQueryBox->run();
463 bScaleObjects = nBut == RET_YES;
464 bContinue = nBut != RET_CANCEL;
466 if (!bContinue)
468 return bContinue;
473 // Get the necessary presentation stylesheets and transfer them before
474 // the pages, else, the text objects won't reference their styles anymore.
475 SfxUndoManager* pUndoMgr = nullptr;
476 if( mpDocSh )
478 pUndoMgr = mpDocSh->GetUndoManager();
479 ViewShellId nViewShellId(-1);
480 if (sd::ViewShell* pViewShell = mpDocSh->GetViewShell())
481 nViewShellId = pViewShell->GetViewShellBase().GetViewShellId();
482 pUndoMgr->EnterListAction(SdResId(STR_UNDO_INSERTPAGES), "", 0, nViewShellId);
485 // Refactored copy'n'pasted layout name collection into IterateBookmarkPages
487 std::vector<OUString> aLayoutsToTransfer;
488 InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor( aLayoutsToTransfer );
489 lcl_IterateBookmarkPages( *this, pBookmarkDoc, rBookmarkList, nBMSdPageCount, aSearchFunctor, ( rBookmarkList.empty() && pBookmarkDoc != this ) );
491 // Copy the style that we actually need.
492 SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*pBookmarkDoc->GetStyleSheetPool());
493 SdStyleSheetPool& rStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*GetStyleSheetPool());
495 // When copying styles, also copy the master pages!
496 if( !aLayoutsToTransfer.empty() )
497 bMergeMasterPages = true;
499 for ( const OUString& layoutName : aLayoutsToTransfer )
501 StyleSheetCopyResultVector aCreatedStyles;
503 rStyleSheetPool.CopyLayoutSheets(layoutName, rBookmarkStyleSheetPool,aCreatedStyles);
505 if(!aCreatedStyles.empty())
507 if( pUndoMgr )
509 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aCreatedStyles, true));
514 // Copy styles. This unconditionally copies all styles, even those
515 // that are not used in any of the inserted pages. The unused styles
516 // are then removed at the end of the function, where we also create
517 // undo records for the inserted styles.
518 StyleSheetCopyResultVector aNewGraphicStyles;
519 OUString aRenameStr;
520 if(!bReplace && !bNoDialogs)
521 aRenameStr = "_";
522 rStyleSheetPool.RenameAndCopyGraphicSheets(rBookmarkStyleSheetPool, aNewGraphicStyles, aRenameStr);
523 StyleSheetCopyResultVector aNewCellStyles;
524 rStyleSheetPool.CopyCellSheets(rBookmarkStyleSheetPool, aNewCellStyles);
526 // TODO handle undo of table styles too
527 rStyleSheetPool.CopyTableStyles(rBookmarkStyleSheetPool);
529 // Insert document
531 const bool bUndo = IsUndoEnabled();
533 if( bUndo )
534 BegUndo(SdResId(STR_UNDO_INSERTPAGES));
536 if (rBookmarkList.empty())
538 if (nInsertPos >= GetPageCount())
540 // Add pages to the end
541 nInsertPos = GetPageCount();
544 sal_uInt16 nActualInsertPos = nInsertPos;
546 sal_uInt16 nBMSdPage;
547 std::set<sal_uInt16> aRenameSet;
548 std::map<sal_uInt16,OUString> aNameMap;
550 for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
552 SdPage* pBMPage = pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard);
553 OUString sName(pBMPage->GetName());
554 bool bIsMasterPage;
556 if (bLink)
558 // Remember the names of all pages
559 aNameMap.insert(std::make_pair(nBMSdPage,sName));
562 // Have to check for duplicate names here, too
563 // don't change name if source and dest model are the same!
564 if( pBookmarkDoc != this &&
565 GetPageByName(sName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
567 // delay renaming *after* pages are copied (might destroy source otherwise)
568 aRenameSet.insert(nBMSdPage);
572 Merge(*pBookmarkDoc,
573 1, // Not the handout page
574 0xFFFF, // But all others
575 nActualInsertPos, // Insert at position ...
576 bMergeMasterPages, // Move master pages?
577 false, // But only the master pages used
578 true, // Create an undo action
579 bCopy); // Copy (or merge) pages?
581 for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
583 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
584 SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) );
586 // delay renaming *after* pages are copied (might destroy source otherwise)
587 if( aRenameSet.find(nBMSdPage) != aRenameSet.end() )
589 // Page name already in use -> Use default name for default and
590 // notes page
591 pPage->SetName(OUString());
592 pNotesPage->SetName(OUString());
595 if (bLink)
597 OUString aName(aNameMap[nBMSdPage]);
599 // Assemble all link names
600 pPage->SetFileName(aBookmarkName);
601 pPage->SetBookmarkName(aName);
604 nActualInsertPos += 2;
607 else
609 // Insert selected pages
610 SdPage* pBMPage;
612 if (nInsertPos >= GetPageCount())
614 // Add pages to the end
615 bReplace = false;
616 nInsertPos = GetPageCount();
619 sal_uInt16 nActualInsertPos = nInsertPos;
621 // Collect the bookmarked pages
622 ::std::vector<SdPage*> aBookmarkedPages (rBookmarkList.size(), nullptr);
623 for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos)
625 OUString aPgName(rBookmarkList[nPos]);
626 bool bIsMasterPage;
627 sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage );
629 if (nBMPage != SDRPAGE_NOTFOUND)
631 aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(pBookmarkDoc->GetPage(nBMPage));
635 for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos)
637 pBMPage = aBookmarkedPages[nPos];
638 sal_uInt16 nBMPage = pBMPage!=nullptr ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND;
640 if (pBMPage && pBMPage->GetPageKind()==PageKind::Standard && !pBMPage->IsMasterPage())
642 // It has to be a default page
643 bool bMustRename = false;
645 // delay renaming *after* pages are copied (might destroy source otherwise)
646 // don't change name if source and dest model are the same!
647 // avoid renaming if replacing the same page
648 OUString aPgName(rBookmarkList[nPos]);
649 bool bIsMasterPage;
650 sal_uInt16 nPageSameName = GetPageByName(aPgName, bIsMasterPage);
651 if( pBookmarkDoc != this &&
652 nPageSameName != SDRPAGE_NOTFOUND &&
653 ( !bReplace ||
654 nPageSameName != nActualInsertPos ) )
656 bMustRename = true;
659 SdPage* pBookmarkPage = pBMPage;
660 if (bReplace )
662 ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage );
665 Merge(*pBookmarkDoc,
666 nBMPage, // From page (default page)
667 nBMPage+1, // To page (notes page)
668 nActualInsertPos, // Insert at position
669 bMergeMasterPages, // Move master pages?
670 false, // But only the master pages used
671 true, // Create undo action
672 bCopy); // Copy (or merge) pages?
674 if( bReplace )
676 if( GetPage( nActualInsertPos ) != pBookmarkPage )
678 // bookmark page was not moved but cloned, so update custom shows again
679 ReplacePageInCustomShows( pBookmarkPage, dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ) );
683 if( bMustRename )
685 // Page name already in use -> use default name for default and
686 // notes page
687 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
688 pPage->SetName(OUString());
689 SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) );
690 pNotesPage->SetName(OUString());
693 if (bLink)
695 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
696 pPage->SetFileName(aBookmarkName);
697 pPage->SetBookmarkName(aPgName);
700 if (bReplace)
702 // Remove page and notes page.
703 const sal_uInt16 nDestPageNum(nActualInsertPos + 2);
704 SdPage* pStandardPage = nullptr;
706 if(nDestPageNum < GetPageCount())
708 pStandardPage = static_cast<SdPage*>(GetPage(nDestPageNum));
711 if (pStandardPage)
713 if( bPreservePageNames )
715 // Take old slide names for inserted pages
716 SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
717 pPage->SetName( pStandardPage->GetRealName() );
720 if( bUndo )
721 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage));
723 RemovePage(nDestPageNum);
726 SdPage* pNotesPage = nullptr;
728 if(nDestPageNum < GetPageCount())
730 pNotesPage = static_cast<SdPage*>(GetPage(nDestPageNum));
733 if (pNotesPage)
735 if( bPreservePageNames )
737 // Take old slide names for inserted pages
738 SdPage* pNewNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1));
739 if( pNewNotesPage )
740 pNewNotesPage->SetName( pStandardPage->GetRealName() );
743 if( bUndo )
744 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
746 RemovePage(nDestPageNum);
749 nReplacedStandardPages++;
752 nActualInsertPos += 2;
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();
761 // Go backwards, so the numbers don't become messed up
762 for (sal_uInt16 nPage = nNewMPageCount - 1; nPage >= nMPageCount; nPage--)
764 pRefPage = static_cast<SdPage*>( GetMasterPage(nPage) );
765 OUString aMPLayout(pRefPage->GetLayoutName());
766 PageKind eKind = pRefPage->GetPageKind();
768 // Does this already exist?
769 for (sal_uInt16 nTest = 0; nTest < nMPageCount; nTest++)
771 SdPage* pTest = static_cast<SdPage*>( GetMasterPage(nTest) );
772 OUString aTest(pTest->GetLayoutName());
774 // nInsertPos > 2 is always true when inserting into non-empty models
775 if ( nInsertPos > 2 &&
776 aTest == aMPLayout &&
777 eKind == pTest->GetPageKind() )
779 if( bUndo )
780 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage));
782 RemoveMasterPage(nPage);
784 nNewMPageCount--;
785 break;
790 // nInsertPos > 2 is always true when inserting into non-empty models
791 if (nInsertPos > 0)
793 sal_uInt16 nSdPageStart = (nInsertPos - 1) / 2;
794 sal_uInt16 nSdPageEnd = bReplace
795 ? nSdPageStart + nReplacedStandardPages - 1
796 : GetSdPageCount(PageKind::Standard) - nSdPageCount + nSdPageStart - 1;
797 const bool bRemoveEmptyPresObj =
798 (pBookmarkDoc->GetDocumentType() == DocumentType::Impress) &&
799 (GetDocumentType() == DocumentType::Draw);
801 std::vector<OUString>::iterator pExchangeIter;
803 if (pExchangeList)
804 pExchangeIter = pExchangeList->begin();
806 for (sal_uInt16 nSdPage = nSdPageStart; nSdPage <= nSdPageEnd; nSdPage++)
808 pRefPage = GetSdPage(nSdPage, PageKind::Standard);
810 if (pExchangeList && pExchangeIter != pExchangeList->end())
812 // Get the name to use from Exchange list
813 OUString aExchangeName(*pExchangeIter);
814 pRefPage->SetName(aExchangeName);
815 Broadcast(SdrHint(SdrHintKind::PageOrderChange, pRefPage));
817 SdPage* pNewNotesPage = GetSdPage(nSdPage, PageKind::Notes);
818 pNewNotesPage->SetName(aExchangeName);
819 Broadcast(SdrHint(SdrHintKind::PageOrderChange, pNewNotesPage));
821 ++pExchangeIter;
824 OUString aLayout(pRefPage->GetLayoutName());
825 sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR );
826 if( nIndex != -1 )
827 aLayout = aLayout.copy(0, nIndex);
829 // update layout and referred master page
830 pRefPage->SetPresentationLayout(aLayout);
831 if( bUndo )
832 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
834 if (bScaleObjects)
836 ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
837 pRefPage->ScaleObjects(aSize, aBorderRect, true);
839 pRefPage->SetSize(aSize);
840 pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
841 pRefPage->SetOrientation( eOrient );
843 if( bRemoveEmptyPresObj )
844 pRefPage->RemoveEmptyPresentationObjects();
846 pRefPage = GetSdPage(nSdPage, PageKind::Notes);
848 // update layout and referred master page
849 pRefPage->SetPresentationLayout(aLayout);
850 if( bUndo )
851 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
853 if (bScaleObjects)
855 ::tools::Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
856 pRefPage->ScaleObjects(aNSize, aBorderRect, true);
859 pRefPage->SetSize(aNSize);
860 pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
861 pRefPage->SetOrientation( eNOrient );
863 if( bRemoveEmptyPresObj )
864 pRefPage->RemoveEmptyPresentationObjects();
867 ///Remove processed elements, to avoid doing hacks in InsertBookmarkAsObject
868 if ( pExchangeList )
869 pExchangeList->erase(pExchangeList->begin(),pExchangeIter);
871 for (sal_uInt16 nPage = nMPageCount; nPage < nNewMPageCount; nPage++)
873 pRefPage = static_cast<SdPage*>( GetMasterPage(nPage) );
874 if (pRefPage->GetPageKind() == PageKind::Standard)
876 if (bScaleObjects)
878 ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
879 pRefPage->ScaleObjects(aSize, aBorderRect, true);
881 pRefPage->SetSize(aSize);
882 pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
883 pRefPage->SetOrientation( eOrient );
885 else // Can only be notes
887 if (bScaleObjects)
889 ::tools::Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
890 pRefPage->ScaleObjects(aNSize, aBorderRect, true);
892 pRefPage->SetSize(aNSize);
893 pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
894 pRefPage->SetOrientation( eNOrient );
897 if( bRemoveEmptyPresObj )
898 pRefPage->RemoveEmptyPresentationObjects();
902 // Make absolutely sure no double masterpages are there
903 RemoveUnnecessaryMasterPages(nullptr, true);
905 // Rename object styles if necessary
906 if(!aRenameStr.isEmpty())
910 for(sal_uInt32 p = nInsertPos; p < sal_uInt32(nInsertPos) + sal_uInt32(nBMSdPageCount); p++)
912 SdPage *pPg = static_cast<SdPage *>( GetPage(p) );
913 for(size_t i = 0; pPg && (i < pPg->GetObjCount()); ++i)
915 if(pPg->GetObj(i)->GetStyleSheet())
917 OUString aStyleName = pPg->GetObj(i)->GetStyleSheet()->GetName();
918 SfxStyleSheet *pSheet = lcl_findStyle(aNewGraphicStyles, OUStringConcatenation(aStyleName + aRenameStr));
919 if(pSheet != nullptr)
920 pPg->GetObj(i)->SetStyleSheet(pSheet, true);
925 catch(...)
927 TOOLS_WARN_EXCEPTION( "sd", "Exception while renaming styles @ SdDrawDocument::InsertBookmarkAsPage");
930 // remove copied styles not used on any inserted page and create
931 // undo records
932 // WARNING: SdMoveStyleSheetsUndoAction clears the passed list of
933 // styles, so it cannot be used after this point
934 lcl_removeUnusedStyles(GetStyleSheetPool(), aNewGraphicStyles);
935 if (!aNewGraphicStyles.empty() && pUndoMgr)
936 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aNewGraphicStyles, true));
937 lcl_removeUnusedStyles(GetStyleSheetPool(), aNewCellStyles);
938 if (!aNewCellStyles.empty() && pUndoMgr)
939 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aNewCellStyles, true));
941 if( bUndo )
942 EndUndo();
944 if (pUndoMgr)
945 pUndoMgr->LeaveListAction();
947 return bContinue;
950 // Inserts a bookmark as an object
951 bool SdDrawDocument::InsertBookmarkAsObject(
952 const std::vector<OUString> &rBookmarkList,
953 const std::vector<OUString> &rExchangeList, // List of names to use
954 ::sd::DrawDocShell* pBookmarkDocSh,
955 Point const * pObjPos,
956 bool bCalcObjCount)
958 bool bOK = true;
959 bool bOLEObjFound = false;
960 std::unique_ptr<::sd::View> pBMView;
962 SdDrawDocument* pBookmarkDoc = nullptr;
964 if (pBookmarkDocSh)
966 pBookmarkDoc = pBookmarkDocSh->GetDoc();
968 else if ( mxBookmarkDocShRef.is() )
970 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
972 else
974 return false;
977 if (rBookmarkList.empty())
979 pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr));
980 pBMView->EndListening(*pBookmarkDoc);
981 pBMView->MarkAll();
983 else
985 SdrPage* pPage;
986 SdrPageView* pPV;
988 for ( const auto& rBookmark : rBookmarkList )
990 // Get names of bookmarks from the list
991 SdrObject* pObj = pBookmarkDoc->GetObj(rBookmark);
993 if (pObj)
995 // Found an object
996 if (pObj->GetObjInventor() == SdrInventor::Default &&
997 pObj->GetObjIdentifier() == OBJ_OLE2)
999 bOLEObjFound = true;
1002 if (!pBMView)
1004 // Create View for the first time
1005 pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr));
1006 pBMView->EndListening(*pBookmarkDoc);
1009 pPage = pObj->getSdrPageFromSdrObject();
1011 if (pPage->IsMasterPage())
1013 pPV = pBMView->ShowSdrPage(pBMView->GetModel()->GetMasterPage(pPage->GetPageNum()));
1015 else
1017 pPV = pBMView->GetSdrPageView();
1018 if( !pPV || (pPV->GetPage() != pPage))
1019 pPV = pBMView->ShowSdrPage(pPage);
1022 pBMView->MarkObj(pObj, pPV);
1027 if (pBMView)
1029 // Insert selected objects
1030 std::optional<::sd::View> pView(std::in_place, *this, nullptr);
1031 pView->EndListening(*this);
1033 // Look for the page into which the objects are supposed to be inserted
1034 SdrPage* pPage = GetSdPage(0, PageKind::Standard);
1036 if (mpDocSh)
1038 ::sd::ViewShell* pViewSh = mpDocSh->GetViewShell();
1040 if (pViewSh)
1042 // Which page is currently in view?
1043 SdrPageView* pPV = pViewSh->GetView()->GetSdrPageView();
1045 if (pPV)
1047 pPage = pPV->GetPage();
1049 else if (pViewSh->GetActualPage())
1051 pPage = pViewSh->GetActualPage();
1056 Point aObjPos;
1058 if (pObjPos)
1060 aObjPos = *pObjPos;
1062 else
1064 aObjPos = ::tools::Rectangle(Point(), pPage->GetSize()).Center();
1067 size_t nCountBefore = 0;
1069 if (!rExchangeList.empty() || bCalcObjCount)
1071 // Sort OrdNums and get the number of objects before inserting
1072 pPage->RecalcObjOrdNums();
1073 nCountBefore = pPage->GetObjCount();
1076 if (bOLEObjFound)
1077 pBMView->GetDoc().SetAllocDocSh(true);
1079 SdDrawDocument* pTmpDoc = static_cast<SdDrawDocument*>( pBMView->CreateMarkedObjModel().release() );
1080 bOK = pView->Paste(*pTmpDoc, aObjPos, pPage, SdrInsertFlags::NONE);
1082 if (bOLEObjFound)
1083 pBMView->GetDoc().SetAllocDocSh(false);
1085 if (!bOLEObjFound)
1086 delete pTmpDoc; // Would otherwise be destroyed by DocShell
1088 pView.reset();
1090 // Get number of objects after inserting.
1091 const size_t nCount = pPage->GetObjCount();
1092 if (nCountBefore < nCount)
1094 size_t nObj = nCountBefore;
1095 for (const auto& rExchange : rExchangeList)
1097 // Get the name to use from the Exchange list
1098 if (pPage->GetObj(nObj))
1100 pPage->GetObj(nObj)->SetName(rExchange);
1103 ++nObj;
1104 if (nObj >= nCount)
1105 break;
1110 return bOK;
1113 // Stops the bookmark insertion
1114 void SdDrawDocument::CloseBookmarkDoc()
1116 if (mxBookmarkDocShRef.is())
1118 mxBookmarkDocShRef->DoClose();
1121 mxBookmarkDocShRef.clear();
1122 maBookmarkFile.clear();
1125 // Is this document read-only?
1126 bool SdDrawDocument::IsReadOnly() const
1128 return false;
1131 // In the subsequent AllocModel() a DocShell (xAllocedDocShRef) is created.
1132 // Any pre-existing DocShell is deleted
1133 void SdDrawDocument::SetAllocDocSh(bool bAlloc)
1135 mbAllocDocSh = bAlloc;
1137 if(mxAllocedDocShRef.is())
1139 mxAllocedDocShRef->DoClose();
1142 mxAllocedDocShRef.clear();
1145 // Return list of CustomShows (create it, too, if necessary)
1146 SdCustomShowList* SdDrawDocument::GetCustomShowList(bool bCreate)
1148 if (!mpCustomShowList && bCreate)
1150 mpCustomShowList.reset(new SdCustomShowList);
1153 return mpCustomShowList.get();
1156 // Remove unused master pages and layouts
1157 void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage* pMasterPage, bool bOnlyDuplicatePages, bool bUndo)
1159 ::sd::View* pView = nullptr;
1160 SfxUndoManager* pUndoMgr = nullptr;
1162 if( bUndo && !IsUndoEnabled() )
1163 bUndo = false;
1165 if (mpDocSh)
1167 pUndoMgr = mpDocSh->GetUndoManager();
1169 if (mpDocSh->GetViewShell())
1170 pView = mpDocSh->GetViewShell()->GetView();
1173 // Check all master pages
1174 sal_uInt16 nSdMasterPageCount = GetMasterSdPageCount( PageKind::Standard );
1175 for (sal_Int32 nMPage = nSdMasterPageCount - 1; nMPage >= 0; nMPage--)
1177 SdPage* pMaster = pMasterPage;
1178 SdPage* pNotesMaster = nullptr;
1180 if (!pMaster)
1182 pMaster = GetMasterSdPage( static_cast<sal_uInt16>(nMPage), PageKind::Standard );
1183 pNotesMaster = GetMasterSdPage( static_cast<sal_uInt16>(nMPage), PageKind::Notes );
1185 else
1187 for ( sal_uInt16 nMPg = 0; nMPg < GetMasterPageCount(); nMPg++ )
1189 if ( pMaster == GetMasterPage( nMPg ) )
1191 pNotesMaster = static_cast<SdPage*>( GetMasterPage( ++nMPg ) );
1192 break;
1197 DBG_ASSERT( pMaster->GetPageKind() == PageKind::Standard, "wrong page kind" );
1199 if ( pMaster->GetPageKind() == PageKind::Standard &&
1200 GetMasterPageUserCount( pMaster ) == 0 &&
1201 pNotesMaster )
1203 // Do not delete master pages that have their precious flag set
1204 bool bDeleteMaster = !pMaster->IsPrecious();
1205 OUString aLayoutName = pMaster->GetLayoutName();
1207 if(bOnlyDuplicatePages )
1209 // remove only duplicate pages
1210 bDeleteMaster = false;
1211 for (sal_uInt16 i = 0; i < GetMasterSdPageCount( PageKind::Standard ); i++)
1213 SdPage* pMPg = GetMasterSdPage( i, PageKind::Standard );
1214 if( pMPg != pMaster &&
1215 pMPg->GetLayoutName() == aLayoutName )
1217 // duplicate page found -> remove it
1218 bDeleteMaster = true;
1223 if( bDeleteMaster )
1225 if (pView)
1227 // if MasterPage is visible hide on pageview
1228 SdrPageView* pPgView = pView->GetSdrPageView();
1229 if (pPgView)
1231 SdrPage* pShownPage = pPgView->GetPage();
1232 if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) )
1234 pView->HideSdrPage();
1235 pView->ShowSdrPage( GetSdPage( 0, PageKind::Standard ) );
1240 if( bUndo )
1242 BegUndo();
1243 AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster ) );
1246 RemoveMasterPage( pNotesMaster->GetPageNum() );
1248 if( bUndo )
1249 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster));
1251 RemoveMasterPage( pMaster->GetPageNum() );
1253 if( bUndo )
1254 EndUndo(); // do this here already, so Joe's actions happen _between_ our own
1256 // Delete old, unused layout stylesheets
1257 bool bDeleteOldStyleSheets = true;
1258 for ( sal_uInt16 nMPg = 0;
1259 nMPg < GetMasterPageCount() && bDeleteOldStyleSheets;
1260 nMPg++ )
1262 SdPage* pMPg = static_cast<SdPage*>( GetMasterPage(nMPg) );
1263 if (pMPg->GetLayoutName() == aLayoutName)
1265 bDeleteOldStyleSheets = false;
1269 if (bDeleteOldStyleSheets)
1271 SdStyleSheetVector aRemove;
1272 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList( aLayoutName, aRemove );
1274 if( bUndo )
1276 StyleSheetCopyResultVector aUndoRemove;
1277 aUndoRemove.reserve(aRemove.size());
1278 for (const auto& a : aRemove)
1279 aUndoRemove.emplace_back(a.get(), true);
1281 if (pUndoMgr)
1282 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aUndoRemove, false));
1285 for( const auto& a : aRemove )
1286 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->Remove(a.get());
1291 if (pMasterPage)
1292 break; // Just this one master page!
1296 /** Exchange master page
1298 * Either the nSdPageNum gets a new, own master page or the master page is
1299 * exchanged completely (which then applies to all pages).
1301 * nSdPageNum : page number that the new master page should get.
1302 * rLayoutName : LayoutName of the new master page
1303 * pSourceDoc : document (template) to get the master page from
1304 * bMaster : exchange the master page of nSdPageNum
1305 * bCheckMasters: remove unused master pages
1307 * If pSourceDoc == NULL, an empty master page is applied.
1308 * If rLayoutName is empty, the first master page is used.
1310 // #i121863# factored out functionality
1311 static bool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, std::u16string_view rCandidate)
1313 if (rCandidate.empty())
1315 return false;
1318 const sal_uInt16 nPageCount(rDoc.GetMasterPageCount());
1320 for(sal_uInt16 a(0); a < nPageCount; a++)
1322 const SdrPage* pCandidate = rDoc.GetMasterPage(a);
1323 OUString aPageLayoutName(pCandidate->GetLayoutName());
1324 sal_Int32 nIndex = aPageLayoutName.indexOf(SD_LT_SEPARATOR);
1325 if( nIndex != -1 )
1326 aPageLayoutName = aPageLayoutName.copy(0, nIndex);
1328 if(aPageLayoutName == rCandidate)
1330 return false;
1334 return true;
1337 // #i121863# factored out functionality
1338 static OUString createNewMasterPageLayoutName(const SdDrawDocument& rDoc)
1340 const OUString aBaseName(SdResId(STR_LAYOUT_DEFAULT_NAME));
1341 sal_uInt16 nCount(0);
1342 for (;;)
1344 OUString aRetval = aBaseName;
1345 if(nCount)
1347 aRetval += OUString::number(nCount);
1349 if (isMasterPageLayoutNameUnique(rDoc, aRetval))
1350 return aRetval;
1351 nCount++;
1355 void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum,
1356 std::u16string_view rLayoutName,
1357 SdDrawDocument* pSourceDoc,
1358 bool bMaster,
1359 bool bCheckMasters)
1361 SfxUndoManager* pUndoMgr = nullptr;
1363 if( mpDocSh )
1365 mpDocSh->SetWaitCursor( true );
1366 pUndoMgr = mpDocSh->GetUndoManager();
1369 const bool bUndo = pUndoMgr && IsUndoEnabled();
1371 if (bUndo)
1373 ViewShellId nViewShellId(-1);
1374 if (sd::ViewShell* pViewShell = mpDocSh->GetViewShell())
1375 nViewShellId = pViewShell->GetViewShellBase().GetViewShellId();
1376 pUndoMgr->EnterListAction(SdResId(STR_UNDO_SET_PRESLAYOUT), OUString(), 0, nViewShellId);
1379 SdPage* pSelectedPage = GetSdPage(nSdPageNum, PageKind::Standard);
1380 SdPage* pNotes = static_cast<SdPage*>( GetPage(pSelectedPage->GetPageNum()+1) );
1381 SdPage& rOldMaster = static_cast<SdPage&>(pSelectedPage->TRG_GetMasterPage());
1382 SdPage& rOldNotesMaster = static_cast<SdPage&>(pNotes->TRG_GetMasterPage());
1383 rtl::Reference<SdPage> pMaster;
1384 rtl::Reference<SdPage> pNotesMaster;
1385 OUString aOldPageLayoutName(pSelectedPage->GetLayoutName());
1386 OUString aOldLayoutName(aOldPageLayoutName);
1387 sal_Int32 nIndex = aOldLayoutName.indexOf( SD_LT_SEPARATOR );
1388 if( nIndex != -1 )
1389 aOldLayoutName = aOldLayoutName.copy(0, nIndex);
1391 if (pSourceDoc)
1393 std::vector<StyleReplaceData> aReplList; // List of replaced stylesheets
1394 bool bLayoutReloaded = false; // Was ex. layout reloaded?
1396 // LayoutName, Page and Notes page
1397 if (rLayoutName.empty())
1399 // No LayoutName: take first MasterPage
1400 pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard);
1401 pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes);
1403 else
1405 OUString aSearchFor
1406 = OUString::Concat(rLayoutName) + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
1408 for (sal_uInt16 nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); ++nMP)
1410 SdPage* pMP = static_cast<SdPage*>( pSourceDoc->GetMasterPage(nMP) );
1412 if (pMP->GetLayoutName() == aSearchFor)
1414 if (pMP->GetPageKind() == PageKind::Standard)
1415 pMaster = pMP;
1416 if (pMP->GetPageKind() == PageKind::Notes)
1417 pNotesMaster = pMP;
1419 if (pMaster && pNotesMaster)
1420 break;
1422 DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
1423 DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
1425 // this should not happen, but looking at crash reports, it does
1426 if( (pMaster == nullptr) || (pNotesMaster == nullptr) )
1428 // so take the first MasterPage
1429 pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard);
1430 pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes);
1434 // we should never reach this, but one never knows...
1435 if( (pMaster == nullptr) || (pNotesMaster == nullptr) )
1437 if (bUndo)
1438 pUndoMgr->LeaveListAction();
1440 if( mpDocSh )
1441 mpDocSh->SetWaitCursor( false );
1443 OSL_FAIL( "SdDrawDocument::SetMasterPage() failed!" );
1445 return;
1448 const OUString aOriginalNewLayoutName( pMaster->GetName() );
1449 OUString aTargetNewLayoutName(aOriginalNewLayoutName);
1451 if (pSourceDoc != this)
1453 // #i121863# clone masterpages, they are from another model (!)
1454 rtl::Reference<SdPage> pNewNotesMaster(dynamic_cast< SdPage* >(pNotesMaster->CloneSdrPage(*this).get()));
1455 rtl::Reference<SdPage> pNewMaster(dynamic_cast< SdPage* >(pMaster->CloneSdrPage(*this).get()));
1457 if(!pNewNotesMaster || !pNewMaster)
1459 OSL_FAIL("SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" );
1460 return;
1463 pNotesMaster = pNewNotesMaster;
1464 pMaster = pNewMaster;
1466 // layout name needs to be unique
1467 aTargetNewLayoutName = pMaster->GetLayoutName();
1468 sal_Int32 nIndex2 = aTargetNewLayoutName.indexOf(SD_LT_SEPARATOR);
1469 if( nIndex2 != -1 )
1470 aTargetNewLayoutName = aTargetNewLayoutName.copy(0, nIndex2);
1472 if(!isMasterPageLayoutNameUnique(*this, aTargetNewLayoutName))
1474 aTargetNewLayoutName = createNewMasterPageLayoutName(*this);
1476 OUString aTemp = aTargetNewLayoutName + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
1478 pMaster->SetName(aTargetNewLayoutName);
1479 pMaster->SetLayoutName(aTemp);
1481 pNotesMaster->SetName(aTargetNewLayoutName);
1482 pNotesMaster->SetLayoutName(aTemp);
1486 if (pSourceDoc != this)
1488 const sal_uInt16 nMasterPageCount = GetMasterPageCount();
1489 for ( sal_uInt16 nMPage = 0; nMPage < nMasterPageCount; nMPage++ )
1491 SdPage* pCheckMaster = static_cast<SdPage*>(GetMasterPage(nMPage));
1492 if( pCheckMaster->GetName() == aTargetNewLayoutName )
1494 bLayoutReloaded = true;
1495 break;
1499 // Correct or create presentation templates --
1500 // only worry about presentation templates
1501 OUString aName;
1502 SdStyleSheetPool* pSourceStyleSheetPool = static_cast<SdStyleSheetPool*>( pSourceDoc->GetStyleSheetPool() );
1504 StyleSheetCopyResultVector aCreatedStyles; // List of created stylesheets
1505 SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First(SfxStyleFamily::Page);
1507 while (pHisSheet)
1509 aName = pHisSheet->GetName();
1511 // #i121863# search in source styles with original style name from source of
1512 // evtl. cloned master (not-cloned, renamed for uniqueness)
1513 if( aName.startsWith( aOriginalNewLayoutName ) )
1515 // #i121863# build name of evtl. cloned master style to search for
1516 if(aOriginalNewLayoutName != aTargetNewLayoutName)
1518 const sal_Int32 nPos(aName.indexOf(SD_LT_SEPARATOR));
1519 aName = aTargetNewLayoutName + aName.subView(nPos);
1522 SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SfxStyleFamily::Page) );
1524 if (pMySheet)
1526 // A stylesheet of the same name already exists -> overwrite contents
1527 bool bTest = pMySheet->SetName(pHisSheet->GetName());
1528 DBG_ASSERT(bTest, "Renaming StyleSheet failed.");
1529 pMySheet->GetItemSet().ClearItem(); // Delete all
1531 if (bUndo)
1533 pUndoMgr->AddUndoAction(std::make_unique<StyleSheetUndoAction>(this,
1534 pMySheet, &pHisSheet->GetItemSet()));
1536 pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1537 pMySheet->Broadcast(SfxHint(SfxHintId::DataChanged));
1539 else
1541 // create new style
1542 OUString aHelpFile;
1543 pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SfxStyleFamily::Page, pHisSheet->GetMask()) );
1544 pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) );
1545 pMySheet->GetItemSet().ClearItem(); // Delete all
1546 pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1548 aCreatedStyles.emplace_back(static_cast<SdStyleSheet*>(pMySheet), true);
1551 StyleReplaceData aReplData;
1552 aReplData.nNewFamily = pMySheet->GetFamily();
1553 aReplData.nFamily = pMySheet->GetFamily();
1554 aReplData.aNewName = pMySheet->GetName();
1556 // #i121863# re-create original name of style used at page where to replace with
1557 // this new style
1558 OUString aTemp(pMySheet->GetName());
1559 const sal_Int32 nPos(aTemp.indexOf(SD_LT_SEPARATOR));
1560 aTemp = aOldLayoutName + aTemp.subView(nPos);
1561 aReplData.aName = aTemp;
1562 aReplList.push_back(aReplData);
1565 pHisSheet = pSourceStyleSheetPool->Next();
1568 // If new styles were created: re-create parent chaining of the item
1569 // sets in the styles.
1570 if(!aCreatedStyles.empty())
1572 for ( const auto& rRData : aReplList )
1574 SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(rRData.aName, SfxStyleFamily::Page);
1575 SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(rRData.aNewName, SfxStyleFamily::Page);
1577 if (pSOld && pSNew)
1579 const OUString& rParentOfOld = pSOld->GetParent();
1580 const OUString& rParentOfNew = pSNew->GetParent();
1582 if (!rParentOfOld.isEmpty() && rParentOfNew.isEmpty())
1584 std::vector<StyleReplaceData>::iterator pRDIter = std::find_if(aReplList.begin(), aReplList.end(),
1585 [&rParentOfOld](const StyleReplaceData& rRD) { return (rRD.aName == rParentOfOld) && (rRD.aName != rRD.aNewName); });
1586 if (pRDIter != aReplList.end())
1588 OUString aParentOfNew(pRDIter->aNewName);
1589 pSNew->SetParent(aParentOfNew);
1596 if (bUndo && !aCreatedStyles.empty())
1598 // Add UndoAction for creating and inserting the stylesheets to
1599 // the top of the UndoManager
1600 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>( this, aCreatedStyles, true));
1604 // Create layout name based upon the name of the page layout of the
1605 // master page
1606 OUString aPageLayoutName(pMaster->GetLayoutName());
1607 OUString aLayoutName = aPageLayoutName;
1608 sal_Int32 nIndex2 = aLayoutName.indexOf( SD_LT_SEPARATOR );
1609 if( nIndex2 != -1 )
1610 aLayoutName = aLayoutName.copy( 0, nIndex2);
1612 // #i121863# Do *not* remove from original document any longer, it is potentially used there
1613 // and would lead to crashes. Rely on the automatic process of removing unused masterpages
1614 // (see RemoveUnnecessaryMasterPages)
1615 //if (pSourceDoc != this)
1617 // // Remove from the source document
1618 // pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1619 // pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1622 // Register the new master pages with the document and then use
1623 // the new presentation layout for the default and notes pages
1624 if (pSourceDoc != this)
1626 // Insert the master pages:
1627 // Insert master pages from new layouts at the end.
1628 // If a layout is being replaced, however, insert them before the
1629 // position of the old master page, so from now on the new master
1630 // page will be found when searching (e.g.
1631 // SdPage::SetPresentationLayout).
1632 sal_uInt16 nInsertPos = rOldMaster.GetPageNum();
1633 BegUndo();
1635 if (!bLayoutReloaded)
1636 nInsertPos = 0xFFFF;
1637 InsertMasterPage(pMaster.get(), nInsertPos);
1638 if( bUndo )
1639 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1641 nInsertPos++;
1642 if (!bLayoutReloaded)
1643 nInsertPos = 0xFFFF;
1644 InsertMasterPage(pNotesMaster.get(), nInsertPos);
1645 if( bUndo )
1647 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1649 EndUndo(); // do this here already, so Joe's actions happen _between_ our own.
1653 // Fill list with pages
1654 std::vector<rtl::Reference<SdPage>> aPageList;
1656 // #98456, this has to be removed according to CL (KA 07/08/2002)
1657 // #109884# but we need them again to restore the styles of the presentation objects while undo
1658 aPageList.push_back(pMaster);
1659 aPageList.push_back(pNotesMaster);
1661 if (bMaster || bLayoutReloaded)
1663 for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1665 SdPage* pPage = static_cast<SdPage*>( GetPage(nPage) );
1666 OUString aTest = pPage->GetLayoutName();
1667 if (aTest == aOldPageLayoutName)
1669 aPageList.push_back(pPage);
1674 else
1676 aPageList.push_back(pSelectedPage);
1677 aPageList.push_back(pNotes);
1680 for (rtl::Reference<SdPage>& pPage : aPageList)
1682 AutoLayout eAutoLayout = pPage->GetAutoLayout();
1684 if( bUndo )
1686 pUndoMgr->AddUndoAction(std::make_unique<SdPresentationLayoutUndoAction>
1687 (this,
1688 pPage->IsMasterPage() ? aLayoutName : aOldLayoutName,
1689 aLayoutName,
1690 eAutoLayout, eAutoLayout, false, pPage.get()));
1692 pPage->SetPresentationLayout(aLayoutName);
1693 pPage->SetAutoLayout(eAutoLayout);
1696 // Adapt new master pages
1697 if (pSourceDoc != this)
1699 Size aSize(rOldMaster.GetSize());
1700 ::tools::Rectangle aBorderRect(rOldMaster.GetLeftBorder(),
1701 rOldMaster.GetUpperBorder(),
1702 rOldMaster.GetRightBorder(),
1703 rOldMaster.GetLowerBorder());
1704 pMaster->ScaleObjects(aSize, aBorderRect, true);
1705 pMaster->SetSize(aSize);
1706 pMaster->SetBorder(rOldMaster.GetLeftBorder(),
1707 rOldMaster.GetUpperBorder(),
1708 rOldMaster.GetRightBorder(),
1709 rOldMaster.GetLowerBorder());
1710 pMaster->SetOrientation( rOldMaster.GetOrientation() );
1711 pMaster->SetAutoLayout(pMaster->GetAutoLayout());
1713 aSize = rOldNotesMaster.GetSize();
1714 ::tools::Rectangle aNotesBorderRect(rOldNotesMaster.GetLeftBorder(),
1715 rOldNotesMaster.GetUpperBorder(),
1716 rOldNotesMaster.GetRightBorder(),
1717 rOldNotesMaster.GetLowerBorder());
1718 pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, true);
1719 pNotesMaster->SetSize(aSize);
1720 pNotesMaster->SetBorder(rOldNotesMaster.GetLeftBorder(),
1721 rOldNotesMaster.GetUpperBorder(),
1722 rOldNotesMaster.GetRightBorder(),
1723 rOldNotesMaster.GetLowerBorder());
1724 pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() );
1725 pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout());
1727 if( (pSourceDoc->GetDocumentType() == DocumentType::Impress) &&
1728 (GetDocumentType() == DocumentType::Draw) )
1730 pMaster->RemoveEmptyPresentationObjects();
1731 pNotesMaster->RemoveEmptyPresentationObjects();
1735 else
1737 // Find a new name for the layout
1738 OUString aName(createNewMasterPageLayoutName(*this));
1739 OUString aPageLayoutName(aName + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE);
1741 // Generate new stylesheets
1742 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName);
1743 SdStyleSheetVector aCreatedStyles;
1744 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles);
1746 if( bUndo )
1748 StyleSheetCopyResultVector aUndoInsert;
1749 aUndoInsert.reserve(aCreatedStyles.size());
1750 for (const auto& a : aCreatedStyles)
1751 aUndoInsert.emplace_back(a.get(), true);
1752 pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aUndoInsert, true));
1753 // Generate new master pages and register them with the document
1754 BegUndo();
1757 pMaster = AllocSdPage(true);
1758 pMaster->SetSize(pSelectedPage->GetSize());
1759 pMaster->SetBorder(pSelectedPage->GetLeftBorder(),
1760 pSelectedPage->GetUpperBorder(),
1761 pSelectedPage->GetRightBorder(),
1762 pSelectedPage->GetLowerBorder() );
1763 pMaster->SetName(aName);
1764 pMaster->SetLayoutName(aPageLayoutName);
1765 InsertMasterPage(pMaster.get());
1767 if( bUndo )
1768 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1770 pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
1772 pNotesMaster = AllocSdPage(true);
1773 pNotesMaster->SetPageKind(PageKind::Notes);
1774 pNotesMaster->SetSize(pNotes->GetSize());
1775 pNotesMaster->SetBorder(pNotes->GetLeftBorder(),
1776 pNotes->GetUpperBorder(),
1777 pNotes->GetRightBorder(),
1778 pNotes->GetLowerBorder() );
1779 pNotesMaster->SetName(aName);
1780 pNotesMaster->SetLayoutName(aPageLayoutName);
1781 InsertMasterPage(pNotesMaster.get());
1783 if( bUndo )
1784 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1786 pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
1788 if( bUndo )
1789 EndUndo();
1791 // Create a list of affected default and notes pages
1792 std::vector<SdPage*> aPageList;
1793 if (bMaster)
1795 for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++)
1797 SdPage* pPage = static_cast<SdPage*>( GetPage(nPage) );
1798 if (pPage->GetLayoutName() == aOldPageLayoutName)
1800 aPageList.push_back(pPage);
1804 else
1806 aPageList.push_back(pSelectedPage);
1807 aPageList.push_back(pNotes);
1810 // Set presentation layout and AutoLayout for the affected pages
1811 for ( auto& rpPage : aPageList )
1813 AutoLayout eOldAutoLayout = rpPage->GetAutoLayout();
1814 AutoLayout eNewAutoLayout =
1815 rpPage->GetPageKind() == PageKind::Standard ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES;
1817 if( bUndo )
1819 pUndoMgr->AddUndoAction(std::make_unique<SdPresentationLayoutUndoAction>
1820 (this, aOldLayoutName, aName,
1821 eOldAutoLayout, eNewAutoLayout, true,
1822 rpPage));
1825 rpPage->SetPresentationLayout(aName);
1826 rpPage->SetAutoLayout(eNewAutoLayout);
1830 // If the old master pages aren't used anymore, they and their styles have
1831 // to be removed.
1832 if (bCheckMasters)
1834 // Check all
1835 RemoveUnnecessaryMasterPages();
1837 else
1839 // Check only the master page that was replaced
1840 RemoveUnnecessaryMasterPages(&rOldMaster);
1843 if( bUndo )
1844 pUndoMgr->LeaveListAction();
1846 if( mpDocSh )
1847 mpDocSh->SetWaitCursor( false );
1850 void SdDrawDocument::Merge(SdrModel& rSourceModel,
1851 sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1852 sal_uInt16 nDestPos,
1853 bool bMergeMasterPages, bool bAllMasterPages,
1854 bool bUndo, bool bTreadSourceAsConst)
1856 sal_uInt16 nMasterPageCount = GetMasterPageCount();
1857 SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst );
1859 // add style family for each new master page
1860 for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ )
1862 SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) );
1863 if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PageKind::Standard) )
1865 // new master page created, add its style family
1866 SdStyleSheetPool* pStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
1867 if( pStylePool )
1868 pStylePool->AddStyleFamily( pPage );
1873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */