sd/inc/drawdoc.hxx | 88 +- sd/qa/unit/uiimpress.cxx | 437 +++++++++ sd/source/core/drawdoc3.cxx | 438 ++++++++-- sd/source/ui/app/sdxfer.cxx | 4 sd/source/ui/func/fuoltext.cxx | 4 sd/source/ui/func/fupoor.cxx | 8 sd/source/ui/inc/View.hxx | 4 sd/source/ui/inc/fuoltext.hxx | 4 sd/source/ui/inc/fupoor.hxx | 4 sd/source/ui/inc/sdxfer.hxx | 2 sd/source/ui/slidesorter/controller/SlsClipboard.cxx | 39 sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx | 8 sd/source/ui/slidesorter/controller/SlsSlotManager.cxx | 4 sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx | 2 sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx | 9 sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx | 2 sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx | 4 sd/source/ui/view/sdview2.cxx | 4 18 files changed, 916 insertions(+), 149 deletions(-)
New commits: commit 0d8f5429a0f4b1e9818c6d04502e08dbfeec3eba Author: Mohamed Ali <mohmedali1462...@gmail.com> AuthorDate: Tue Feb 25 03:13:44 2025 +0200 Commit: Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org> CommitDate: Mon Apr 28 16:06:08 2025 +0200 tdf#45617 Make master slide copyable Added a new boolean option `bMergeMasterPagesOnly` to `InsertBookmarkOptions` to allow operations that only merge master pages. Updated various functions across the codebase to accommodate this new option, including `ForPaste`, `ForFileInsert`, `ForDragDrop`, and others Modified the `DocumentPageCounts` structure to include a count of new master pages Adjusted the logic in `insertAllPages`, `PasteBookmarkAsPage`, `ResolvePageLinks`, and `ImportDocumentPages` to utilize the new option for conditional merging behavior Updated UI components to pass the new parameter where necessary Enhances the naming logic for duplicate master slides, using a numeric prefix pattern (e.g., "1_MasterName") instead of simply appending underscores. Add unit tests for copying and pasting master pages Change-Id: If4167e846e5a747e1e1b194e3ced065a39f34ede Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182206 Tested-by: Jenkins Reviewed-by: Jonathan Clark <jonat...@libreoffice.org> Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org> diff --git a/sd/inc/drawdoc.hxx b/sd/inc/drawdoc.hxx index 5e34d41ccbea..24f1b077a21e 100644 --- a/sd/inc/drawdoc.hxx +++ b/sd/inc/drawdoc.hxx @@ -179,6 +179,7 @@ struct InsertBookmarkOptions bool bNoDialogs; // No dialogs allowed bool bCopy; // Copy source document bool bMergeMasterPages; // Merge master pages + bool bMergeMasterPagesOnly; // Only merge master pages bool bPreservePageNames; // Preserve page names bool bIsClipboardOperation; // Operation triggered by clipboard bool bIsDragAndDropOperation; // Operation triggered by drag and drop @@ -187,60 +188,66 @@ struct InsertBookmarkOptions InsertBookmarkOptions() : bLink(false), bReplace(false), bNoDialogs(false), - bCopy(true), bMergeMasterPages(true), bPreservePageNames(false), - bIsClipboardOperation(false), bIsDragAndDropOperation(false), - bIsSameDocumentOperation(false), bIsFileDocument(false) + bCopy(true), bMergeMasterPages(true), bMergeMasterPagesOnly(false), + bPreservePageNames(false), bIsClipboardOperation(false), + bIsDragAndDropOperation(false), bIsSameDocumentOperation(false), + bIsFileDocument(false) {} // Preset for paste operation - static InsertBookmarkOptions ForPaste(bool bMergeMasterPages) { + static InsertBookmarkOptions ForPaste(bool bMergeMasterPages, bool bMergeMasterPagesOnly = false) { InsertBookmarkOptions options; options.bIsClipboardOperation = true; options.bMergeMasterPages = bMergeMasterPages; + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; // All defaults are fine for paste return options; } // Preset for file insert operation - static InsertBookmarkOptions ForFileInsert(bool bLinkPages) { + static InsertBookmarkOptions ForFileInsert(bool bLinkPages, bool bMergeMasterPagesOnly = false) { InsertBookmarkOptions options; options.bLink = bLinkPages; options.bIsFileDocument = true; + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; return options; } // Preset for drag and drop operation - static InsertBookmarkOptions ForDragDrop(bool bMergeMasterPages) { + static InsertBookmarkOptions ForDragDrop(bool bMergeMasterPages, bool bMergeMasterPagesOnly = false) { InsertBookmarkOptions options; options.bIsDragAndDropOperation = true; options.bNoDialogs = true; options.bMergeMasterPages = bMergeMasterPages; + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; return options; } // Preset for page link resolution - static InsertBookmarkOptions ForPageLinks(bool bCopySource, bool bNoDialogs) { + static InsertBookmarkOptions ForPageLinks(bool bCopySource, bool bNoDialogs, bool bMergeMasterPagesOnly = false) { InsertBookmarkOptions options; options.bLink = true; options.bReplace = true; options.bPreservePageNames = true; options.bCopy = bCopySource; options.bNoDialogs = bNoDialogs; + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; return options; } // Preset for internal document operations - static InsertBookmarkOptions ForInternalOps(bool bPreserveNames) { + static InsertBookmarkOptions ForInternalOps(bool bPreserveNames, bool bMergeMasterPagesOnly = false) { InsertBookmarkOptions options; options.bNoDialogs = true; options.bMergeMasterPages = false; options.bPreservePageNames = bPreserveNames; options.bIsSameDocumentOperation = true; + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; return options; } // Preset for document import operations - static InsertBookmarkOptions ForDocumentImport() { + static InsertBookmarkOptions ForDocumentImport(bool bMergeMasterPagesOnly = false) { InsertBookmarkOptions options; options.bLink = false; // No linking for document import options.bReplace = true; // Replace pages when importing document @@ -249,6 +256,7 @@ struct InsertBookmarkOptions options.bMergeMasterPages = true; // Always merge master pages options.bPreservePageNames = false; // Don't preserve page names options.bIsFileDocument = true; // This is a file document operation + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly;// Only merge master pages return options; } }; @@ -284,11 +292,11 @@ struct DocumentPageCounts sal_uInt16 nMasterPageCount; // Count of master pages in destination document sal_uInt16 nNewMPageCount; // Count of new master pages after processing - DocumentPageCounts(sal_uInt16 destCount, sal_uInt16 sourceCount, sal_uInt16 masterCount) + DocumentPageCounts(sal_uInt16 destCount, sal_uInt16 sourceCount, sal_uInt16 masterCount, sal_uInt16 newmasterCount) : nDestPageCount(destCount) , nSourcePageCount(sourceCount) , nMasterPageCount(masterCount) - , nNewMPageCount(0) + , nNewMPageCount(newmasterCount) {} // Check if all counts are valid (non-zero) @@ -432,7 +440,7 @@ public: */ void insertAllPages(PageInsertionParams& rParams, const InsertBookmarkOptions& rOptions, - const sal_uInt16& nBMSdPageCount); + const DocumentPageCounts& rPageCounts); /** * Determine whether objects should be scaled during insertion @@ -447,7 +455,8 @@ public: void collectLayoutsToTransfer(const PageNameList& rBookmarkList, SdDrawDocument* pBookmarkDoc, SlideLayoutNameList& rLayoutsToTransfer, - const sal_uInt16& nBMSdPageCount); + const DocumentPageCounts& rPageCounts, + bool bMergeMasterPagesOnly); /** * Transfer layout styles from source document to destination @@ -620,6 +629,7 @@ public: * @param nInsertPos Position where pages should be inserted * @param pBookmarkDocSh Source document shell * @param bMergeMasterPages Whether to merge master pages from source + * @param bMergeMasterPagesOnly Whether to only merge master pages (not content pages) * @return true if operation was successful */ bool PasteBookmarkAsPage( @@ -627,7 +637,8 @@ public: PageNameList *pExchangeList, sal_uInt16 nInsertPos, ::sd::DrawDocShell* pBookmarkDocSh, - bool bMergeMasterPages); + bool bMergeMasterPages, + bool bMergeMasterPagesOnly = false); /** * Insert pages from external files @@ -641,6 +652,7 @@ public: * @param bLink Whether to link to the source pages instead of copying * @param nInsertPos Position where pages should be inserted * @param pBookmarkDocSh Source document shell + * @param bMergeMasterPagesOnly Whether to only merge master pages (not content pages) * @return true if operation was successful */ bool InsertFileAsPage( @@ -648,7 +660,8 @@ public: PageNameList *pExchangeList, bool bLink, sal_uInt16 nInsertPos, - ::sd::DrawDocShell* pBookmarkDocSh); + ::sd::DrawDocShell* pBookmarkDocSh, + bool bMergeMasterPagesOnly = false); /** * Handle drag and drop operations @@ -661,13 +674,15 @@ public: * @param nInsertPos Position where pages should be inserted * @param pBookmarkDocSh Source document shell * @param bMergeMasterPages Whether to merge master pages from source + * @param bMergeMasterPagesOnly Whether to only merge master pages (not content pages) * @return true if operation was successful */ bool DropBookmarkAsPage( const PageNameList &rBookmarkList, sal_uInt16 nInsertPos, ::sd::DrawDocShell* pBookmarkDocSh, - bool bMergeMasterPages); + bool bMergeMasterPages, + bool bMergeMasterPagesOnly = false); /** * Resolve page links @@ -680,13 +695,15 @@ public: * @param nInsertPos Position where resolved pages should be inserted * @param bNoDialogs Whether to suppress dialogs during operation * @param bCopy Whether to copy the linked pages + * @param bMergeMasterPagesOnly Whether to only merge master pages (not content pages) * @return true if operation was successful */ bool ResolvePageLinks( const PageNameList &rBookmarkList, sal_uInt16 nInsertPos, bool bNoDialogs, - bool bCopy); + bool bCopy, + bool bMergeMasterPagesOnly = false); /** * Copy or move pages within the same document @@ -699,13 +716,15 @@ public: * @param pExchangeList Optional list of names to use for the destination pages * @param nInsertPos Position where pages should be inserted * @param bPreservePageNames Whether to preserve original page names + * @param bMergeMasterPagesOnly Whether to only merge master pages (not content pages) * @return true if operation was successful */ bool CopyOrMovePagesWithinDocument( const PageNameList &rBookmarkList, PageNameList *pExchangeList, sal_uInt16 nInsertPos, - bool bPreservePageNames); + bool bPreservePageNames, + bool bMergeMasterPagesOnly = false); /** * Import a whole document @@ -717,12 +736,14 @@ public: * @param rBookmarkList List of page names to be imported (empty for all pages) * @param nInsertPos Position where imported pages should be inserted * @param pBookmarkDocSh Source document shell + * @param bMergeMasterPagesOnly Whether to only merge master pages (not content pages) * @return true if operation was successful */ bool ImportDocumentPages( const PageNameList &rBookmarkList, sal_uInt16 nInsertPos, - ::sd::DrawDocShell* pBookmarkDocSh); + ::sd::DrawDocShell* pBookmarkDocSh, + bool bMergeMasterPagesOnly = false); SAL_DLLPRIVATE bool InsertBookmarkAsObject(const PageNameList &rBookmarkList, const PageNameList &rExchangeList, @@ -818,7 +839,7 @@ public: SAL_DLLPRIVATE void SetTextDefaults() const; SAL_DLLPRIVATE void CreateLayoutTemplates(); - SAL_DLLPRIVATE void RenameLayoutTemplate(const OUString& rOldLayoutName, const OUString& rNewName); + void RenameLayoutTemplate(const OUString& rOldLayoutName, const OUString& rNewName); SAL_DLLPRIVATE void CreateDefaultCellStyles(); @@ -975,6 +996,18 @@ public: SAL_DLLPRIVATE static void SetCalcFieldValueHdl( ::Outliner* pOutliner); + /** Extract the base layout name from a layout name by removing the separator and anything after it + * @param rLayoutName The full layout name that may include a separator and suffix + * @return The base layout name without separator and suffix + */ + static OUString GetBaseLayoutName(std::u16string_view rLayoutName); + + /** Generate a new layout name based on the original name by appending a number to it + * @param aOriginalName The original layout name + * @return A new layout name that is unique and based on the original name + */ + static OUString GenerateNewLayoutName(std::u16string_view rOriginalName); + SAL_DLLPRIVATE sal_uInt16 GetAnnotationAuthorIndex( const OUString& rAuthor ); SAL_DLLPRIVATE bool IsEmbedFonts() const { return mbEmbedFonts; } @@ -994,6 +1027,21 @@ public: void dumpAsXml(xmlTextWriterPtr pWriter) const override; + /** Create a new master page based on an existing master page. + * This function is useful for copy/paste operations of master pages. + * + * @param pSourceMasterPage The master page to copy from. + * @param pBookmarkDoc The document containing the source master page. If null, assumes this document. + * @param bUndo Whether to support undo for this operation. + * @param sNewName Optional new name for the master page. If empty, a new name will be generated. + * @return The newly created master page. + */ + SdPage* AddNewMasterPageFromExisting( + SdPage* pSourceMasterPage, + SdDrawDocument* pBookmarkDoc = nullptr, + bool bUndo = true, + const OUString& sNewName = OUString()); + private: void UpdatePageRelativeURLsImpl(const std::function<void(const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback); diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx index e0f0b7db26ff..dd21f9a7b0a4 100644 --- a/sd/qa/unit/uiimpress.cxx +++ b/sd/qa/unit/uiimpress.cxx @@ -607,6 +607,443 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf96708) CPPUNIT_ASSERT_EQUAL(sal_uInt16(5), nMasterPageCnt2); } +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_default_master) +{ + // Copying/pasting slide referring to a master page. + createSdImpressDoc("odp/tdf96206.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + const sal_uInt16 nMasterPageCnt1 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), nMasterPageCnt1); + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + const sal_uInt16 nMasterPageCnt2 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(nMasterPageCnt1 + 1), nMasterPageCnt2); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617) +{ + // Copying/pasting slide referring to a master page. + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + const sal_uInt16 nMasterPageCnt1 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), nMasterPageCnt1); + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + const sal_uInt16 nMasterPageCnt2 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(nMasterPageCnt1 + 1), nMasterPageCnt2); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_test_master_name) +{ + // Copying/pasting slide referring to a master page. + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + // Get the master page name + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Master0"_ustr, aMasterPageName); + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Master0"_ustr, aNewMasterPageName); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_test_defult_master_name) +{ + // Copying/pasting slide referring to a master page. + createSdImpressDoc(); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + // Get the master page name + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Default"_ustr, aMasterPageName); + + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Default"_ustr, aNewMasterPageName); + + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage2 = pDoc->GetMasterSdPage(1, PageKind::Standard); + OUString aNewMasterPageName2 = pNewMasterPage2->GetName(); + CPPUNIT_ASSERT_EQUAL(u"2_Default"_ustr, aNewMasterPageName2); +} +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_basic_master_name) +{ + // Basic test for copying/pasting slide referring to a master page + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Master0"_ustr, aMasterPageName); + + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Master0"_ustr, aNewMasterPageName); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_leading_underscore_master_name) +{ + // Test master page name with underscore at first position + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + // Rename the master page with leading underscore + pDoc->RenameLayoutTemplate(pMasterPage->GetLayoutName(), "_Master0"); + + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"_Master0"_ustr, aMasterPageName); + + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1__Master0"_ustr, aNewMasterPageName); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_middle_underscore_master_name) +{ + // Test master page name with underscore in the middle + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + // Rename the master page with middle underscore + pDoc->RenameLayoutTemplate(pMasterPage->GetLayoutName(), "Master_0"); + + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Master_0"_ustr, aMasterPageName); + + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Master_0"_ustr, aNewMasterPageName); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_trailing_underscore_master_name) +{ + // Test master page name with underscore at the end + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + // Rename the master page with trailing underscore + pDoc->RenameLayoutTemplate(pMasterPage->GetLayoutName(), "Master0_"); + + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Master0_"_ustr, aMasterPageName); + + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Master0_"_ustr, aNewMasterPageName); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_space_in_master_name) +{ + // Test master page name with space in the middle + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + // Rename the master page with space in the middle + pDoc->RenameLayoutTemplate(pMasterPage->GetLayoutName(), "Master 0"); + + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Master 0"_ustr, aMasterPageName); + + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Master 0"_ustr, aNewMasterPageName); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_Double_Copy) +{ + // Test master page name with double copy + createSdImpressDoc(); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + // Set edit master page mode + rSSController.ChangeEditMode(EditMode::MasterPage); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + // Get the master page name + const sal_uInt16 nMasterPageCnt1 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), nMasterPageCnt1); + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + // Rename the master page with master name + pDoc->RenameLayoutTemplate(pMasterPage->GetLayoutName(), "master"); + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"master"_ustr, aMasterPageName); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + + // Copy and paste the master page + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt2 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), nMasterPageCnt2); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(1, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_master"_ustr, aNewMasterPageName); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + const sal_uInt16 nMasterPageCnt3 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(3), nMasterPageCnt3); + SdPage* pNewMasterPage2 = pDoc->GetMasterSdPage(2, PageKind::Standard); + OUString aNewMasterPageName2 = pNewMasterPage2->GetName(); + CPPUNIT_ASSERT_EQUAL(u"2_master"_ustr, aNewMasterPageName2); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt4 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(4), nMasterPageCnt4); + SdPage* pNewMasterPage3 = pDoc->GetMasterSdPage(3, PageKind::Standard); + OUString aNewMasterPageName3 = pNewMasterPage3->GetName(); + CPPUNIT_ASSERT_EQUAL(u"3_master"_ustr, aNewMasterPageName3); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_Double_Copy_Default) +{ + // Test master page name with double copy + createSdImpressDoc(); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + // Set edit master page mode + rSSController.ChangeEditMode(EditMode::MasterPage); + + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + + // Get the master page name + const sal_uInt16 nMasterPageCnt1 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), nMasterPageCnt1); + SdPage* pMasterPage = pDoc->GetMasterSdPage(0, PageKind::Standard); + // Rename the master page with default name + pDoc->RenameLayoutTemplate(pMasterPage->GetLayoutName(), "Default"); + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Default"_ustr, aMasterPageName); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + + // Copy and paste the master page + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt2 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(2), nMasterPageCnt2); + + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(1, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Default"_ustr, aNewMasterPageName); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + const sal_uInt16 nMasterPageCnt3 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(3), nMasterPageCnt3); + SdPage* pNewMasterPage2 = pDoc->GetMasterSdPage(2, PageKind::Standard); + OUString aNewMasterPageName2 = pNewMasterPage2->GetName(); + CPPUNIT_ASSERT_EQUAL(u"2_Default"_ustr, aNewMasterPageName2); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + const sal_uInt16 nMasterPageCnt4 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(4), nMasterPageCnt4); + SdPage* pNewMasterPage3 = pDoc->GetMasterSdPage(3, PageKind::Standard); + OUString aNewMasterPageName3 = pNewMasterPage3->GetName(); + CPPUNIT_ASSERT_EQUAL(u"3_Default"_ustr, aNewMasterPageName3); +} +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf45617_Double_Copy_CopiedPage) +{ + // Test master page name with double copy for copied page which dosen`t have a normal page created + createSdImpressDoc("odp/tdf96708.odp"); + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + // Set edit master page mode + rSSController.ChangeEditMode(EditMode::MasterPage); + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + // Get the master page name + const sal_uInt16 nMasterPageCnt1 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), nMasterPageCnt1); + SdPage* pMasterPage = pDoc->GetMasterSdPage(3, PageKind::Standard); + OUString aMasterPageName = pMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"Master3"_ustr, aMasterPageName); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pMasterPage); + // Copy and paste the master page + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt2 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(5), nMasterPageCnt2); + SdPage* pNewMasterPage = pDoc->GetMasterSdPage(4, PageKind::Standard); + OUString aNewMasterPageName = pNewMasterPage->GetName(); + CPPUNIT_ASSERT_EQUAL(u"1_Master3"_ustr, aNewMasterPageName); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pNewMasterPage); + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt3 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(6), nMasterPageCnt3); + SdPage* pNewMasterPage2 = pDoc->GetMasterSdPage(5, PageKind::Standard); + OUString aNewMasterPageName2 = pNewMasterPage2->GetName(); + CPPUNIT_ASSERT_EQUAL(u"2_Master3"_ustr, aNewMasterPageName2); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pNewMasterPage2); + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt4 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(7), nMasterPageCnt4); + SdPage* pNewMasterPage3 = pDoc->GetMasterSdPage(6, PageKind::Standard); + OUString aNewMasterPageName3 = pNewMasterPage3->GetName(); + CPPUNIT_ASSERT_EQUAL(u"3_Master3"_ustr, aNewMasterPageName3); + + // Reslect the master page + rSSController.GetPageSelector().DeselectAllPages(); + rSSController.GetPageSelector().SelectPage(pNewMasterPage); + // Copy again + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + const sal_uInt16 nMasterPageCnt5 = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(8), nMasterPageCnt5); + SdPage* pNewMasterPage4 = pDoc->GetMasterSdPage(7, PageKind::Standard); + OUString aNewMasterPageName4 = pNewMasterPage4->GetName(); + CPPUNIT_ASSERT_EQUAL(u"4_Master3"_ustr, aNewMasterPageName4); +} +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testUndoMergeMasterPage) +{ + // Test undo for merging master pages only + createSdImpressDoc("odp/tdf96708.odp"); + + sd::slidesorter::SlideSorterViewShell* pSSVS = getSlideSorterViewShell(); + auto& rSSController = pSSVS->GetSlideSorter().GetController(); + + // Get document and check initial master page count + SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + SdDrawDocument* pDoc = pXImpressDocument->GetDoc(); + const sal_uInt16 nInitialMasterPageCount = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), nInitialMasterPageCount); + + // Copy and paste master page only + rSSController.GetClipboard().DoCopy(true); + rSSController.GetClipboard().DoPaste(true); + + // Check that a master page was added + const sal_uInt16 nAfterPasteMasterPageCount = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(nInitialMasterPageCount + 1), + nAfterPasteMasterPageCount); + + // Undo the master page merge + dispatchCommand(mxComponent, u".uno:Undo"_ustr, {}); + + // Check that the master page count is back to the initial value + const sal_uInt16 nAfterUndoMasterPageCount = pDoc->GetMasterSdPageCount(PageKind::Standard); + CPPUNIT_ASSERT_EQUAL(nInitialMasterPageCount, nAfterUndoMasterPageCount); +} + CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf139996) { createSdImpressDoc(); diff --git a/sd/source/core/drawdoc3.cxx b/sd/source/core/drawdoc3.cxx index d3086d03f76e..dfad98ded58e 100644 --- a/sd/source/core/drawdoc3.cxx +++ b/sd/source/core/drawdoc3.cxx @@ -69,21 +69,18 @@ class InsertBookmarkAsPage_FindDuplicateLayouts public: explicit InsertBookmarkAsPage_FindDuplicateLayouts( std::vector<OUString> &rLayoutsToTransfer ) : mrLayoutsToTransfer(rLayoutsToTransfer) {} - void operator()( SdDrawDocument&, SdPage const *, bool, SdDrawDocument* ); + void operator()( SdDrawDocument&, SdPage const *, bool bRenameDuplicates, SdDrawDocument* pBookmarkDoc, bool bMergeMasterPagesOnly); private: std::vector<OUString> &mrLayoutsToTransfer; }; } -void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage const * pBMMPage, bool bRenameDuplicates, SdDrawDocument* pBookmarkDoc ) +void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage const * pBMMPage, bool bRenameDuplicates, SdDrawDocument* pBookmarkDoc, bool bMergeMasterPagesOnly ) { // now check for duplicate masterpage and layout names - OUString aLayout( pBMMPage->GetLayoutName() ); - sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR ); - if( nIndex != -1 ) - aLayout = aLayout.copy(0, nIndex); + OUString aLayout = SdDrawDocument::GetBaseLayoutName( pBMMPage->GetLayoutName() ); std::vector<OUString>::const_iterator pIter = find(mrLayoutsToTransfer.begin(), mrLayoutsToTransfer.end(), aLayout); @@ -104,15 +101,23 @@ void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc { // Ignore Layouts with "Default" these seem to be special - in the sense that there are lot of assumption all over Impress // about this - if( bRenameDuplicates && aTest != SdResId( STR_LAYOUT_DEFAULT_NAME ) && !(pTestPage->Equals(*pBMMPage)) ) + if (aTest != SdResId(STR_LAYOUT_DEFAULT_NAME) || bMergeMasterPagesOnly) { - OUString aOldPageLayoutName = pBMMPage->GetLayoutName(); - pBookmarkDoc->RenameLayoutTemplate(aOldPageLayoutName, pBMMPage->GetName() + "_"); - aLayout = pBMMPage->GetName(); - break; + // If we are merging master pages only, or if we are renaming duplicates and the page is not the same, then we need to rename the layout + if ( bMergeMasterPagesOnly ||(bRenameDuplicates && !(pTestPage->Equals(*pBMMPage)))) + { + OUString aOriginalName = pBMMPage->GetName(); + OUString aNewName; + // Generate a new name with incremented numeric prefix + aNewName = SdDrawDocument::GenerateNewLayoutName(aOriginalName); + OUString aOldLayoutName = pBMMPage->GetLayoutName(); + pBookmarkDoc->RenameLayoutTemplate(aOldLayoutName,aNewName); + aLayout = pBMMPage->GetName(); + break; + } + else + bFound = true; } - else - bFound = true; } } @@ -122,8 +127,8 @@ void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc // Inserts a bookmark as a page static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBookmarkDoc, - const std::vector<OUString> &rBookmarkList, sal_uInt16 nBMSdPageCount, - InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator, bool bRenameDuplicates ) + const std::vector<OUString> &rBookmarkList, sal_uInt16 nCount, + InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator, bool bRenameDuplicates, bool bMergeMasterPagesOnly = false) { // Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage @@ -133,7 +138,7 @@ static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBoo if( rBookmarkList.empty() ) { // no list? whole source document - nEndPos = nBMSdPageCount; + nEndPos = nCount; } else { @@ -152,7 +157,10 @@ static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBoo if( rBookmarkList.empty() ) { // simply take master page of nPos'th page in source document - pBMMPage = static_cast<SdPage*>(&(pBookmarkDoc->GetSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard)->TRG_GetMasterPage())); + if (bMergeMasterPagesOnly) + pBMMPage = pBookmarkDoc->GetMasterSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard); + else + pBMMPage = static_cast<SdPage*>(&(pBookmarkDoc->GetSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard)->TRG_GetMasterPage())); } else { @@ -164,7 +172,10 @@ static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBoo if (nBMPage != SDRPAGE_NOTFOUND) { - pBMPage = static_cast<SdPage*>( pBookmarkDoc->GetPage(nBMPage) ); + if (bIsMasterPage) + pBMPage = static_cast<SdPage*>( pBookmarkDoc->GetMasterPage(nBMPage) ); + else + pBMPage = static_cast<SdPage*>( pBookmarkDoc->GetPage(nBMPage) ); } else { @@ -183,7 +194,7 @@ static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBoo if( pBMMPage ) { // yes, call functor - rPageIterator( rDoc, pBMMPage, bRenameDuplicates, pBookmarkDoc ); + rPageIterator( rDoc, pBMMPage, bRenameDuplicates, pBookmarkDoc, bMergeMasterPagesOnly ); } } } @@ -485,10 +496,12 @@ SfxUndoManager* SdDrawDocument::beginUndoAction() void SdDrawDocument::collectLayoutsToTransfer(const PageNameList& rBookmarkList, SdDrawDocument* pBookmarkDoc, SlideLayoutNameList& aLayoutsToTransfer, - const sal_uInt16& nBMSdPageCount) + const DocumentPageCounts& rPageCounts, + bool bMergeMasterPagesOnly) { + sal_uInt16 nCount = bMergeMasterPagesOnly ? rPageCounts.nMasterPageCount : rPageCounts.nSourcePageCount;// Replace by pageCounts to add the masterpagecount InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor(aLayoutsToTransfer); - lcl_IterateBookmarkPages( *this, pBookmarkDoc, rBookmarkList, nBMSdPageCount, aSearchFunctor, ( rBookmarkList.empty() && pBookmarkDoc != this ) ); + lcl_IterateBookmarkPages( *this, pBookmarkDoc, rBookmarkList, nCount, aSearchFunctor, ( rBookmarkList.empty() && pBookmarkDoc != this ), bMergeMasterPagesOnly ); } void SdDrawDocument::transferLayoutStyles(const SlideLayoutNameList& aLayoutsToTransfer, @@ -563,7 +576,7 @@ void SdDrawDocument::copyStyles(bool bReplace, bool bNoDialogs, void SdDrawDocument::insertAllPages(PageInsertionParams& rParams, const InsertBookmarkOptions& rOptions, - const sal_uInt16& nBMSdPageCount) + const DocumentPageCounts& rPageCounts) { // Adjust insertion position if needed. if (rParams.nInsertPos >= GetPageCount()) @@ -571,12 +584,49 @@ void SdDrawDocument::insertAllPages(PageInsertionParams& rParams, sal_uInt16 nActualInsertPos = rParams.nInsertPos; + // First, handle master pages. + if (rOptions.bMergeMasterPagesOnly) + { + // Insert all master pages from the bookmark document. + sal_uInt16 nMPageCount = rParams.pBookmarkDoc->GetMasterPageCount(); + // During the copy process, a vector holds the master page slides: + // - default handout page, + // - default standard page, + // - and default notes page. + // + // Normally, new master slides are added, so we start targeting from index 3. + // If the copied slide matches the existing "Default" name, no new slides are added; + // we then start from index 1, skipping the handout. + sal_uInt16 nStart = (nMPageCount % 2) + 2; + if (nStart == nMPageCount) + nStart = 1; + // Process all master pages. + for (sal_uInt16 nMPage = nStart; nMPage < nMPageCount; nMPage++) + { + SdPage* pSBMPage = static_cast<SdPage*>(rParams.pBookmarkDoc->GetMasterPage(nMPage)); + + // Only process standard pages + if (pSBMPage && pSBMPage->GetPageKind() == PageKind::Standard && pSBMPage->IsMasterPage()) + { + OUString aLayoutName(pSBMPage->GetName()); + if (aLayoutName == SdResId(STR_LAYOUT_DEFAULT_NAME)) + { + // Default page -> use default name + aLayoutName = OUString(); + } + AddNewMasterPageFromExisting(pSBMPage, rParams.pBookmarkDoc, rParams.bUndo, aLayoutName); + } + + } + return ; + } + sal_uInt16 nBMSdPage; // Build a name map and a set for pages that need renaming. std::set<sal_uInt16> aRenameSet; std::map<sal_uInt16, OUString> aNameMap; - for (nBMSdPage = 0; nBMSdPage < nBMSdPageCount; nBMSdPage++) + for (nBMSdPage = 0; nBMSdPage < rPageCounts.nSourcePageCount; nBMSdPage++) { SdPage* pBMPage = rParams.pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard); OUString sName(pBMPage->GetName()); @@ -609,7 +659,7 @@ void SdDrawDocument::insertAllPages(PageInsertionParams& rParams, rOptions.bCopy); // Copy (or merge) pages? // After merging, fix names and set link info if needed. - for ( nBMSdPage = 0; nBMSdPage < nBMSdPageCount; nBMSdPage++) + for ( nBMSdPage = 0; nBMSdPage < rPageCounts.nSourcePageCount; nBMSdPage++) { SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) ); SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos + 1) ); @@ -628,6 +678,7 @@ void SdDrawDocument::insertAllPages(PageInsertionParams& rParams, pPage->SetFileName(rParams.aBookmarkName); pPage->SetBookmarkName(aNameMap[nBMSdPage]); } + nActualInsertPos += 2; } } @@ -656,8 +707,31 @@ void SdDrawDocument::insertSelectedPages(const PageNameList& rBookmarkList, if (nBMPage != SDRPAGE_NOTFOUND) { - aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(rParams.pBookmarkDoc->GetPage(nBMPage)); + if (rOptions.bMergeMasterPagesOnly) + { + // Only the master page + aBookmarkedPages[nPos] = static_cast<SdPage*>(rParams.pBookmarkDoc->GetMasterPage(nBMPage)); + } + else + { + // The standard page + aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(rParams.pBookmarkDoc->GetPage(nBMPage)); + } + } + } + + if (rOptions.bMergeMasterPagesOnly) + { + for (size_t nPos = 0; nPos < rBookmarkList.size(); ++nPos) + { + SdPage* pBMPage = aBookmarkedPages[nPos]; + if (pBMPage && pBMPage->GetPageKind() == PageKind::Standard && pBMPage->IsMasterPage()) + { + // It has to be a default page + AddNewMasterPageFromExisting(pBMPage, rParams.pBookmarkDoc, rParams.bUndo, pBMPage->GetName()); + } } + return; } // Process each bookmarked page. @@ -685,7 +759,7 @@ void SdDrawDocument::insertSelectedPages(const PageNameList& rBookmarkList, SdPage* pBookmarkPage = pBMPage; if (rOptions.bReplace) - ReplacePageInCustomShows(dynamic_cast<SdPage*>(GetPage(nActualInsertPos)), pBMPage); + ReplacePageInCustomShows(dynamic_cast<SdPage*>(GetPage(nActualInsertPos)), pBookmarkPage); Merge(*rParams.pBookmarkDoc, nBMPage, // From page (default page) @@ -699,7 +773,7 @@ void SdDrawDocument::insertSelectedPages(const PageNameList& rBookmarkList, if (rOptions.bReplace && GetPage(nActualInsertPos) != pBookmarkPage) { // bookmark page was not moved but cloned, so update custom shows again - ReplacePageInCustomShows(pBMPage, dynamic_cast<SdPage*>(GetPage(nActualInsertPos))); + ReplacePageInCustomShows(pBookmarkPage, dynamic_cast<SdPage*>(GetPage(nActualInsertPos))); } // tdf#39519 - rename page if its name is not unique, e.g., if a slide is copied by // ctrl + drag and drop (DND_ACTION_COPY) @@ -820,6 +894,10 @@ void SdDrawDocument::updateInsertedPages(PageInsertionParams& rParams, const DocumentPageCounts& rPageCounts, StyleTransferContext& rStyleContext) { + // If we are copying master pages only, we don't need to update the pages. + if (rOptions.bMergeMasterPagesOnly) + return; + // Update page names (from pExchangeList), layouts, scaling, etc. sal_uInt16 nSdPageStart = (rParams.nInsertPos - 1) / 2; sal_uInt16 nSdPageEnd = rOptions.bReplace @@ -849,10 +927,7 @@ void SdDrawDocument::updateInsertedPages(PageInsertionParams& rParams, ++pExchangeIter; } - OUString aLayout(rParams.mainProps.pPage->GetLayoutName()); - sal_Int32 nIndex = aLayout.indexOf(SD_LT_SEPARATOR); - if (nIndex != -1) - aLayout = aLayout.copy(0, nIndex); + OUString aLayout = GetBaseLayoutName(rParams.mainProps.pPage->GetLayoutName()); // update layout and referred master page rParams.mainProps.pPage->SetPresentationLayout(aLayout); @@ -871,12 +946,12 @@ void SdDrawDocument::updateInsertedPages(PageInsertionParams& rParams, if (bRemoveEmptyPresObj) rParams.mainProps.pPage->RemoveEmptyPresentationObjects(); - rParams.mainProps.pPage = GetSdPage(nSdPage, PageKind::Notes); + rParams.notesProps.pPage = GetSdPage(nSdPage, PageKind::Notes); // update layout and referred master page - rParams.mainProps.pPage->SetPresentationLayout(aLayout); + rParams.notesProps.pPage->SetPresentationLayout(aLayout); if (rParams.bUndo) - AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*rParams.mainProps.pPage)); + AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*rParams.notesProps.pPage)); if (rParams.bScaleObjects) { @@ -884,12 +959,12 @@ void SdDrawDocument::updateInsertedPages(PageInsertionParams& rParams, rParams.notesProps.pPage->ScaleObjects(rParams.notesProps.size, aBorderRect, true); } - rParams.mainProps.pPage->SetSize(rParams.notesProps.size); - rParams.mainProps.pPage->SetBorder(rParams.notesProps.left, rParams.notesProps.upper, rParams.notesProps.right, rParams.notesProps.lower); - rParams.mainProps.pPage->SetOrientation(rParams.notesProps.orientation); + rParams.notesProps.pPage->SetSize(rParams.notesProps.size); + rParams.notesProps.pPage->SetBorder(rParams.notesProps.left, rParams.notesProps.upper, rParams.notesProps.right, rParams.notesProps.lower); + rParams.notesProps.pPage->SetOrientation(rParams.notesProps.orientation); if (bRemoveEmptyPresObj) - rParams.mainProps.pPage->RemoveEmptyPresentationObjects(); + rParams.notesProps.pPage->RemoveEmptyPresentationObjects(); } ///Remove processed elements, to avoid doing hacks in InsertBookmarkAsObject if (rParams.pExchangeList) @@ -1162,6 +1237,62 @@ bool SdDrawDocument::InsertBookmarkAsObject( return bOK; } +OUString SdDrawDocument::GetBaseLayoutName(std::u16string_view rLayoutName) +{ + OUString aBaseName(rLayoutName); + sal_Int32 nIndex = aBaseName.indexOf(SD_LT_SEPARATOR); + if (nIndex != -1) + aBaseName = aBaseName.copy(0, nIndex); + + return aBaseName; +} + +OUString SdDrawDocument::GenerateNewLayoutName(std::u16string_view rOriginalName) +{ + // Generate a new name with incremented numeric prefix + OUString aOriginalName(rOriginalName); + OUString aNewName; + sal_uInt32 nCount = 1; + + // Check if name already has a number prefix + int nUnderscorePos = aOriginalName.indexOf( "_" ); + if (nUnderscorePos > 0) + { + // Try to extract the number part + OUString aPrefix = aOriginalName.copy(0, nUnderscorePos); + + // Check if the prefix is a valid number + bool bIsNumber = true; + for (sal_Int32 i = 0; i < aPrefix.getLength(); ++i) + { + if (!isdigit(aPrefix[i])) + { + bIsNumber = false; + break; + } + } + if (bIsNumber) + { + // If it is a number, increment it + nCount = aPrefix.toInt32() + 1; + OUString aBaseName = aOriginalName.copy(nUnderscorePos + 1); + aNewName = OUString::number(nCount) + "_" + aBaseName; + } + else + { + // Has underscore but not a number, just append "1_" + aNewName = "1_" + aOriginalName; + } + } + else + { + // If no number prefix, just append "1_" + aNewName = "1_" + aOriginalName; + } + + return aNewName; +} + // Stops the bookmark insertion void SdDrawDocument::CloseBookmarkDoc() { @@ -1372,10 +1503,7 @@ static bool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, std::u16str for(sal_uInt16 a(0); a < nPageCount; a++) { const SdPage* pCandidate = static_cast<const SdPage*>(rDoc.GetMasterPage(a)); - OUString aPageLayoutName(pCandidate->GetLayoutName()); - sal_Int32 nIndex = aPageLayoutName.indexOf(SD_LT_SEPARATOR); - if( nIndex != -1 ) - aPageLayoutName = aPageLayoutName.copy(0, nIndex); + OUString aPageLayoutName = SdDrawDocument::GetBaseLayoutName(pCandidate->GetLayoutName()); if(aPageLayoutName == rCandidate) { @@ -1435,10 +1563,7 @@ void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum, rtl::Reference<SdPage> pMaster; rtl::Reference<SdPage> pNotesMaster; OUString aOldPageLayoutName(pSelectedPage->GetLayoutName()); - OUString aOldLayoutName(aOldPageLayoutName); - sal_Int32 nIndex = aOldLayoutName.indexOf( SD_LT_SEPARATOR ); - if( nIndex != -1 ) - aOldLayoutName = aOldLayoutName.copy(0, nIndex); + OUString aOldLayoutName = GetBaseLayoutName(aOldPageLayoutName); if (pSourceDoc) { @@ -1906,7 +2031,7 @@ void SdDrawDocument::Merge(SdrModel& rSourceModel, bool bUndo, bool bTreadSourceAsConst) { sal_uInt16 nMasterPageCount = GetMasterPageCount(); - SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst ); + SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst); // add style family for each new master page for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ ) @@ -1922,16 +2047,121 @@ void SdDrawDocument::Merge(SdrModel& rSourceModel, } } +SdPage* SdDrawDocument::AddNewMasterPageFromExisting( + SdPage* pSourceMasterPage, + SdDrawDocument* pBookmarkDoc, + bool bUndo, + const OUString& sNewName) +{ + // Check if the source master page is valid and a master page + assert(pSourceMasterPage && pSourceMasterPage->IsMasterPage() && + "AddNewMasterPageFromExisting: Source must be a valid master page"); + + // If bookmark document not provided, assume it's from this document + if (!pBookmarkDoc) + pBookmarkDoc = this; + + // Setup undo management + SfxUndoManager* pUndoMgr = nullptr; + if (bUndo && IsUndoEnabled()) + { + pUndoMgr = GetDocSh()->GetUndoManager(); + pUndoMgr->EnterListAction(SdResId(STR_INSERTPAGE), OUString(), 0, ViewShellId(-1)); + } + + // Find a new name for the layout or use provided name + OUString aName = sNewName.isEmpty() ? createNewMasterPageLayoutName(*this) : sNewName; + OUString aPageLayoutName(aName + SD_LT_SEPARATOR + STR_LAYOUT_OUTLINE); + + // Check if the layout name is unique + // If not, generate a new name until it is unique + while (!isMasterPageLayoutNameUnique(*this, aName)) + { + aName = GenerateNewLayoutName(aName); + aPageLayoutName = aName + SD_LT_SEPARATOR + STR_LAYOUT_OUTLINE; + } + + // Generate new stylesheets + SdStyleSheetPool* pStylePool = static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get()); + StyleSheetCopyResultVector aCreatedStyles; + + // Copy layout sheets from the source page's name to the new name + OUString sSourceLayoutName = GetBaseLayoutName(pSourceMasterPage->GetLayoutName()); + + // Create the style transfer context + StyleTransferContext aStyleContext( + static_cast<SdStyleSheetPool*>(pBookmarkDoc->mxStyleSheetPool.get()), + pStylePool); + + // Copy layout sheets + pStylePool->CopyLayoutSheets(sSourceLayoutName, *pStylePool, aCreatedStyles); + + if(!aCreatedStyles.empty() && bUndo && pUndoMgr) + { + pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aCreatedStyles, true)); + } + + if(bUndo && pUndoMgr) + BegUndo(); + + // Clone the master slide page across documents + rtl::Reference<SdPage> pMaster(dynamic_cast<SdPage*>( + pSourceMasterPage->CloneSdrPage(*this).get())); + + pMaster->SetName(aName); + pMaster->SetLayoutName(aPageLayoutName); + InsertMasterPage(pMaster.get()); + + if(bUndo && pUndoMgr) + AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster)); + + // Find the notes master page that corresponds to the source master page + SdPage* pSourceNotesMaster = nullptr; + for (sal_uInt16 i = 0; i < pBookmarkDoc->GetMasterPageCount(); i++) + { + SdPage* pPage = static_cast<SdPage*>(pBookmarkDoc->GetMasterPage(i)); + if (pPage && pPage->GetPageKind() == PageKind::Notes && + pPage->GetLayoutName() == pSourceMasterPage->GetLayoutName()) + { + pSourceNotesMaster = pPage; + break; + } + } + + // Clone the notes master page if found + if (pSourceNotesMaster) + { + rtl::Reference<SdPage> pNotesMaster(dynamic_cast<SdPage*>( + pSourceNotesMaster->CloneSdrPage(*this).get())); + + pNotesMaster->SetName(aName); + pNotesMaster->SetLayoutName(aPageLayoutName); + InsertMasterPage(pNotesMaster.get()); + + if(bUndo && pUndoMgr) + AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster)); + } + + if(bUndo && pUndoMgr) + { + EndUndo(); + pUndoMgr->LeaveListAction(); + } + + return pMaster.get(); +} + // Paste pages from clipboard - handles regular paste operations bool SdDrawDocument::PasteBookmarkAsPage( const PageNameList &rBookmarkList, PageNameList *pExchangeList, sal_uInt16 nInsertPos, ::sd::DrawDocShell* pBookmarkDocSh, - bool bMergeMasterPages) + bool bMergeMasterPages, + bool bMergeMasterPagesOnly) { - // Use predefined options for clipboard paste operation - InsertBookmarkOptions options = InsertBookmarkOptions::ForPaste(bMergeMasterPages); + // Use predefined options for paste operation + InsertBookmarkOptions options = InsertBookmarkOptions::ForPaste(bMergeMasterPages, bMergeMasterPagesOnly); // Create insertion parameters PageInsertionParams aInsertParams(nInsertPos, pExchangeList); @@ -1942,7 +2172,9 @@ bool SdDrawDocument::PasteBookmarkAsPage( DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), - GetMasterPageCount()); + GetMasterPageCount(), + aInsertParams.pBookmarkDoc->GetMasterPageCount()); + if (!pageCounts.areValid()) { @@ -1962,7 +2194,7 @@ bool SdDrawDocument::PasteBookmarkAsPage( // Collect layout names that need to be transferred SlideLayoutNameList aLayoutsToTransfer; - collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts.nSourcePageCount); + collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts, options.bMergeMasterPagesOnly); // Copy the style that we actually need. SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*aInsertParams.pBookmarkDoc->GetStyleSheetPool()); @@ -1970,7 +2202,7 @@ bool SdDrawDocument::PasteBookmarkAsPage( // When copying styles, also copy the master pages! if (!aLayoutsToTransfer.empty()) - bMergeMasterPages = true; + options.bMergeMasterPages = true; // Create a StyleTransferContext with the style sheet pools StyleTransferContext aStyleContext(&rBookmarkStyleSheetPool, &rStyleSheetPool); @@ -1993,7 +2225,7 @@ bool SdDrawDocument::PasteBookmarkAsPage( // Insert pages based on whether all or selected pages are bookmarked. if (rBookmarkList.empty()) { - insertAllPages(aInsertParams, options, pageCounts.nSourcePageCount); + insertAllPages(aInsertParams, options, pageCounts);//reblce by pageCounts to add the masterpagecount } else { @@ -2002,7 +2234,8 @@ bool SdDrawDocument::PasteBookmarkAsPage( } // Remove duplicate master pages that may have been created. - removeDuplicateMasterPages(aInsertParams, pageCounts); + if (!options.bMergeMasterPagesOnly) + removeDuplicateMasterPages(aInsertParams, pageCounts); // nInsertPos > 2 is always true when inserting into non-empty models if (nInsertPos > 0) { @@ -2010,7 +2243,8 @@ bool SdDrawDocument::PasteBookmarkAsPage( } // Make absolutely sure no double masterpages are there - RemoveUnnecessaryMasterPages(nullptr, true); + if (!options.bMergeMasterPagesOnly) + RemoveUnnecessaryMasterPages(nullptr, true); // Rename object styles if necessary renameObjectStylesIfNeeded(nInsertPos, aStyleContext, pageCounts.nSourcePageCount); @@ -2033,10 +2267,12 @@ bool SdDrawDocument::ResolvePageLinks( const PageNameList &rBookmarkList, sal_uInt16 nInsertPos, bool bNoDialogs, - bool bCopy) + bool bCopy, + bool bMergeMasterPagesOnly) { // Use predefined options for page link resolution InsertBookmarkOptions options = InsertBookmarkOptions::ForPageLinks(bCopy, bNoDialogs); + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; // Create insertion parameters PageInsertionParams aInsertParams(nInsertPos); @@ -2045,7 +2281,10 @@ bool SdDrawDocument::ResolvePageLinks( if (!initBookmarkDoc(nullptr, aInsertParams.pBookmarkDoc, aInsertParams.aBookmarkName)) return false; - DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), GetMasterPageCount()); + DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), + aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), + GetMasterPageCount(), + aInsertParams.pBookmarkDoc->GetMasterPageCount()); if (!pageCounts.areValid()) { @@ -2064,7 +2303,7 @@ bool SdDrawDocument::ResolvePageLinks( // Collect layout names that need to be transferred SlideLayoutNameList aLayoutsToTransfer; - collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts.nSourcePageCount); + collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts, options.bMergeMasterPagesOnly); // Copy the style that we actually need. SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*aInsertParams.pBookmarkDoc->GetStyleSheetPool()); @@ -2090,7 +2329,7 @@ bool SdDrawDocument::ResolvePageLinks( if (rBookmarkList.empty()) { - insertAllPages(aInsertParams, options, pageCounts.nSourcePageCount); + insertAllPages(aInsertParams, options, pageCounts); } else { @@ -2099,13 +2338,15 @@ bool SdDrawDocument::ResolvePageLinks( } // Remove duplicate master pages that may have been created. - removeDuplicateMasterPages(aInsertParams, pageCounts); + if (!options.bMergeMasterPagesOnly) + removeDuplicateMasterPages(aInsertParams, pageCounts); // Update inserted pages (scaling objects if needed, etc) updateInsertedPages(aInsertParams, options, pageCounts, aStyleContext); // Make absolutely sure no double masterpages are there - RemoveUnnecessaryMasterPages(nullptr, true); + if (!options.bMergeMasterPagesOnly) + RemoveUnnecessaryMasterPages(nullptr, true); // Rename object styles if necessary renameObjectStylesIfNeeded(nInsertPos, aStyleContext, pageCounts.nSourcePageCount); @@ -2127,20 +2368,23 @@ bool SdDrawDocument::ResolvePageLinks( bool SdDrawDocument::ImportDocumentPages( const PageNameList &rBookmarkList, sal_uInt16 nInsertPos, - ::sd::DrawDocShell* pBookmarkDocSh) + ::sd::DrawDocShell* pBookmarkDocSh, + bool bMergeMasterPagesOnly) { // Use predefined options for document import - InsertBookmarkOptions options = InsertBookmarkOptions::ForDocumentImport(); + InsertBookmarkOptions options = InsertBookmarkOptions::ForDocumentImport(bMergeMasterPagesOnly); // Create parameter object for page insertion PageInsertionParams aInsertParams(nInsertPos); - // Initialize bookmark document if (!initBookmarkDoc(pBookmarkDocSh, aInsertParams.pBookmarkDoc, aInsertParams.aBookmarkName)) return false; - DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), GetMasterPageCount()); + DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), + aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), + GetMasterPageCount(), + aInsertParams.pBookmarkDoc->GetMasterPageCount()); if (!pageCounts.areValid()) { @@ -2159,7 +2403,7 @@ bool SdDrawDocument::ImportDocumentPages( // Collect layout names that need to be transferred SlideLayoutNameList aLayoutsToTransfer; - collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts.nSourcePageCount); + collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts, options.bMergeMasterPagesOnly); // Copy the style that we actually need. SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*aInsertParams.pBookmarkDoc->GetStyleSheetPool()); @@ -2186,7 +2430,7 @@ bool SdDrawDocument::ImportDocumentPages( // For document import, we typically import all pages if (rBookmarkList.empty()) { - insertAllPages(aInsertParams, options, pageCounts.nSourcePageCount); + insertAllPages(aInsertParams, options, pageCounts); } else { @@ -2195,7 +2439,8 @@ bool SdDrawDocument::ImportDocumentPages( } // Remove duplicate master pages that may have been created. - removeDuplicateMasterPages(aInsertParams, pageCounts); + if (!options.bMergeMasterPagesOnly) + removeDuplicateMasterPages(aInsertParams, pageCounts); // nInsertPos > 2 is always true when inserting into non-empty models if (nInsertPos > 0) { @@ -2203,7 +2448,8 @@ bool SdDrawDocument::ImportDocumentPages( } // Make absolutely sure no double masterpages are there - RemoveUnnecessaryMasterPages(nullptr, true); + if (!options.bMergeMasterPagesOnly) + RemoveUnnecessaryMasterPages(nullptr, true); // Rename object styles if necessary renameObjectStylesIfNeeded(nInsertPos, aStyleContext, pageCounts.nSourcePageCount); @@ -2223,10 +2469,12 @@ bool SdDrawDocument::InsertFileAsPage( PageNameList *pExchangeList, bool bLink, sal_uInt16 nInsertPos, - ::sd::DrawDocShell* pBookmarkDocSh) + ::sd::DrawDocShell* pBookmarkDocSh, + bool bMergeMasterPagesOnly) { // Use predefined options for file insert operation InsertBookmarkOptions options = InsertBookmarkOptions::ForFileInsert(bLink); + options.bMergeMasterPagesOnly = bMergeMasterPagesOnly; // Create parameter object for page insertion PageInsertionParams aInsertParams(nInsertPos, pExchangeList); @@ -2235,7 +2483,10 @@ bool SdDrawDocument::InsertFileAsPage( if (!initBookmarkDoc(pBookmarkDocSh, aInsertParams.pBookmarkDoc, aInsertParams.aBookmarkName)) return false; - DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), GetMasterPageCount()); + DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), + aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), + GetMasterPageCount(), + aInsertParams.pBookmarkDoc->GetMasterPageCount()); if (!pageCounts.areValid()) { @@ -2255,7 +2506,7 @@ bool SdDrawDocument::InsertFileAsPage( // Collect layout names that need to be transferred SlideLayoutNameList aLayoutsToTransfer; - collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts.nSourcePageCount); + collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts, options.bMergeMasterPagesOnly); // Copy the style that we actually need. SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*aInsertParams.pBookmarkDoc->GetStyleSheetPool()); @@ -2280,7 +2531,7 @@ bool SdDrawDocument::InsertFileAsPage( if (rBookmarkList.empty()) { - insertAllPages(aInsertParams, options, pageCounts.nSourcePageCount); + insertAllPages(aInsertParams, options, pageCounts); } else { @@ -2289,7 +2540,8 @@ bool SdDrawDocument::InsertFileAsPage( } // Remove duplicate master pages that may have been created. - removeDuplicateMasterPages(aInsertParams, pageCounts); + if (!options.bMergeMasterPagesOnly) + removeDuplicateMasterPages(aInsertParams, pageCounts); // nInsertPos > 2 is always true when inserting into non-empty models if (nInsertPos > 0) { @@ -2297,7 +2549,8 @@ bool SdDrawDocument::InsertFileAsPage( } // Make absolutely sure no double masterpages are there - RemoveUnnecessaryMasterPages(nullptr, true); + if (!options.bMergeMasterPagesOnly) + RemoveUnnecessaryMasterPages(nullptr, true); // Rename object styles if necessary renameObjectStylesIfNeeded(nInsertPos, aStyleContext, pageCounts.nSourcePageCount); @@ -2316,10 +2569,11 @@ bool SdDrawDocument::DropBookmarkAsPage( const PageNameList &rBookmarkList, sal_uInt16 nInsertPos, ::sd::DrawDocShell* pBookmarkDocSh, - bool bMergeMasterPages) + bool bMergeMasterPages, + bool bMergeMasterPagesOnly) { // Use predefined options for drag and drop operation - InsertBookmarkOptions options = InsertBookmarkOptions::ForDragDrop(bMergeMasterPages); + InsertBookmarkOptions options = InsertBookmarkOptions::ForDragDrop(bMergeMasterPages, bMergeMasterPagesOnly); // Create parameter object for page insertion PageInsertionParams aInsertParams(nInsertPos); @@ -2328,7 +2582,10 @@ bool SdDrawDocument::DropBookmarkAsPage( if (!initBookmarkDoc(pBookmarkDocSh, aInsertParams.pBookmarkDoc, aInsertParams.aBookmarkName)) return false; - DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), GetMasterPageCount()); + DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), + aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), + GetMasterPageCount(), + aInsertParams.pBookmarkDoc->GetMasterPageCount()); if (!pageCounts.areValid()) { @@ -2348,7 +2605,7 @@ bool SdDrawDocument::DropBookmarkAsPage( // Collect layout names that need to be transferred SlideLayoutNameList aLayoutsToTransfer; - collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts.nSourcePageCount); + collectLayoutsToTransfer(rBookmarkList, aInsertParams.pBookmarkDoc, aLayoutsToTransfer, pageCounts, options.bMergeMasterPagesOnly); // Copy the style that we actually need. SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*aInsertParams.pBookmarkDoc->GetStyleSheetPool()); @@ -2374,7 +2631,7 @@ bool SdDrawDocument::DropBookmarkAsPage( // Insert pages based on whether all or selected pages are bookmarked. if (rBookmarkList.empty()) { - insertAllPages(aInsertParams, options, pageCounts.nSourcePageCount); + insertAllPages(aInsertParams, options, pageCounts); } else { @@ -2383,7 +2640,8 @@ bool SdDrawDocument::DropBookmarkAsPage( } // Remove duplicate master pages that may have been created. - removeDuplicateMasterPages(aInsertParams, pageCounts); + if (!options.bMergeMasterPagesOnly) + removeDuplicateMasterPages(aInsertParams, pageCounts); // nInsertPos > 2 is always true when inserting into non-empty models if (nInsertPos > 0) { @@ -2391,7 +2649,8 @@ bool SdDrawDocument::DropBookmarkAsPage( } // Make absolutely sure no double masterpages are there - RemoveUnnecessaryMasterPages(nullptr, true); + if (!options.bMergeMasterPagesOnly) + RemoveUnnecessaryMasterPages(nullptr, true); // Rename object styles if necessary renameObjectStylesIfNeeded(nInsertPos, aStyleContext, pageCounts.nSourcePageCount); @@ -2410,16 +2669,20 @@ bool SdDrawDocument::CopyOrMovePagesWithinDocument( const PageNameList &rBookmarkList, PageNameList *pExchangeList, sal_uInt16 nInsertPos, - bool bPreservePageNames) + bool bPreservePageNames, + bool bMergeMasterPagesOnly) { // Use predefined options for internal document operations - InsertBookmarkOptions options = InsertBookmarkOptions::ForInternalOps(bPreservePageNames); + InsertBookmarkOptions options = InsertBookmarkOptions::ForInternalOps(bPreservePageNames, bMergeMasterPagesOnly); // Create parameter object for page insertion // When copying within document, source and target are the same PageInsertionParams aInsertParams(nInsertPos, pExchangeList, this); - DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), GetMasterPageCount()); + DocumentPageCounts pageCounts(GetSdPageCount(PageKind::Standard), + aInsertParams.pBookmarkDoc->GetSdPageCount(PageKind::Standard), + GetMasterPageCount(), + aInsertParams.pBookmarkDoc->GetMasterPageCount()); if (!pageCounts.areValid()) { @@ -2443,7 +2706,8 @@ bool SdDrawDocument::CopyOrMovePagesWithinDocument( insertSelectedPages(rBookmarkList, aInsertParams, options); // Remove duplicate master pages that may have been created. - removeDuplicateMasterPages(aInsertParams, pageCounts); + if (!options.bMergeMasterPagesOnly) + removeDuplicateMasterPages(aInsertParams, pageCounts); // nInsertPos > 2 is always true when inserting into non-empty models StyleTransferContext aStyleContext; diff --git a/sd/source/ui/app/sdxfer.cxx b/sd/source/ui/app/sdxfer.cxx index 348322d47334..31d61b6b9b19 100644 --- a/sd/source/ui/app/sdxfer.cxx +++ b/sd/source/ui/app/sdxfer.cxx @@ -656,7 +656,7 @@ void SdTransferable::SetObjectDescriptor( std::unique_ptr<TransferableObjectDesc PrepareOLE( *mpObjDesc ); } -void SdTransferable::SetPageBookmarks( std::vector<OUString> && rPageBookmarks, bool bPersistent ) +void SdTransferable::SetPageBookmarks( std::vector<OUString> && rPageBookmarks, bool bPersistent, bool bMergeMasterPagesOnly ) { if( !mpSourceDoc ) return; @@ -673,7 +673,7 @@ void SdTransferable::SetPageBookmarks( std::vector<OUString> && rPageBookmarks, if( bPersistent ) { mpSdDrawDocument->CreateFirstPages(mpSourceDoc); - mpSdDrawDocument->ImportDocumentPages(rPageBookmarks, 1, mpSourceDoc->GetDocSh()); + mpSdDrawDocument->ImportDocumentPages(rPageBookmarks, 1, mpSourceDoc->GetDocSh(), bMergeMasterPagesOnly); } else { diff --git a/sd/source/ui/func/fuoltext.cxx b/sd/source/ui/func/fuoltext.cxx index 0f2c354fca32..57f626a6ecab 100644 --- a/sd/source/ui/func/fuoltext.cxx +++ b/sd/source/ui/func/fuoltext.cxx @@ -275,7 +275,7 @@ void FuSimpleOutlinerText::DoCut() /** * Copy object to clipboard */ -void FuSimpleOutlinerText::DoCopy() +void FuSimpleOutlinerText::DoCopy(bool /*bMergeMasterPagesOnly*/) { mpSimpleOutlinerView->GetViewByWindow(mpWindow)->Copy(); } @@ -283,7 +283,7 @@ void FuSimpleOutlinerText::DoCopy() /** * Paste object from clipboard */ -void FuSimpleOutlinerText::DoPaste() +void FuSimpleOutlinerText::DoPaste(bool /*bMergeMasterPagesOnly*/) { mpSimpleOutlinerView->GetViewByWindow(mpWindow)->PasteSpecial(); } diff --git a/sd/source/ui/func/fupoor.cxx b/sd/source/ui/func/fupoor.cxx index 5d952d1e4a40..d6b75b13abf7 100644 --- a/sd/source/ui/func/fupoor.cxx +++ b/sd/source/ui/func/fupoor.cxx @@ -888,22 +888,22 @@ void FuPoor::DoCut() /** * Copy object to clipboard */ -void FuPoor::DoCopy() +void FuPoor::DoCopy(bool bMergeMasterPagesOnly ) { if (mpView) { - mpView->DoCopy(); + mpView->DoCopy(bMergeMasterPagesOnly); } } /** * Paste object from clipboard */ -void FuPoor::DoPaste() +void FuPoor::DoPaste(bool bMergeMasterPagesOnly ) { if (mpView) { - mpView->DoPaste(mpWindow); + mpView->DoPaste(mpWindow, bMergeMasterPagesOnly); } } diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx index 493756871998..c9f3333d4842 100644 --- a/sd/source/ui/inc/View.hxx +++ b/sd/source/ui/inc/View.hxx @@ -109,8 +109,8 @@ public: virtual void MarkListHasChanged() override; void SelectAll(); void DoCut(); - void DoCopy(); - void DoPaste(::sd::Window* pWindow=nullptr); + void DoCopy(bool bMergeMasterPagesOnly = false ); + void DoPaste(::sd::Window* pWindow=nullptr, bool bMergeMasterPagesOnly = false); virtual void DoConnect(SdrOle2Obj* pOleObj) override; virtual bool SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr = false); void StartDrag( const Point& rStartPos, vcl::Window* pWindow ); diff --git a/sd/source/ui/inc/fuoltext.hxx b/sd/source/ui/inc/fuoltext.hxx index 61b69ad9512b..9ac8e38dd692 100644 --- a/sd/source/ui/inc/fuoltext.hxx +++ b/sd/source/ui/inc/fuoltext.hxx @@ -44,8 +44,8 @@ public: virtual bool MouseButtonDown(const MouseEvent& rMEvt) override; virtual void DoCut() override; - virtual void DoCopy() override; - virtual void DoPaste() override; + virtual void DoCopy(bool bMergeMasterPagesOnly = false ) override; + virtual void DoPaste(bool bMergeMasterPagesOnly = false ) override; virtual void DoPasteUnformatted() override; /** Call this method when the text in the outliner (may) have changed. diff --git a/sd/source/ui/inc/fupoor.hxx b/sd/source/ui/inc/fupoor.hxx index e0103a111d51..201605cf11fa 100644 --- a/sd/source/ui/inc/fupoor.hxx +++ b/sd/source/ui/inc/fupoor.hxx @@ -60,8 +60,8 @@ public: DrawDocShell* GetDocSh() { return mpDocSh; } virtual void DoCut(); - virtual void DoCopy(); - virtual void DoPaste(); + virtual void DoCopy(bool bMergeMasterPagesOnly = false ); + virtual void DoPaste(bool bMergeMasterPagesOnly = false ); virtual void DoPasteUnformatted(); // mouse & key events; return value = sal_True: event has been handled diff --git a/sd/source/ui/inc/sdxfer.hxx b/sd/source/ui/inc/sdxfer.hxx index 3a1e599856e1..4282a7635862 100644 --- a/sd/source/ui/inc/sdxfer.hxx +++ b/sd/source/ui/inc/sdxfer.hxx @@ -67,7 +67,7 @@ public: bool HasSourceDoc( const SdDrawDocument* pDoc ) const { return( mpSourceDoc == pDoc ); } - void SetPageBookmarks( std::vector<OUString>&& rPageBookmarks, bool bPersistent ); + void SetPageBookmarks( std::vector<OUString>&& rPageBookmarks, bool bPersistent, bool bMergeMasterPagesOnly = false ); bool IsPageTransferable() const { return mbPageTransferable; } bool HasPageBookmarks() const { return( mpPageDocShell && ( !maPageBookmarks.empty() ) ); } const std::vector<OUString>& GetPageBookmarks() const { return maPageBookmarks; } diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 5483cfd766ab..00cf5e82d8b9 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -189,6 +189,14 @@ void Clipboard::HandleSlotCall (SfxRequest& rRequest) else DoCopy(); } + else + { + // Copying master pages only. + if(xFunc.is()) + xFunc->DoCopy(true); + else + DoCopy(true); + } rRequest.Done(); break; @@ -206,6 +214,16 @@ void Clipboard::HandleSlotCall (SfxRequest& rRequest) else DoPaste(); } + else + { + // Pasting master pages only. + view::SlideSorterView::DrawLock aLock (mrSlideSorter); + SelectionObserver::Context aContext (mrSlideSorter); + if(xFunc.is()) + xFunc->DoPaste(true); + else + DoPaste(true); + } rRequest.Done(); break; @@ -233,12 +251,12 @@ void Clipboard::DoDelete() } } -void Clipboard::DoCopy () +void Clipboard::DoCopy (bool bMergeMasterPagesOnly ) { - CreateSlideTransferable( nullptr, false ); + CreateSlideTransferable( nullptr, false, bMergeMasterPagesOnly); } -void Clipboard::DoPaste () +void Clipboard::DoPaste (bool bMergeMasterPagesOnly ) { SdTransferable* pClipTransferable = SdModule::get()->pTransferClip; @@ -250,7 +268,7 @@ void Clipboard::DoPaste () if (nInsertPosition >= 0) { // Paste the pages from the clipboard. - sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition); + sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition, bMergeMasterPagesOnly); // Select the pasted pages and make the first of them the // current page. mrSlideSorter.GetContentWindow()->GrabFocus(); @@ -299,7 +317,7 @@ sal_Int32 Clipboard::GetInsertionPosition () return nInsertPosition; } -sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition) +sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition, bool bMergeMasterPagesOnly) { SdTransferable* pClipTransferable = SdModule::get()->pTransferClip; model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); @@ -317,7 +335,8 @@ sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition) nullptr, nInsertIndex, pClipTransferable->GetPageDocShell(), - bMergeMasterPages); + bMergeMasterPages, + bMergeMasterPagesOnly); } else { @@ -337,7 +356,8 @@ sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition) nullptr, nInsertIndex, pDataDocSh, - bMergeMasterPages); + bMergeMasterPages, + bMergeMasterPagesOnly); } } mrController.HandleModelChange(); @@ -368,7 +388,8 @@ void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount) void Clipboard::CreateSlideTransferable ( vcl::Window* pWindow, - bool bDrag) + bool bDrag, + bool bMergeMasterPagesOnly) { std::vector<OUString> aBookmarkList; @@ -469,7 +490,7 @@ void Clipboard::CreateSlideTransferable ( { TemporarySlideTrackingDeactivator aDeactivator (mrController); - pTransferable->SetPageBookmarks (std::move(aBookmarkList), !bDrag); + pTransferable->SetPageBookmarks (std::move(aBookmarkList), !bDrag, bMergeMasterPagesOnly); } if (bDrag) diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index bc4f54a3196d..e05f14ef6bc7 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -563,14 +563,14 @@ void SelectionFunction::DoCut() mrController.GetClipboard().DoCut(); } -void SelectionFunction::DoCopy() +void SelectionFunction::DoCopy(bool bMergeMasterPagesOnly ) { - mrController.GetClipboard().DoCopy(); + mrController.GetClipboard().DoCopy(bMergeMasterPagesOnly); } -void SelectionFunction::DoPaste() +void SelectionFunction::DoPaste(bool bMergeMasterPagesOnly ) { - mrController.GetClipboard().DoPaste(); + mrController.GetClipboard().DoPaste(bMergeMasterPagesOnly); } bool SelectionFunction::cancel() diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index a9051bc41059..c686e3a9246d 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -761,10 +761,6 @@ void SlotManager::GetClipboardState ( SfxItemSet& rSet) { if (rSet.GetItemState(SID_CUT) == SfxItemState::DEFAULT) rSet.DisableItem(SID_CUT); - if (rSet.GetItemState(SID_COPY) == SfxItemState::DEFAULT) - rSet.DisableItem(SID_COPY); - if (rSet.GetItemState(SID_PASTE) == SfxItemState::DEFAULT) - rSet.DisableItem(SID_PASTE); if (rSet.GetItemState(SID_PASTE_SPECIAL) == SfxItemState::DEFAULT) rSet.DisableItem(SID_PASTE_SPECIAL); } diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index 10c2aa13ed58..80da060c001a 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -216,7 +216,7 @@ public: this method should be called between calls to PrepareEditModeChange() and FinishEditModeChange(). */ - void ChangeEditMode(EditMode eEditMode); + SD_DLLPUBLIC void ChangeEditMode(EditMode eEditMode); /** Finish the change of the edit mode. Here we may select a page or restore a previously saved selection. diff --git a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx index 46833f7f3f2f..6482def0aa4a 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx @@ -67,9 +67,9 @@ public: // Exported for unit test SD_DLLPUBLIC void DoCut (); // Exported for unit test - SD_DLLPUBLIC void DoCopy(); + SD_DLLPUBLIC void DoCopy(bool bMergeMasterPagesOnly = false ); // Exported for unit test - SD_DLLPUBLIC void DoPaste(); + SD_DLLPUBLIC void DoPaste(bool bMergeMasterPagesOnly = false ); void DoDelete (); void StartDrag ( @@ -119,7 +119,8 @@ private: void CreateSlideTransferable ( vcl::Window* pWindow, - bool bDrag); + bool bDrag, + bool bMergeMasterPagesOnly = false); public: /** Determine the position of where to insert the pages in the current @@ -144,7 +145,7 @@ private: @return The number of inserted pages is returned. */ - sal_Int32 PasteTransferable (sal_Int32 nInsertPosition); + sal_Int32 PasteTransferable (sal_Int32 nInsertPosition, bool bMergeMasterPagesOnly = false); /** Select a range of pages of the model. Typically usage is the selection of newly inserted pages. diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index 8ea46b3f36e7..27f0a8c507aa 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -79,7 +79,7 @@ public: /** Select the descriptor that is associated with the given page. The selection state of the other descriptors is not affected. */ - void SelectPage(const SdPage* pPage); + SD_DLLPUBLIC void SelectPage(const SdPage* pPage); /** Select the specified descriptor. The selection state of the other descriptors is not affected. */ diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 7d80fbd26cf1..b66a93af53ba 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -52,10 +52,10 @@ public: virtual void DoCut() override; /// Forward to the clipboard manager. - virtual void DoCopy() override; + virtual void DoCopy(bool bMergeMasterPagesOnly = false) override; /// Forward to the clipboard manager. - virtual void DoPaste() override; + virtual void DoPaste(bool bMergeMasterPagesOnly = false) override; /** is called when the current function should be aborted. <p> This is used when a function gets a KEY_ESCAPE but can also diff --git a/sd/source/ui/view/sdview2.cxx b/sd/source/ui/view/sdview2.cxx index 1ed27775501b..7fd8970d4142 100644 --- a/sd/source/ui/view/sdview2.cxx +++ b/sd/source/ui/view/sdview2.cxx @@ -261,7 +261,7 @@ void View::DoCut() } } -void View::DoCopy() +void View::DoCopy(bool /*bMergeMasterPagesOnly*/) { const OutlinerView* pOLV = GetTextEditOutlinerView(); @@ -275,7 +275,7 @@ void View::DoCopy() } } -void View::DoPaste (::sd::Window* pWindow) +void View::DoPaste (::sd::Window* pWindow,bool /*bMergeMasterPagesOnly*/) { TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewSh->GetActiveWindow() ) ); if( !aDataHelper.GetTransferable().is() )