1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <cppuhelper/exc_hlp.hxx>
24 #include <vcl/wrkwin.hxx>
25 #include <sfx2/docfile.hxx>
26 #include <sot/storage.hxx>
27 #include <sfx2/app.hxx>
28 #include <svl/itemset.hxx>
30 #include <sfx2/fcontnr.hxx>
31 #include <svx/svdopath.hxx>
32 #include <svx/svditer.hxx>
33 #include <svl/style.hxx>
34 #include <sfx2/linkmgr.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <svx/svdogrp.hxx>
37 #include <svx/svdundo.hxx>
38 #include <vcl/weld.hxx>
39 #include <sot/formats.hxx>
40 #include <xmloff/autolayout.hxx>
42 #include <strings.hrc>
43 #include <drawdoc.hxx>
45 #include <stlpool.hxx>
46 #include <sdresid.hxx>
47 #include <sdiocmpt.hxx>
49 #include <anminfo.hxx>
50 #include <customshowlist.hxx>
53 #include <unmovss.hxx>
55 #include <unprlout.hxx>
56 #include <DrawDocShell.hxx>
57 #include <GraphicDocShell.hxx>
58 #include <ViewShell.hxx>
60 #include <ViewShellBase.hxx>
61 #include <strings.hxx>
63 using namespace ::com::sun::star
;
65 /** Concrete incarnations get called by lcl_IterateBookmarkPages, for
66 every page in the bookmark document/list
69 class InsertBookmarkAsPage_FindDuplicateLayouts
72 explicit InsertBookmarkAsPage_FindDuplicateLayouts( std::vector
<OUString
> &rLayoutsToTransfer
)
73 : mrLayoutsToTransfer(rLayoutsToTransfer
) {}
74 void operator()( SdDrawDocument
&, SdPage
const *, bool, SdDrawDocument
* );
76 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
);
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
);
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
107 if( bRenameDuplicates
&& aTest
!= SdResId( STR_LAYOUT_DEFAULT_NAME
) && !(pTestPage
->Equals(*pBMMPage
)) )
109 pBookmarkDoc
->RenameLayoutTemplate(
110 pBMMPage
->GetLayoutName(), pBMMPage
->GetName() + "_");
111 aLayout
= pBMMPage
->GetName();
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
134 if( rBookmarkList
.empty() )
136 // no list? whole source document
137 nEndPos
= nBMSdPageCount
;
141 // bookmark list? number of entries
142 nEndPos
= rBookmarkList
.size();
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()));
160 // fetch nPos'th entry from bookmark list, and determine master page
161 OUString
aBMPgName(rBookmarkList
[nPos
]);
164 sal_uInt16 nBMPage
= pBookmarkDoc
->GetPageByName( aBMPgName
, bIsMasterPage
);
166 if (nBMPage
!= SDRPAGE_NOTFOUND
)
168 pBMPage
= static_cast<SdPage
*>( pBookmarkDoc
->GetPage(nBMPage
) );
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?
187 rPageIterator( rDoc
, pBMMPage
, bRenameDuplicates
, pBookmarkDoc
);
192 // Opens a bookmark document
193 SdDrawDocument
* SdDrawDocument::OpenBookmarkDoc(SfxMedium
* pMedium
)
196 SdDrawDocument
* pBookmarkDoc
= nullptr;
197 OUString aBookmarkName
= pMedium
->GetName();
198 std::shared_ptr
<const SfxFilter
> pFilter
= pMedium
->GetFilter();
201 pMedium
->UseInteractionHandler( true );
202 SfxGetpApp()->GetFilterMatcher().GuessFilter(*pMedium
, pFilter
);
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
)
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
)
222 mxBookmarkDocShRef
= new ::sd::GraphicDocShell(SfxObjectCreateMode::STANDARD
, true, DocumentType::Draw
);
225 mxBookmarkDocShRef
= new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD
, true, DocumentType::Impress
);
227 bOK
= mxBookmarkDocShRef
->DoLoad(pMedium
);
230 maBookmarkFile
= aBookmarkName
;
231 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
236 DBG_ASSERT(!aBookmarkName
.isEmpty(), "Empty document name!");
240 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(nullptr,
241 VclMessageType::Warning
, VclButtonsType::Ok
, SdResId(STR_READ_DATA_ERROR
)));
245 pBookmarkDoc
= nullptr;
247 else if (mxBookmarkDocShRef
.is())
249 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
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();
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
283 bool bInsertPages
= false;
285 if (rBookmarkList
.empty())
292 SdDrawDocument
* pBookmarkDoc
= nullptr;
296 pBookmarkDoc
= pBookmarkDocSh
->GetDoc();
298 else if ( mxBookmarkDocShRef
.is() )
300 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
305 std::vector
<OUString
>::const_iterator pIter
;
306 for ( pIter
= rBookmarkList
.begin(); bOK
&& pIter
!= rBookmarkList
.end() && !bInsertPages
; ++pIter
)
308 // Is there a page name in the bookmark list?
310 if( pBookmarkDoc
->GetPageByName( *pIter
, bIsMasterPage
) != SDRPAGE_NOTFOUND
)
318 bool bCalcObjCount
= !rExchangeList
.empty();
320 if ( bOK
&& bInsertPages
)
322 // Insert all page bookmarks
323 bOK
= InsertBookmarkAsPage(rBookmarkList
, &rExchangeList
, bLink
, false/*bReplace*/,
324 nInsertPos
, false/*bNoDialogs*/, pBookmarkDocSh
, true/*bCopy*/, true, false);
327 if ( bOK
&& !rBookmarkList
.empty() )
329 // Insert all object bookmarks
330 InsertBookmarkAsObject(rBookmarkList
, rExchangeList
,
331 pBookmarkDocSh
, pObjPos
, bCalcObjCount
);
339 lcl_removeUnusedStyles(SfxStyleSheetBasePool
* const pStyleSheetPool
, StyleSheetCopyResultVector
& rStyles
)
341 StyleSheetCopyResultVector aUsedStyles
;
342 aUsedStyles
.reserve(rStyles
.size());
343 for (const auto& a
: rStyles
)
345 if (a
.m_xStyleSheet
->IsUsed())
346 aUsedStyles
.push_back(a
);
348 pStyleSheetPool
->Remove(a
.m_xStyleSheet
.get());
350 rStyles
= aUsedStyles
;
353 SfxStyleSheet
*lcl_findStyle(StyleSheetCopyResultVector
& rStyles
, const OUString
& aStyleName
)
355 for (const auto& a
: rStyles
)
357 if (a
.m_xStyleSheet
->GetName().startsWith(aStyleName
))
358 return a
.m_xStyleSheet
.get();
365 bool SdDrawDocument::InsertBookmarkAsPage(
366 const std::vector
<OUString
> &rBookmarkList
,
367 std::vector
<OUString
> *pExchangeList
, // List of names to be used
370 sal_uInt16 nInsertPos
,
372 ::sd::DrawDocShell
* pBookmarkDocSh
,
374 bool bMergeMasterPages
,
375 bool bPreservePageNames
)
377 bool bContinue
= true;
378 bool bScaleObjects
= false;
379 sal_uInt16 nReplacedStandardPages
= 0;
381 SdDrawDocument
* pBookmarkDoc
= nullptr;
382 OUString aBookmarkName
;
386 pBookmarkDoc
= pBookmarkDocSh
->GetDoc();
388 if (pBookmarkDocSh
->GetMedium())
390 aBookmarkName
= pBookmarkDocSh
->GetMedium()->GetName();
393 else if ( mxBookmarkDocShRef
.is() )
395 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
396 aBookmarkName
= maBookmarkFile
;
403 const sal_uInt16 nSdPageCount
= GetSdPageCount(PageKind::Standard
);
404 const sal_uInt16 nBMSdPageCount
= pBookmarkDoc
->GetSdPageCount(PageKind::Standard
);
405 const sal_uInt16 nMPageCount
= GetMasterPageCount();
407 if (nSdPageCount
==0 || nBMSdPageCount
==0 || nMPageCount
==0)
412 // Store the size and some other properties of the first page and notes
413 // page so that inserted pages can be properly scaled even when inserted
414 // before the first page.
415 // Note that the pointers are used later on as general page pointers.
416 SdPage
* pRefPage
= GetSdPage(0, PageKind::Standard
);
417 Size
aSize(pRefPage
->GetSize());
418 sal_Int32 nLeft
= pRefPage
->GetLeftBorder();
419 sal_Int32 nRight
= pRefPage
->GetRightBorder();
420 sal_Int32 nUpper
= pRefPage
->GetUpperBorder();
421 sal_Int32 nLower
= pRefPage
->GetLowerBorder();
422 Orientation eOrient
= pRefPage
->GetOrientation();
424 SdPage
* pNPage
= GetSdPage(0, PageKind::Notes
);
425 Size
aNSize(pNPage
->GetSize());
426 sal_Int32 nNLeft
= pNPage
->GetLeftBorder();
427 sal_Int32 nNRight
= pNPage
->GetRightBorder();
428 sal_Int32 nNUpper
= pNPage
->GetUpperBorder();
429 sal_Int32 nNLower
= pNPage
->GetLowerBorder();
430 Orientation eNOrient
= pNPage
->GetOrientation();
432 // Adapt page size and margins to those of the later pages?
433 pRefPage
= GetSdPage(nSdPageCount
- 1, PageKind::Standard
);
437 // If this is clipboard, then no need to scale objects:
438 // this will make copied masters to differ from the originals,
439 // and thus InsertBookmarkAsPage_FindDuplicateLayouts will
440 // duplicate masters on insert to same document
441 bTransportContainer
= (SD_MOD()->pTransferClip
&&
442 SD_MOD()->pTransferClip
->GetWorkDocument() == this);
443 if (!bTransportContainer
)
445 if (rBookmarkList
.empty())
446 bScaleObjects
= pRefPage
->IsScaleObjects();
448 bScaleObjects
= true;
453 SdPage
* pBMPage
= pBookmarkDoc
->GetSdPage(0,PageKind::Standard
);
455 if (pBMPage
->GetSize() != pRefPage
->GetSize() ||
456 pBMPage
->GetLeftBorder() != pRefPage
->GetLeftBorder() ||
457 pBMPage
->GetRightBorder() != pRefPage
->GetRightBorder() ||
458 pBMPage
->GetUpperBorder() != pRefPage
->GetUpperBorder() ||
459 pBMPage
->GetLowerBorder() != pRefPage
->GetLowerBorder())
461 OUString
aStr(SdResId(STR_SCALE_OBJECTS
));
462 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(nullptr,
463 VclMessageType::Question
, VclButtonsType::YesNo
,
465 xQueryBox
->add_button(Button::GetStandardText(StandardButtonType::Cancel
), RET_CANCEL
);
466 sal_uInt16 nBut
= xQueryBox
->run();
468 bScaleObjects
= nBut
== RET_YES
;
469 bContinue
= nBut
!= RET_CANCEL
;
478 // Get the necessary presentation stylesheets and transfer them before
479 // the pages, else, the text objects won't reference their styles anymore.
480 ::svl::IUndoManager
* pUndoMgr
= nullptr;
483 pUndoMgr
= mpDocSh
->GetUndoManager();
484 ViewShellId
nViewShellId(-1);
485 if (sd::ViewShell
* pViewShell
= mpDocSh
->GetViewShell())
486 nViewShellId
= pViewShell
->GetViewShellBase().GetViewShellId();
487 pUndoMgr
->EnterListAction(SdResId(STR_UNDO_INSERTPAGES
), "", 0, nViewShellId
);
490 // Refactored copy'n'pasted layout name collection into IterateBookmarkPages
492 std::vector
<OUString
> aLayoutsToTransfer
;
493 InsertBookmarkAsPage_FindDuplicateLayouts
aSearchFunctor( aLayoutsToTransfer
);
494 lcl_IterateBookmarkPages( *this, pBookmarkDoc
, rBookmarkList
, nBMSdPageCount
, aSearchFunctor
, ( rBookmarkList
.empty() && pBookmarkDoc
!= this ) );
496 // Copy the style that we actually need.
497 SdStyleSheetPool
& rBookmarkStyleSheetPool
= dynamic_cast<SdStyleSheetPool
&>(*pBookmarkDoc
->GetStyleSheetPool());
498 SdStyleSheetPool
& rStyleSheetPool
= dynamic_cast<SdStyleSheetPool
&>(*GetStyleSheetPool());
500 // When copying styles, also copy the master pages!
501 if( !aLayoutsToTransfer
.empty() )
502 bMergeMasterPages
= true;
504 std::vector
<OUString
>::const_iterator pIter
;
505 for ( pIter
= aLayoutsToTransfer
.begin(); pIter
!= aLayoutsToTransfer
.end(); ++pIter
)
507 StyleSheetCopyResultVector aCreatedStyles
;
508 OUString layoutName
= *pIter
;
510 rStyleSheetPool
.CopyLayoutSheets(layoutName
, rBookmarkStyleSheetPool
,aCreatedStyles
);
512 if(!aCreatedStyles
.empty())
516 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction(this, aCreatedStyles
, true);
517 pUndoMgr
->AddUndoAction(pMovStyles
);
522 // Copy styles. This unconditionally copies all styles, even those
523 // that are not used in any of the inserted pages. The unused styles
524 // are then removed at the end of the function, where we also create
525 // undo records for the inserted styles.
526 StyleSheetCopyResultVector aNewGraphicStyles
;
528 if(!bReplace
&& !bNoDialogs
)
530 rStyleSheetPool
.RenameAndCopyGraphicSheets(rBookmarkStyleSheetPool
, aNewGraphicStyles
, aRenameStr
);
531 StyleSheetCopyResultVector aNewCellStyles
;
532 rStyleSheetPool
.CopyCellSheets(rBookmarkStyleSheetPool
, aNewCellStyles
);
534 // TODO handle undo of table styles too
535 rStyleSheetPool
.CopyTableStyles(rBookmarkStyleSheetPool
);
539 const bool bUndo
= IsUndoEnabled();
542 BegUndo(SdResId(STR_UNDO_INSERTPAGES
));
544 if (rBookmarkList
.empty())
546 if (nInsertPos
>= GetPageCount())
548 // Add pages to the end
549 nInsertPos
= GetPageCount();
552 sal_uInt16 nActualInsertPos
= nInsertPos
;
554 sal_uInt16 nBMSdPage
;
555 std::set
<sal_uInt16
> aRenameSet
;
556 std::map
<sal_uInt16
,OUString
> aNameMap
;
558 for (nBMSdPage
=0; nBMSdPage
< nBMSdPageCount
; nBMSdPage
++)
560 SdPage
* pBMPage
= pBookmarkDoc
->GetSdPage(nBMSdPage
, PageKind::Standard
);
561 OUString
sName(pBMPage
->GetName());
566 // Remember the names of all pages
567 aNameMap
.insert(std::make_pair(nBMSdPage
,sName
));
570 // Have to check for duplicate names here, too
571 // don't change name if source and dest model are the same!
572 if( pBookmarkDoc
!= this &&
573 GetPageByName(sName
, bIsMasterPage
) != SDRPAGE_NOTFOUND
)
575 // delay renaming *after* pages are copied (might destroy source otherwise)
576 aRenameSet
.insert(nBMSdPage
);
581 1, // Not the handout page
582 0xFFFF, // But all others
583 nActualInsertPos
, // Insert at position ...
584 bMergeMasterPages
, // Move master pages?
585 false, // But only the master pages used
586 true, // Create an undo action
587 bCopy
); // Copy (or merge) pages?
589 for (nBMSdPage
=0; nBMSdPage
< nBMSdPageCount
; nBMSdPage
++)
591 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
) );
592 SdPage
* pNotesPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
+1) );
594 // delay renaming *after* pages are copied (might destroy source otherwise)
595 if( aRenameSet
.find(nBMSdPage
) != aRenameSet
.end() )
597 // Page name already in use -> Use default name for default and
599 pPage
->SetName(OUString());
600 pNotesPage
->SetName(OUString());
605 OUString
aName(aNameMap
[nBMSdPage
]);
607 // Assemble all link names
608 pPage
->SetFileName(aBookmarkName
);
609 pPage
->SetBookmarkName(aName
);
612 nActualInsertPos
+= 2;
617 // Insert selected pages
620 if (nInsertPos
>= GetPageCount())
622 // Add pages to the end
624 nInsertPos
= GetPageCount();
627 sal_uInt16 nActualInsertPos
= nInsertPos
;
629 // Collect the bookmarked pages
630 ::std::vector
<SdPage
*> aBookmarkedPages (rBookmarkList
.size(), nullptr);
631 for ( size_t nPos
= 0, n
= rBookmarkList
.size(); nPos
< n
; ++nPos
)
633 OUString
aPgName(rBookmarkList
[nPos
]);
635 sal_uInt16 nBMPage
= pBookmarkDoc
->GetPageByName( aPgName
, bIsMasterPage
);
637 if (nBMPage
!= SDRPAGE_NOTFOUND
)
639 aBookmarkedPages
[nPos
] = dynamic_cast<SdPage
*>(pBookmarkDoc
->GetPage(nBMPage
));
643 for ( size_t nPos
= 0, n
= rBookmarkList
.size(); nPos
< n
; ++nPos
)
645 pBMPage
= aBookmarkedPages
[nPos
];
646 sal_uInt16 nBMPage
= pBMPage
!=nullptr ? pBMPage
->GetPageNum() : SDRPAGE_NOTFOUND
;
648 if (pBMPage
&& pBMPage
->GetPageKind()==PageKind::Standard
&& !pBMPage
->IsMasterPage())
650 // It has to be a default page
651 bool bMustRename
= false;
653 // delay renaming *after* pages are copied (might destroy source otherwise)
654 // don't change name if source and dest model are the same!
655 // avoid renaming if replacing the same page
656 OUString
aPgName(rBookmarkList
[nPos
]);
658 sal_uInt16 nPageSameName
= GetPageByName(aPgName
, bIsMasterPage
);
659 if( pBookmarkDoc
!= this &&
660 nPageSameName
!= SDRPAGE_NOTFOUND
&&
662 nPageSameName
!= nActualInsertPos
) )
667 SdPage
* pBookmarkPage
= pBMPage
;
670 ReplacePageInCustomShows( dynamic_cast< SdPage
* >( GetPage( nActualInsertPos
) ), pBookmarkPage
);
674 nBMPage
, // From page (default page)
675 nBMPage
+1, // To page (notes page)
676 nActualInsertPos
, // Insert at position
677 bMergeMasterPages
, // Move master pages?
678 false, // But only the master pages used
679 true, // Create undo action
680 bCopy
); // Copy (or merge) pages?
684 if( GetPage( nActualInsertPos
) != pBookmarkPage
)
686 // bookmark page was not moved but cloned, so update custom shows again
687 ReplacePageInCustomShows( pBookmarkPage
, dynamic_cast< SdPage
* >( GetPage( nActualInsertPos
) ) );
693 // Page name already in use -> use default name for default and
695 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
) );
696 pPage
->SetName(OUString());
697 SdPage
* pNotesPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
+1) );
698 pNotesPage
->SetName(OUString());
703 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
) );
704 pPage
->SetFileName(aBookmarkName
);
705 pPage
->SetBookmarkName(aPgName
);
710 // Remove page and notes page.
711 const sal_uInt16
nDestPageNum(nActualInsertPos
+ 2);
712 SdPage
* pStandardPage
= nullptr;
714 if(nDestPageNum
< GetPageCount())
716 pStandardPage
= static_cast<SdPage
*>(GetPage(nDestPageNum
));
721 if( bPreservePageNames
)
723 // Take old slide names for inserted pages
724 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
) );
725 pPage
->SetName( pStandardPage
->GetRealName() );
729 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage
));
731 RemovePage(nDestPageNum
);
734 delete pStandardPage
;
737 SdPage
* pNotesPage
= nullptr;
739 if(nDestPageNum
< GetPageCount())
741 pNotesPage
= static_cast<SdPage
*>(GetPage(nDestPageNum
));
746 if( bPreservePageNames
)
748 // Take old slide names for inserted pages
749 SdPage
* pNewNotesPage
= static_cast<SdPage
*>( GetPage(nActualInsertPos
+1));
751 pNewNotesPage
->SetName( pStandardPage
->GetRealName() );
755 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage
));
757 RemovePage(nDestPageNum
);
763 nReplacedStandardPages
++;
766 nActualInsertPos
+= 2;
771 // We might have duplicate master pages now, as the drawing engine does not
772 // recognize duplicates. Remove these now.
773 sal_uInt16 nNewMPageCount
= GetMasterPageCount();
775 // Go backwards, so the numbers don't become messed up
776 for (sal_uInt16 nPage
= nNewMPageCount
- 1; nPage
>= nMPageCount
; nPage
--)
778 pRefPage
= static_cast<SdPage
*>( GetMasterPage(nPage
) );
779 OUString
aMPLayout(pRefPage
->GetLayoutName());
780 PageKind eKind
= pRefPage
->GetPageKind();
782 // Does this already exist?
783 for (sal_uInt16 nTest
= 0; nTest
< nMPageCount
; nTest
++)
785 SdPage
* pTest
= static_cast<SdPage
*>( GetMasterPage(nTest
) );
786 OUString
aTest(pTest
->GetLayoutName());
788 // nInsertPos > 2 is always true when inserting into non-empty models
789 if ( nInsertPos
> 2 &&
790 aTest
== aMPLayout
&&
791 eKind
== pTest
->GetPageKind() )
794 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage
));
796 RemoveMasterPage(nPage
);
806 // nInsertPos > 2 is always true when inserting into non-empty models
809 sal_uInt16 nSdPageStart
= (nInsertPos
- 1) / 2;
810 sal_uInt16 nSdPageEnd
= GetSdPageCount(PageKind::Standard
) - nSdPageCount
+
812 const bool bRemoveEmptyPresObj
=
813 (pBookmarkDoc
->GetDocumentType() == DocumentType::Impress
) &&
814 (GetDocumentType() == DocumentType::Draw
);
818 nSdPageEnd
= nSdPageStart
+ nReplacedStandardPages
- 1;
821 std::vector
<OUString
>::iterator pExchangeIter
;
824 pExchangeIter
= pExchangeList
->begin();
826 for (sal_uInt16 nSdPage
= nSdPageStart
; nSdPage
<= nSdPageEnd
; nSdPage
++)
828 pRefPage
= GetSdPage(nSdPage
, PageKind::Standard
);
830 if (pExchangeList
&& pExchangeIter
!= pExchangeList
->end())
832 // Get the name to use from Exchange list
833 OUString
aExchangeName(*pExchangeIter
);
834 pRefPage
->SetName(aExchangeName
);
835 Broadcast(SdrHint(SdrHintKind::PageOrderChange
, pRefPage
));
837 SdPage
* pNewNotesPage
= GetSdPage(nSdPage
, PageKind::Notes
);
838 pNewNotesPage
->SetName(aExchangeName
);
839 Broadcast(SdrHint(SdrHintKind::PageOrderChange
, pNewNotesPage
));
844 OUString
aLayout(pRefPage
->GetLayoutName());
845 sal_Int32 nIndex
= aLayout
.indexOf( SD_LT_SEPARATOR
);
847 aLayout
= aLayout
.copy(0, nIndex
);
849 // update layout and referred master page
850 pRefPage
->SetPresentationLayout(aLayout
);
852 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage
) );
856 ::tools::Rectangle
aBorderRect(nLeft
, nUpper
, nRight
, nLower
);
857 pRefPage
->ScaleObjects(aSize
, aBorderRect
, true);
859 pRefPage
->SetSize(aSize
);
860 pRefPage
->SetBorder(nLeft
, nUpper
, nRight
, nLower
);
861 pRefPage
->SetOrientation( eOrient
);
863 if( bRemoveEmptyPresObj
)
864 pRefPage
->RemoveEmptyPresentationObjects();
866 pRefPage
= GetSdPage(nSdPage
, PageKind::Notes
);
868 // update layout and referred master page
869 pRefPage
->SetPresentationLayout(aLayout
);
871 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage
) );
875 ::tools::Rectangle
aBorderRect(nNLeft
, nNUpper
, nNRight
, nNLower
);
876 pRefPage
->ScaleObjects(aNSize
, aBorderRect
, true);
879 pRefPage
->SetSize(aNSize
);
880 pRefPage
->SetBorder(nNLeft
, nNUpper
, nNRight
, nNLower
);
881 pRefPage
->SetOrientation( eNOrient
);
883 if( bRemoveEmptyPresObj
)
884 pRefPage
->RemoveEmptyPresentationObjects();
887 ///Remove processed elements, to avoid doings hacks in InsertBookmarkAsObject
889 pExchangeList
->erase(pExchangeList
->begin(),pExchangeIter
);
891 for (sal_uInt16 nPage
= nMPageCount
; nPage
< nNewMPageCount
; nPage
++)
893 pRefPage
= static_cast<SdPage
*>( GetMasterPage(nPage
) );
894 if (pRefPage
->GetPageKind() == PageKind::Standard
)
898 ::tools::Rectangle
aBorderRect(nLeft
, nUpper
, nRight
, nLower
);
899 pRefPage
->ScaleObjects(aSize
, aBorderRect
, true);
901 pRefPage
->SetSize(aSize
);
902 pRefPage
->SetBorder(nLeft
, nUpper
, nRight
, nLower
);
903 pRefPage
->SetOrientation( eOrient
);
905 else // Can only be notes
909 ::tools::Rectangle
aBorderRect(nNLeft
, nNUpper
, nNRight
, nNLower
);
910 pRefPage
->ScaleObjects(aNSize
, aBorderRect
, true);
912 pRefPage
->SetSize(aNSize
);
913 pRefPage
->SetBorder(nNLeft
, nNUpper
, nNRight
, nNLower
);
914 pRefPage
->SetOrientation( eNOrient
);
917 if( bRemoveEmptyPresObj
)
918 pRefPage
->RemoveEmptyPresentationObjects();
922 // Make absolutely sure no double masterpages are there
923 RemoveUnnecessaryMasterPages(nullptr, true);
925 // Rename object styles if necessary
926 if(!aRenameStr
.isEmpty())
930 for(sal_uInt32 p
= nInsertPos
; p
< sal_uInt32(nInsertPos
) + sal_uInt32(nBMSdPageCount
); p
++)
932 SdPage
*pPg
= static_cast<SdPage
*>( GetPage(p
) );
933 for(size_t i
= 0; pPg
&& (i
< pPg
->GetObjCount()); ++i
)
935 if(pPg
->GetObj(i
)->GetStyleSheet())
937 OUString aStyleName
= pPg
->GetObj(i
)->GetStyleSheet()->GetName();
938 SfxStyleSheet
*pSheet
= lcl_findStyle(aNewGraphicStyles
, aStyleName
+ aRenameStr
);
939 if(pSheet
!= nullptr)
940 pPg
->GetObj(i
)->SetStyleSheet(pSheet
, true);
947 OSL_FAIL("Exception while renaming styles @ SdDrawDocument::InsertBookmarkAsPage");
950 // remove copied styles not used on any inserted page and create
952 // WARNING: SdMoveStyleSheetsUndoAction clears the passed list of
953 // styles, so it cannot be used after this point
954 lcl_removeUnusedStyles(GetStyleSheetPool(), aNewGraphicStyles
);
955 if (!aNewGraphicStyles
.empty() && pUndoMgr
)
956 pUndoMgr
->AddUndoAction(new SdMoveStyleSheetsUndoAction(this, aNewGraphicStyles
, true));
957 lcl_removeUnusedStyles(GetStyleSheetPool(), aNewCellStyles
);
958 if (!aNewCellStyles
.empty() && pUndoMgr
)
959 pUndoMgr
->AddUndoAction(new SdMoveStyleSheetsUndoAction(this, aNewCellStyles
, true));
965 pUndoMgr
->LeaveListAction();
970 // Inserts a bookmark as an object
971 bool SdDrawDocument::InsertBookmarkAsObject(
972 const std::vector
<OUString
> &rBookmarkList
,
973 const std::vector
<OUString
> &rExchangeList
, // List of names to use
974 ::sd::DrawDocShell
* pBookmarkDocSh
,
975 Point
const * pObjPos
,
979 bool bOLEObjFound
= false;
980 ::sd::View
* pBMView
= nullptr;
982 SdDrawDocument
* pBookmarkDoc
= nullptr;
986 pBookmarkDoc
= pBookmarkDocSh
->GetDoc();
988 else if ( mxBookmarkDocShRef
.is() )
990 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
997 if (rBookmarkList
.empty())
999 pBMView
= new ::sd::View(*pBookmarkDoc
, nullptr);
1000 pBMView
->EndListening(*pBookmarkDoc
);
1008 std::vector
<OUString
>::const_iterator pIter
;
1009 for ( pIter
= rBookmarkList
.begin(); pIter
!= rBookmarkList
.end(); ++pIter
)
1011 // Get names of bookmarks from the list
1012 SdrObject
* pObj
= pBookmarkDoc
->GetObj(*pIter
);
1017 if (pObj
->GetObjInventor() == SdrInventor::Default
&&
1018 pObj
->GetObjIdentifier() == OBJ_OLE2
)
1020 bOLEObjFound
= true;
1025 // Create View for the first time
1026 pBMView
= new ::sd::View(*pBookmarkDoc
, nullptr);
1027 pBMView
->EndListening(*pBookmarkDoc
);
1030 pPage
= pObj
->getSdrPageFromSdrObject();
1032 if (pPage
->IsMasterPage())
1034 pPV
= pBMView
->ShowSdrPage(pBMView
->GetModel()->GetMasterPage(pPage
->GetPageNum()));
1038 pPV
= pBMView
->GetSdrPageView();
1039 if( !pPV
|| (pPV
->GetPage() != pPage
))
1040 pPV
= pBMView
->ShowSdrPage(pPage
);
1043 pBMView
->MarkObj(pObj
, pPV
);
1050 // Insert selected objects
1051 ::sd::View
* pView
= new ::sd::View(*this, nullptr);
1052 pView
->EndListening(*this);
1054 // Look for the page into which the objects are supposed to be inserted
1055 SdrPage
* pPage
= GetSdPage(0, PageKind::Standard
);
1059 ::sd::ViewShell
* pViewSh
= mpDocSh
->GetViewShell();
1063 // Which page is currently in view?
1064 SdrPageView
* pPV
= pViewSh
->GetView()->GetSdrPageView();
1068 pPage
= pPV
->GetPage();
1070 else if (pViewSh
->GetActualPage())
1072 pPage
= pViewSh
->GetActualPage();
1085 aObjPos
= ::tools::Rectangle(Point(), pPage
->GetSize()).Center();
1088 size_t nCountBefore
= 0;
1090 if (!rExchangeList
.empty() || bCalcObjCount
)
1092 // Sort OrdNums and get the number of objects before inserting
1093 pPage
->RecalcObjOrdNums();
1094 nCountBefore
= pPage
->GetObjCount();
1098 pBMView
->GetDoc().SetAllocDocSh(true);
1100 SdDrawDocument
* pTmpDoc
= static_cast<SdDrawDocument
*>( pBMView
->GetMarkedObjModel() );
1101 bOK
= pView
->Paste(*pTmpDoc
, aObjPos
, pPage
, SdrInsertFlags::NONE
);
1104 pBMView
->GetDoc().SetAllocDocSh(false);
1107 delete pTmpDoc
; // Would otherwise be destroyed by DocShell
1111 if (!rExchangeList
.empty())
1113 // Get number of objects after inserting.
1114 const size_t nCount
= pPage
->GetObjCount();
1116 std::vector
<OUString
>::const_iterator pIter
= rExchangeList
.begin();
1117 for (size_t nObj
= nCountBefore
; nObj
< nCount
; ++nObj
)
1119 // Get the name to use from the Exchange list
1120 if (pIter
!= rExchangeList
.end())
1122 if (pPage
->GetObj(nObj
))
1124 pPage
->GetObj(nObj
)->SetName(*pIter
);
1138 // Stops the bookmark insertion
1139 void SdDrawDocument::CloseBookmarkDoc()
1141 if (mxBookmarkDocShRef
.is())
1143 mxBookmarkDocShRef
->DoClose();
1146 mxBookmarkDocShRef
.clear();
1147 maBookmarkFile
.clear();
1150 // Is this document read-only?
1151 bool SdDrawDocument::IsReadOnly() const
1156 // In the subsequent AllocModel() a DocShell (xAllocedDocShRef) is created.
1157 // Any pre-existing DocShell is deleted
1158 void SdDrawDocument::SetAllocDocSh(bool bAlloc
)
1160 mbAllocDocSh
= bAlloc
;
1162 if(mxAllocedDocShRef
.is())
1164 mxAllocedDocShRef
->DoClose();
1167 mxAllocedDocShRef
.clear();
1170 // Return list of CustomShows (create it, too, if necessary)
1171 SdCustomShowList
* SdDrawDocument::GetCustomShowList(bool bCreate
)
1173 if (!mpCustomShowList
&& bCreate
)
1175 mpCustomShowList
.reset(new SdCustomShowList
);
1178 return mpCustomShowList
.get();
1181 // Remove unused master pages and layouts
1182 void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage
* pMasterPage
, bool bOnlyDuplicatePages
, bool bUndo
)
1184 ::sd::View
* pView
= nullptr;
1185 ::svl::IUndoManager
* pUndoMgr
= nullptr;
1187 if( bUndo
&& !IsUndoEnabled() )
1192 pUndoMgr
= mpDocSh
->GetUndoManager();
1194 if (mpDocSh
->GetViewShell())
1195 pView
= mpDocSh
->GetViewShell()->GetView();
1198 // Check all master pages
1199 sal_uInt16 nSdMasterPageCount
= GetMasterSdPageCount( PageKind::Standard
);
1200 for (sal_Int32 nMPage
= nSdMasterPageCount
- 1; nMPage
>= 0; nMPage
--)
1202 SdPage
* pMaster
= pMasterPage
;
1203 SdPage
* pNotesMaster
= nullptr;
1207 pMaster
= GetMasterSdPage( static_cast<sal_uInt16
>(nMPage
), PageKind::Standard
);
1208 pNotesMaster
= GetMasterSdPage( static_cast<sal_uInt16
>(nMPage
), PageKind::Notes
);
1212 for ( sal_uInt16 nMPg
= 0; nMPg
< GetMasterPageCount(); nMPg
++ )
1214 if ( pMaster
== GetMasterPage( nMPg
) )
1216 pNotesMaster
= static_cast<SdPage
*>( GetMasterPage( ++nMPg
) );
1222 DBG_ASSERT( pMaster
->GetPageKind() == PageKind::Standard
, "wrong page kind" );
1224 if ( pMaster
->GetPageKind() == PageKind::Standard
&&
1225 GetMasterPageUserCount( pMaster
) == 0 &&
1228 // Do not delete master pages that have their precious flag set
1229 bool bDeleteMaster
= !pMaster
->IsPrecious();
1230 OUString aLayoutName
= pMaster
->GetLayoutName();
1232 if(bOnlyDuplicatePages
)
1234 // remove only duplicate pages
1235 bDeleteMaster
= false;
1236 for (sal_uInt16 i
= 0; i
< GetMasterSdPageCount( PageKind::Standard
); i
++)
1238 SdPage
* pMPg
= GetMasterSdPage( i
, PageKind::Standard
);
1239 if( pMPg
!= pMaster
&&
1240 pMPg
->GetLayoutName() == aLayoutName
)
1242 // duplicate page found -> remove it
1243 bDeleteMaster
= true;
1252 // if MasterPage is visible hide on pageview
1253 SdrPageView
* pPgView
= pView
->GetSdrPageView();
1256 SdrPage
* pShownPage
= pPgView
->GetPage();
1257 if( (pShownPage
== pMaster
) || (pShownPage
== pNotesMaster
) )
1259 pView
->HideSdrPage();
1260 pView
->ShowSdrPage( GetSdPage( 0, PageKind::Standard
) );
1268 AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster
) );
1271 RemoveMasterPage( pNotesMaster
->GetPageNum() );
1274 delete pNotesMaster
;
1277 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster
));
1279 RemoveMasterPage( pMaster
->GetPageNum() );
1285 EndUndo(); // do this here already, so Joe's actions happen _between_ our own
1287 // Delete old, unused layout stylesheets
1288 bool bDeleteOldStyleSheets
= true;
1289 for ( sal_uInt16 nMPg
= 0;
1290 nMPg
< GetMasterPageCount() && bDeleteOldStyleSheets
;
1293 SdPage
* pMPg
= static_cast<SdPage
*>( GetMasterPage(nMPg
) );
1294 if (pMPg
->GetLayoutName() == aLayoutName
)
1296 bDeleteOldStyleSheets
= false;
1300 if (bDeleteOldStyleSheets
)
1302 SdStyleSheetVector aRemove
;
1303 static_cast<SdStyleSheetPool
*>( mxStyleSheetPool
.get())->CreateLayoutSheetList( aLayoutName
, aRemove
);
1307 StyleSheetCopyResultVector aUndoRemove
;
1308 aUndoRemove
.reserve(aRemove
.size());
1309 for (const auto& a
: aRemove
)
1310 aUndoRemove
.emplace_back(a
.get(), true);
1311 // This list belongs to UndoAction
1312 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction(this, aUndoRemove
, false);
1315 pUndoMgr
->AddUndoAction(pMovStyles
);
1318 for( SdStyleSheetVector::iterator iter
= aRemove
.begin(); iter
!= aRemove
.end(); ++iter
)
1319 static_cast<SdStyleSheetPool
*>( mxStyleSheetPool
.get())->Remove((*iter
).get());
1325 break; // Just this one master page!
1329 /** Exchange master page
1331 * Either the nSdPageNum gets a new, own master page or the master page is
1332 * exchanged completely (which then applies to all pages).
1334 * nSdPageNum : page number that the new master page should get.
1335 * rLayoutName : LayoutName of the new master page
1336 * pSourceDoc : document (template) to get the master page from
1337 * bMaster : exchange the master page of nSdPageNum
1338 * bCheckMasters: remove unused master pages
1340 * If pSourceDoc == NULL, an empty master page is applied.
1341 * If rLayoutName is empty, the first master page is used.
1343 // #i121863# factored out functionality
1344 bool isMasterPageLayoutNameUnique(const SdDrawDocument
& rDoc
, const OUString
& rCandidate
)
1346 if (rCandidate
.isEmpty())
1351 const sal_uInt16
nPageCount(rDoc
.GetMasterPageCount());
1353 for(sal_uInt16
a(0); a
< nPageCount
; a
++)
1355 const SdrPage
* pCandidate
= rDoc
.GetMasterPage(a
);
1356 OUString
aPageLayoutName(pCandidate
->GetLayoutName());
1357 sal_Int32 nIndex
= aPageLayoutName
.indexOf(SD_LT_SEPARATOR
);
1359 aPageLayoutName
= aPageLayoutName
.copy(0, nIndex
);
1361 if(aPageLayoutName
== rCandidate
)
1370 // #i121863# factored out functinality
1371 OUString
createNewMasterPageLayoutName(const SdDrawDocument
& rDoc
)
1373 const OUString
aBaseName(SdResId(STR_LAYOUT_DEFAULT_NAME
));
1375 sal_uInt16
nCount(0);
1377 while (aRetval
.isEmpty())
1379 aRetval
= aBaseName
;
1383 aRetval
+= OUString::number(nCount
);
1388 if(!isMasterPageLayoutNameUnique(rDoc
, aRetval
))
1397 void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum
,
1398 const OUString
& rLayoutName
,
1399 SdDrawDocument
* pSourceDoc
,
1403 ::svl::IUndoManager
* pUndoMgr
= nullptr;
1407 mpDocSh
->SetWaitCursor( true );
1408 pUndoMgr
= mpDocSh
->GetUndoManager();
1411 const bool bUndo
= pUndoMgr
&& IsUndoEnabled();
1415 ViewShellId
nViewShellId(-1);
1416 if (sd::ViewShell
* pViewShell
= mpDocSh
->GetViewShell())
1417 nViewShellId
= pViewShell
->GetViewShellBase().GetViewShellId();
1418 pUndoMgr
->EnterListAction(SdResId(STR_UNDO_SET_PRESLAYOUT
), OUString(), 0, nViewShellId
);
1421 SdPage
* pSelectedPage
= GetSdPage(nSdPageNum
, PageKind::Standard
);
1422 SdPage
* pNotes
= static_cast<SdPage
*>( GetPage(pSelectedPage
->GetPageNum()+1) );
1423 SdPage
& rOldMaster
= static_cast<SdPage
&>(pSelectedPage
->TRG_GetMasterPage());
1424 SdPage
& rOldNotesMaster
= static_cast<SdPage
&>(pNotes
->TRG_GetMasterPage());
1425 SdPage
* pMaster
= nullptr;
1426 SdPage
* pNotesMaster
= nullptr;
1427 OUString
aOldPageLayoutName(pSelectedPage
->GetLayoutName());
1428 OUString
aOldLayoutName(aOldPageLayoutName
);
1429 sal_Int32 nIndex
= aOldLayoutName
.indexOf( SD_LT_SEPARATOR
);
1431 aOldLayoutName
= aOldLayoutName
.copy(0, nIndex
);
1435 std::vector
<StyleReplaceData
> aReplList
; // List of replaced stylesheets
1436 bool bLayoutReloaded
= false; // Was ex. layout reloaded?
1438 // LayoutName, Page and Notes page
1439 if (rLayoutName
.isEmpty())
1441 // No LayoutName: take first MasterPage
1442 pMaster
= pSourceDoc
->GetMasterSdPage(0, PageKind::Standard
);
1443 pNotesMaster
= pSourceDoc
->GetMasterSdPage(0, PageKind::Notes
);
1447 OUString aSearchFor
= rLayoutName
+ SD_LT_SEPARATOR STR_LAYOUT_OUTLINE
;
1449 for (sal_uInt16 nMP
= 0; nMP
< pSourceDoc
->GetMasterPageCount(); ++nMP
)
1451 SdPage
* pMP
= static_cast<SdPage
*>( pSourceDoc
->GetMasterPage(nMP
) );
1453 if (pMP
->GetLayoutName() == aSearchFor
)
1455 if (pMP
->GetPageKind() == PageKind::Standard
)
1457 if (pMP
->GetPageKind() == PageKind::Notes
)
1460 if (pMaster
&& pNotesMaster
)
1463 DBG_ASSERT(pMaster
, "MasterPage (Standard page) not found");
1464 DBG_ASSERT(pNotesMaster
, "MasterPage (Notes page) not found");
1466 // this should not happen, but looking at crash reports, it does
1467 if( (pMaster
== nullptr) || (pNotesMaster
== nullptr) )
1469 // so take the first MasterPage
1470 pMaster
= pSourceDoc
->GetMasterSdPage(0, PageKind::Standard
);
1471 pNotesMaster
= pSourceDoc
->GetMasterSdPage(0, PageKind::Notes
);
1475 // we should never reach this, but one never knows...
1476 if( (pMaster
== nullptr) || (pNotesMaster
== nullptr) )
1479 pUndoMgr
->LeaveListAction();
1482 mpDocSh
->SetWaitCursor( false );
1484 OSL_FAIL( "SdDrawDocument::SetMasterPage() failed!" );
1489 const OUString
aOriginalNewLayoutName( pMaster
->GetName() );
1490 OUString
aTargetNewLayoutName(aOriginalNewLayoutName
);
1492 if (pSourceDoc
!= this)
1494 // #i121863# clone masterpages, they are from another model (!)
1495 SdPage
* pNewNotesMaster
= dynamic_cast< SdPage
* >(pNotesMaster
->CloneSdrPage(*this));
1496 SdPage
* pNewMaster
= dynamic_cast< SdPage
* >(pMaster
->CloneSdrPage(*this));
1498 if(!pNewNotesMaster
|| !pNewMaster
)
1500 delete pNewNotesMaster
;
1502 OSL_FAIL("SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" );
1506 pNotesMaster
= pNewNotesMaster
;
1507 pMaster
= pNewMaster
;
1509 // layout name needs to be unique
1510 aTargetNewLayoutName
= pMaster
->GetLayoutName();
1511 sal_Int32 nIndex2
= aTargetNewLayoutName
.indexOf(SD_LT_SEPARATOR
);
1513 aTargetNewLayoutName
= aTargetNewLayoutName
.copy(0, nIndex2
);
1515 if(!isMasterPageLayoutNameUnique(*this, aTargetNewLayoutName
))
1517 aTargetNewLayoutName
= createNewMasterPageLayoutName(*this);
1519 OUString
aTemp(aTargetNewLayoutName
);
1520 aTemp
+= SD_LT_SEPARATOR
;
1521 aTemp
+= STR_LAYOUT_OUTLINE
;
1523 pMaster
->SetName(aTargetNewLayoutName
);
1524 pMaster
->SetLayoutName(aTemp
);
1526 pNotesMaster
->SetName(aTargetNewLayoutName
);
1527 pNotesMaster
->SetLayoutName(aTemp
);
1531 if (pSourceDoc
!= this)
1533 const sal_uInt16 nMasterPageCount
= GetMasterPageCount();
1534 for ( sal_uInt16 nMPage
= 0; nMPage
< nMasterPageCount
; nMPage
++ )
1536 SdPage
* pCheckMaster
= static_cast<SdPage
*>(GetMasterPage(nMPage
));
1537 if( pCheckMaster
->GetName() == aTargetNewLayoutName
)
1539 bLayoutReloaded
= true;
1544 // Correct or create presentation templates --
1545 // only worry about presentation templates
1547 SdStyleSheetPool
* pSourceStyleSheetPool
= static_cast<SdStyleSheetPool
*>( pSourceDoc
->GetStyleSheetPool() );
1548 pSourceStyleSheetPool
->SetSearchMask(SfxStyleFamily::Page
);
1549 static_cast<SdStyleSheetPool
*>( mxStyleSheetPool
.get())->SetSearchMask(SfxStyleFamily::Page
);
1551 StyleSheetCopyResultVector aCreatedStyles
; // List of created stylesheets
1552 SfxStyleSheetBase
* pHisSheet
= pSourceStyleSheetPool
->First();
1556 aName
= pHisSheet
->GetName();
1558 // #i121863# search in source styles with original style name from source of
1559 // evtl. cloned master (not-cloned, renamed for uniqueness)
1560 if( aName
.startsWith( aOriginalNewLayoutName
) )
1562 // #i121863# build name of evtl. cloned master style to search for
1563 if(aOriginalNewLayoutName
!= aTargetNewLayoutName
)
1565 const sal_Int32
nPos(aName
.indexOf(SD_LT_SEPARATOR
));
1566 aName
= aTargetNewLayoutName
+ aName
.copy(nPos
);
1569 SfxStyleSheet
* pMySheet
= static_cast<SfxStyleSheet
*>( mxStyleSheetPool
->Find(aName
, SfxStyleFamily::Page
) );
1573 // A stylesheet of the same name already exists -> overwrite contents
1574 bool bTest
= pMySheet
->SetName(pHisSheet
->GetName());
1575 DBG_ASSERT(bTest
, "Renaming StyleSheet failed.");
1576 pMySheet
->GetItemSet().ClearItem(); // Delete all
1580 StyleSheetUndoAction
* pUndoChStyle
= new StyleSheetUndoAction(this,
1581 pMySheet
, &pHisSheet
->GetItemSet());
1582 pUndoMgr
->AddUndoAction(pUndoChStyle
);
1584 pMySheet
->GetItemSet().Put(pHisSheet
->GetItemSet());
1585 pMySheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
1591 pMySheet
= static_cast<SfxStyleSheet
*>( &mxStyleSheetPool
->Make(aName
, SfxStyleFamily::Page
, pHisSheet
->GetMask()) );
1592 pMySheet
->SetHelpId( aHelpFile
, pHisSheet
->GetHelpId(aHelpFile
) );
1593 pMySheet
->GetItemSet().ClearItem(); // Delete all
1594 pMySheet
->GetItemSet().Put(pHisSheet
->GetItemSet());
1596 aCreatedStyles
.emplace_back(static_cast<SdStyleSheet
*>(pMySheet
), true);
1599 StyleReplaceData aReplData
;
1600 aReplData
.nNewFamily
= pMySheet
->GetFamily();
1601 aReplData
.nFamily
= pMySheet
->GetFamily();
1602 aReplData
.aNewName
= pMySheet
->GetName();
1604 // #i121863# re-create original name of style used at page where to replace with
1606 OUString
aTemp(pMySheet
->GetName());
1607 const sal_Int32
nPos(aTemp
.indexOf(SD_LT_SEPARATOR
));
1608 aTemp
= aOldLayoutName
+ aTemp
.copy(nPos
);
1609 aReplData
.aName
= aTemp
;
1610 aReplList
.push_back(aReplData
);
1613 pHisSheet
= static_cast<SfxStyleSheet
*>( pSourceStyleSheetPool
->Next() );
1616 // If new styles were created: re-create parent chaining of the item
1617 // sets in the styles.
1618 if(!aCreatedStyles
.empty())
1620 std::vector
<StyleReplaceData
>::iterator pRDataIter
;
1621 for ( pRDataIter
= aReplList
.begin(); pRDataIter
!= aReplList
.end(); ++pRDataIter
)
1623 SfxStyleSheetBase
* pSOld
= mxStyleSheetPool
->Find(pRDataIter
->aName
);
1624 SfxStyleSheetBase
* pSNew
= mxStyleSheetPool
->Find(pRDataIter
->aNewName
);
1628 const OUString
& rParentOfOld
= pSOld
->GetParent();
1629 const OUString
& rParentOfNew
= pSNew
->GetParent();
1631 if (!rParentOfOld
.isEmpty() && rParentOfNew
.isEmpty())
1633 std::vector
<StyleReplaceData
>::iterator pRDIter
;
1634 for ( pRDIter
= aReplList
.begin(); pRDIter
!= aReplList
.end(); ++pRDIter
)
1636 if ((pRDIter
->aName
== rParentOfOld
) && (pRDIter
->aName
!= pRDIter
->aNewName
))
1638 OUString
aParentOfNew(pRDIter
->aNewName
);
1639 pSNew
->SetParent(aParentOfNew
);
1647 // Now look for all of them when searching
1648 pSourceStyleSheetPool
->SetSearchMask(SfxStyleFamily::All
);
1649 mxStyleSheetPool
->SetSearchMask(SfxStyleFamily::All
);
1652 if (bUndo
&& !aCreatedStyles
.empty())
1654 // Add UndoAction for creating and inserting the stylesheets to
1655 // the top of the UndoManager
1656 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction( this, aCreatedStyles
, true);
1657 pUndoMgr
->AddUndoAction(pMovStyles
);
1661 // Create layout name based upon the name of the page layout of the
1663 OUString
aPageLayoutName(pMaster
->GetLayoutName());
1664 OUString aLayoutName
= aPageLayoutName
;
1665 sal_Int32 nIndex2
= aLayoutName
.indexOf( SD_LT_SEPARATOR
);
1667 aLayoutName
= aLayoutName
.copy( 0, nIndex2
);
1669 // #i121863# Do *not* remove from original document any longer, it is potentially used there
1670 // and would lead to crashes. Rely on the automatic process of removing unused masterpages
1671 // (see RemoveUnnecessaryMasterPages)
1672 //if (pSourceDoc != this)
1674 // // Remove from the source document
1675 // pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1676 // pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1679 // Register the new master pages with the document and then use
1680 // the new presentation layout for the default and notes pages
1681 if (pSourceDoc
!= this)
1683 // Insert the master pages:
1684 // Insert master pages from new layouts at the end.
1685 // If a layout is being replaced, however, insert them before the
1686 // position of the old master page, so from now on the new master
1687 // page will be found when searching (e.g.
1688 // SdPage::SetPresentationLayout).
1689 sal_uInt16 nInsertPos
= rOldMaster
.GetPageNum();
1692 if (!bLayoutReloaded
)
1693 nInsertPos
= 0xFFFF;
1694 InsertMasterPage(pMaster
, nInsertPos
);
1696 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster
));
1699 if (!bLayoutReloaded
)
1700 nInsertPos
= 0xFFFF;
1701 InsertMasterPage(pNotesMaster
, nInsertPos
);
1704 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster
));
1706 EndUndo(); // do this here already, so Joe's actions happen _between_ our own.
1710 // Fill list with pages
1711 std::vector
<SdPage
*> aPageList
;
1713 // #98456, this has to be removed according to CL (KA 07/08/2002)
1714 // #109884# but we need them again to restore the styles of the presentation objects while undo
1715 aPageList
.push_back(pMaster
);
1716 aPageList
.push_back(pNotesMaster
);
1718 if (bMaster
|| bLayoutReloaded
)
1720 for (sal_uInt16 nPage
= 1; nPage
< GetPageCount(); nPage
++)
1722 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(nPage
) );
1723 OUString aTest
= pPage
->GetLayoutName();
1724 if (aTest
== aOldPageLayoutName
)
1726 aPageList
.push_back(pPage
);
1733 aPageList
.push_back(pSelectedPage
);
1734 aPageList
.push_back(pNotes
);
1737 for (std::vector
<SdPage
*>::iterator pIter
= aPageList
.begin(); pIter
!= aPageList
.end(); ++pIter
)
1739 SdPage
* pPage
= *pIter
;
1740 AutoLayout eAutoLayout
= pPage
->GetAutoLayout();
1744 SdPresentationLayoutUndoAction
* pPLUndoAction
=
1745 new SdPresentationLayoutUndoAction
1747 pPage
->IsMasterPage() ? aLayoutName
: aOldLayoutName
,
1749 eAutoLayout
, eAutoLayout
, false, *pIter
);
1750 pUndoMgr
->AddUndoAction(pPLUndoAction
);
1752 pPage
->SetPresentationLayout(aLayoutName
);
1753 pPage
->SetAutoLayout(eAutoLayout
);
1756 // Adapt new master pages
1757 if (pSourceDoc
!= this)
1759 Size
aSize(rOldMaster
.GetSize());
1760 ::tools::Rectangle
aBorderRect(rOldMaster
.GetLeftBorder(),
1761 rOldMaster
.GetUpperBorder(),
1762 rOldMaster
.GetRightBorder(),
1763 rOldMaster
.GetLowerBorder());
1764 pMaster
->ScaleObjects(aSize
, aBorderRect
, true);
1765 pMaster
->SetSize(aSize
);
1766 pMaster
->SetBorder(rOldMaster
.GetLeftBorder(),
1767 rOldMaster
.GetUpperBorder(),
1768 rOldMaster
.GetRightBorder(),
1769 rOldMaster
.GetLowerBorder());
1770 pMaster
->SetOrientation( rOldMaster
.GetOrientation() );
1771 pMaster
->SetAutoLayout(pMaster
->GetAutoLayout());
1773 aSize
= rOldNotesMaster
.GetSize();
1774 ::tools::Rectangle
aNotesBorderRect(rOldNotesMaster
.GetLeftBorder(),
1775 rOldNotesMaster
.GetUpperBorder(),
1776 rOldNotesMaster
.GetRightBorder(),
1777 rOldNotesMaster
.GetLowerBorder());
1778 pNotesMaster
->ScaleObjects(aSize
, aNotesBorderRect
, true);
1779 pNotesMaster
->SetSize(aSize
);
1780 pNotesMaster
->SetBorder(rOldNotesMaster
.GetLeftBorder(),
1781 rOldNotesMaster
.GetUpperBorder(),
1782 rOldNotesMaster
.GetRightBorder(),
1783 rOldNotesMaster
.GetLowerBorder());
1784 pNotesMaster
->SetOrientation( rOldNotesMaster
.GetOrientation() );
1785 pNotesMaster
->SetAutoLayout(pNotesMaster
->GetAutoLayout());
1787 if( (pSourceDoc
->GetDocumentType() == DocumentType::Impress
) &&
1788 (GetDocumentType() == DocumentType::Draw
) )
1790 pMaster
->RemoveEmptyPresentationObjects();
1791 pNotesMaster
->RemoveEmptyPresentationObjects();
1797 // Find a new name for the layout
1798 OUString
aName(createNewMasterPageLayoutName(*this));
1799 OUString
aPageLayoutName(aName
+ SD_LT_SEPARATOR STR_LAYOUT_OUTLINE
);
1801 // Generate new stylesheets
1802 static_cast<SdStyleSheetPool
*>( mxStyleSheetPool
.get())->CreateLayoutStyleSheets(aName
);
1803 SdStyleSheetVector aCreatedStyles
;
1804 static_cast<SdStyleSheetPool
*>( mxStyleSheetPool
.get())->CreateLayoutSheetList(aName
, aCreatedStyles
);
1808 StyleSheetCopyResultVector aUndoInsert
;
1809 aUndoInsert
.reserve(aCreatedStyles
.size());
1810 for (const auto& a
: aCreatedStyles
)
1811 aUndoInsert
.emplace_back(a
.get(), true);
1812 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction(this, aUndoInsert
, true);
1813 pUndoMgr
->AddUndoAction(pMovStyles
);
1816 // Generate new master pages and register them with the document
1820 pMaster
= AllocSdPage(true);
1821 pMaster
->SetSize(pSelectedPage
->GetSize());
1822 pMaster
->SetBorder(pSelectedPage
->GetLeftBorder(),
1823 pSelectedPage
->GetUpperBorder(),
1824 pSelectedPage
->GetRightBorder(),
1825 pSelectedPage
->GetLowerBorder() );
1826 pMaster
->SetName(aName
);
1827 pMaster
->SetLayoutName(aPageLayoutName
);
1828 InsertMasterPage(pMaster
);
1831 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster
));
1833 pMaster
->SetAutoLayout(AUTOLAYOUT_NONE
, true, true);
1835 pNotesMaster
= AllocSdPage(true);
1836 pNotesMaster
->SetPageKind(PageKind::Notes
);
1837 pNotesMaster
->SetSize(pNotes
->GetSize());
1838 pNotesMaster
->SetBorder(pNotes
->GetLeftBorder(),
1839 pNotes
->GetUpperBorder(),
1840 pNotes
->GetRightBorder(),
1841 pNotes
->GetLowerBorder() );
1842 pNotesMaster
->SetName(aName
);
1843 pNotesMaster
->SetLayoutName(aPageLayoutName
);
1844 InsertMasterPage(pNotesMaster
);
1847 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster
));
1849 pNotesMaster
->SetAutoLayout(AUTOLAYOUT_NOTES
, true, true);
1854 // Create a list of affected default and notes pages
1855 std::vector
<SdPage
*> aPageList
;
1858 for (sal_uInt16 nPage
= 1; nPage
< GetPageCount(); nPage
++)
1860 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(nPage
) );
1861 if (pPage
->GetLayoutName() == aOldPageLayoutName
)
1863 aPageList
.push_back(pPage
);
1869 aPageList
.push_back(pSelectedPage
);
1870 aPageList
.push_back(pNotes
);
1873 // Set presentation layout and AutoLayout for the affected pages
1874 for ( std::vector
<SdPage
*>::iterator pIter
= aPageList
.begin(); pIter
!= aPageList
.end(); ++pIter
)
1876 AutoLayout eOldAutoLayout
= (*pIter
)->GetAutoLayout();
1877 AutoLayout eNewAutoLayout
=
1878 (*pIter
)->GetPageKind() == PageKind::Standard
? AUTOLAYOUT_NONE
: AUTOLAYOUT_NOTES
;
1882 SdPresentationLayoutUndoAction
* pPLUndoAction
=
1883 new SdPresentationLayoutUndoAction
1884 (this, aOldLayoutName
, aName
,
1885 eOldAutoLayout
, eNewAutoLayout
, true,
1887 pUndoMgr
->AddUndoAction(pPLUndoAction
);
1890 (*pIter
)->SetPresentationLayout(aName
);
1891 (*pIter
)->SetAutoLayout(eNewAutoLayout
);
1895 // If the old master pages aren't used anymore, they and their styles have
1900 RemoveUnnecessaryMasterPages();
1904 // Check only the master page that was replaced
1905 RemoveUnnecessaryMasterPages(&rOldMaster
);
1909 pUndoMgr
->LeaveListAction();
1912 mpDocSh
->SetWaitCursor( false );
1915 void SdDrawDocument::Merge(SdrModel
& rSourceModel
,
1916 sal_uInt16 nFirstPageNum
, sal_uInt16 nLastPageNum
,
1917 sal_uInt16 nDestPos
,
1918 bool bMergeMasterPages
, bool bAllMasterPages
,
1919 bool bUndo
, bool bTreadSourceAsConst
)
1921 sal_uInt16 nMasterPageCount
= GetMasterPageCount();
1922 SdrModel::Merge( rSourceModel
, nFirstPageNum
, nLastPageNum
, nDestPos
, bMergeMasterPages
, bAllMasterPages
, bUndo
, bTreadSourceAsConst
);
1924 // add style family for each new master page
1925 for( sal_uInt16 nMaster
= nMasterPageCount
; nMaster
< GetMasterPageCount(); nMaster
++ )
1927 SdPage
* pPage
= static_cast< SdPage
* >( GetMasterPage( nMaster
) );
1928 if( pPage
&& pPage
->IsMasterPage() && (pPage
->GetPageKind() == PageKind::Standard
) )
1930 // new master page created, add its style family
1931 SdStyleSheetPool
* pStylePool
= static_cast<SdStyleSheetPool
*>( GetStyleSheetPool() );
1933 pStylePool
->AddStyleFamily( pPage
);
1938 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */