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() )

Reply via email to