cui/Library_cui.mk                     |    1 
 cui/Module_cui.mk                      |    1 
 cui/UIConfig_cui.mk                    |    1 
 cui/UITest_cui_tabpages.mk             |   16 +++++
 cui/qa/uitest/tabpages/themepage.py    |   47 ++++++++++++++++
 cui/source/factory/dlgfact.cxx         |    5 +
 cui/source/inc/themepage.hxx           |   38 +++++++++++++
 cui/source/tabpages/themepage.cxx      |   95 +++++++++++++++++++++++++++++++++
 cui/uiconfig/ui/themetabpage.ui        |   72 +++++++++++++++++++++++++
 include/svx/dialogs.hrc                |    1 
 sd/inc/sdabstdlg.hxx                   |    2 
 sd/qa/unit/dialogs-test.cxx            |    2 
 sd/source/ui/dlg/dlgpage.cxx           |    9 ++-
 sd/source/ui/dlg/sddlgfact.cxx         |    4 -
 sd/source/ui/dlg/sddlgfact.hxx         |    2 
 sd/source/ui/func/fupage.cxx           |   31 ++++++++++
 sd/source/ui/inc/dlgpage.hxx           |    2 
 sd/uiconfig/sdraw/ui/drawpagedialog.ui |   48 ++++++++++++++++
 18 files changed, 369 insertions(+), 8 deletions(-)

New commits:
commit 5b63e62271b36b2109d35961acfca29546c13e59
Author:     Miklos Vajna <[email protected]>
AuthorDate: Tue Dec 14 09:55:45 2021 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Wed Jun 29 09:05:40 2022 +0200

    sd: add initial theme UI for master slides
    
    Click Sidebar -> properties -> slide -> master view, then launch the
    Slide -> Slide properties menu item, this adds a new Theme tab page
    there.
    
    This is just an initial UI, only the theme name can be edited as a
    start.
    
    (cherry picked from commit 64fcf278830a33114f0fa5884767f24edf32cb12)
    
    Change-Id: Ia2faa828c57a0e858881fb8640431f046b5739a8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136529
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index 1e8023cc819c..d455a64ab266 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -219,6 +219,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
     cui/source/tabpages/textanim \
     cui/source/tabpages/textattr \
     cui/source/tabpages/TextColumnsPage \
+    cui/source/tabpages/themepage \
     cui/source/tabpages/tparea \
     cui/source/tabpages/tpbitmap \
     cui/source/tabpages/tpcolor \
diff --git a/cui/Module_cui.mk b/cui/Module_cui.mk
index e4ff28c8fabe..53492ef291a4 100644
--- a/cui/Module_cui.mk
+++ b/cui/Module_cui.mk
@@ -29,6 +29,7 @@ $(eval $(call gb_Module_add_screenshot_targets,cui,\
 
 $(eval $(call gb_Module_add_uicheck_targets,cui,\
     UITest_cui_dialogs \
+    UITest_cui_tabpages \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk
index a4ad452bdfee..806779daaa9d 100644
--- a/cui/UIConfig_cui.mk
+++ b/cui/UIConfig_cui.mk
@@ -213,6 +213,7 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\
        cui/uiconfig/ui/textcolumnstabpage \
        cui/uiconfig/ui/textdialog \
        cui/uiconfig/ui/textflowpage \
+       cui/uiconfig/ui/themetabpage \
        cui/uiconfig/ui/thesaurus \
        cui/uiconfig/ui/toolbarmodedialog \
        cui/uiconfig/ui/transparencytabpage \
diff --git a/cui/UITest_cui_tabpages.mk b/cui/UITest_cui_tabpages.mk
new file mode 100644
index 000000000000..4458e9859e23
--- /dev/null
+++ b/cui/UITest_cui_tabpages.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UITest_UITest,cui_tabpages))
+
+$(eval $(call gb_UITest_add_modules,cui_tabpages,$(SRCDIR)/cui/qa/uitest,\
+       tabpages/ \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/qa/uitest/tabpages/themepage.py 
b/cui/qa/uitest/tabpages/themepage.py
new file mode 100644
index 000000000000..eb97205d19ab
--- /dev/null
+++ b/cui/qa/uitest/tabpages/themepage.py
@@ -0,0 +1,47 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from libreoffice.uno.propertyvalue import convert_property_values_to_dict
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+from uitest.uihelper.common import select_pos
+
+# Test for cui/source/tabpages/themepage.cxx.
+class Test(UITestCase):
+
+    def testThemePage(self):
+        # Given an Impress document with a master page that has a theme:
+        with self.ui_test.create_doc_in_start_center("impress") as component:
+            template = self.xUITest.getTopFocusWindow()
+            
self.ui_test.close_dialog_through_button(template.getChild("close"))
+            doc = self.xUITest.getTopFocusWindow()
+            editWin = doc.getChild("impress_win")
+            drawPage = component.getDrawPages().getByIndex(0)
+            master = drawPage.MasterPage
+            theme = mkPropertyValues({
+                "Name": "nameA"
+            })
+            master.Theme = theme
+
+            # When changing the name of the theme:
+            self.xUITest.executeCommand(".uno:SlideMasterPage")
+            with self.ui_test.execute_dialog_through_command(".uno:PageSetup") 
as xDialog:
+                xTabs = xDialog.getChild("tabcontrol")
+                # Select RID_SVXPAGE_THEME.
+                select_pos(xTabs, "3")
+                themeName = xDialog.getChild("themeName")
+                themeName.executeAction("TYPE", mkPropertyValues({"TEXT": 
"nameB"}))
+
+            # Then make sure the doc model is updated accordingly:
+            # Without the accompanying fix in place, this test would have 
failed with:
+            # AssertionError: 'nameA' != 'nameB'
+            # i.e. the UI didn't update the theme name.
+            theme = convert_property_values_to_dict(master.Theme)
+            self.assertEqual(theme["Name"], "nameB")
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
index 4496b8e8799d..8cb265781907 100644
--- a/cui/source/factory/dlgfact.cxx
+++ b/cui/source/factory/dlgfact.cxx
@@ -93,6 +93,7 @@
 #include <DiagramDialog.hxx>
 #include <fileextcheckdlg.hxx>
 #include <TextColumnsPage.hxx>
+#include <themepage.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::frame;
@@ -1291,6 +1292,8 @@ CreateTabPage 
AbstractDialogFactory_Impl::GetTabPageCreatorFunc( sal_uInt16 nId
             return SfxMacroTabPage::Create;
         case RID_SVXPAGE_TEXTCOLUMNS:
             return SvxTextColumnsPage::Create;
+        case RID_SVXPAGE_THEME:
+            return SvxThemePage::Create;
         default:
             break;
     }
@@ -1356,6 +1359,8 @@ GetTabPageRanges 
AbstractDialogFactory_Impl::GetTabPageRangesFunc( sal_uInt16 nI
             return SvxAsianLayoutPage::GetRanges;
         case RID_SVXPAGE_TEXTCOLUMNS:
             return SvxTextColumnsPage::GetRanges;
+        case RID_SVXPAGE_THEME:
+            return SvxThemePage::GetRanges;
         default:
             break;
     }
diff --git a/cui/source/inc/themepage.hxx b/cui/source/inc/themepage.hxx
new file mode 100644
index 000000000000..6596cd227244
--- /dev/null
+++ b/cui/source/inc/themepage.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <sfx2/tabdlg.hxx>
+
+#include <memory>
+
+/// Tab page for themes
+class SvxThemePage : public SfxTabPage
+{
+    static const WhichRangesContainer m_pRanges;
+
+    std::unique_ptr<weld::Entry> m_xThemeName;
+
+public:
+    SvxThemePage(weld::Container* pPage, weld::DialogController* pController,
+                 const SfxItemSet& rInAttrs);
+    virtual ~SvxThemePage() override;
+
+    static std::unique_ptr<SfxTabPage>
+    Create(weld::Container* pPage, weld::DialogController* pController, const 
SfxItemSet*);
+    static WhichRangesContainer GetRanges() { return m_pRanges; }
+
+    virtual bool FillItemSet(SfxItemSet*) override;
+    virtual void Reset(const SfxItemSet*) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/cui/source/tabpages/themepage.cxx 
b/cui/source/tabpages/themepage.cxx
new file mode 100644
index 000000000000..4c2cd18716b9
--- /dev/null
+++ b/cui/source/tabpages/themepage.cxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <com/sun/star/beans/PropertyValues.hpp>
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <editeng/editids.hrc>
+#include <sal/log.hxx>
+#include <svl/grabbagitem.hxx>
+
+#include <themepage.hxx>
+
+using namespace com::sun::star;
+
+const WhichRangesContainer
+    SvxThemePage::m_pRanges(svl::Items<SID_ATTR_CHAR_GRABBAG, 
SID_ATTR_CHAR_GRABBAG>);
+
+SvxThemePage::SvxThemePage(weld::Container* pPage, weld::DialogController* 
pController,
+                           const SfxItemSet& rInAttrs)
+    : SfxTabPage(pPage, pController, "cui/ui/themetabpage.ui", "ThemePage", 
&rInAttrs)
+    , m_xThemeName(m_xBuilder->weld_entry("themeName"))
+{
+}
+
+SvxThemePage::~SvxThemePage() = default;
+
+void SvxThemePage::Reset(const SfxItemSet* pAttrs)
+{
+    const SfxPoolItem* pItem = nullptr;
+    if (!pAttrs->HasItem(SID_ATTR_CHAR_GRABBAG, &pItem))
+    {
+        SAL_WARN("cui.tabpages", "SvxThemePage::Reset: no SfxGrabBagItem");
+        return;
+    }
+
+    const auto& rGrabBagItem = static_cast<const SfxGrabBagItem&>(*pItem);
+    auto itTheme = rGrabBagItem.GetGrabBag().find("Theme");
+    if (itTheme == rGrabBagItem.GetGrabBag().end())
+    {
+        SAL_WARN("cui.tabpages", "SvxThemePage::Reset: no Theme");
+        return;
+    }
+
+    comphelper::SequenceAsHashMap aMap(itTheme->second);
+    auto it = aMap.find("Name");
+    if (it != aMap.end())
+    {
+        OUString aName;
+        it->second >>= aName;
+        m_xThemeName->set_text(aName);
+    }
+}
+
+bool SvxThemePage::FillItemSet(SfxItemSet* pAttrs)
+{
+    const SfxItemSet& rOldSet = GetItemSet();
+
+    if (rOldSet.HasItem(SID_ATTR_CHAR_GRABBAG))
+    {
+        SfxGrabBagItem aGrabBagItem(
+            static_cast<const 
SfxGrabBagItem&>(rOldSet.Get(SID_ATTR_CHAR_GRABBAG)));
+
+        comphelper::SequenceAsHashMap aMap;
+        auto it = aGrabBagItem.GetGrabBag().find("Theme");
+        if (it != aGrabBagItem.GetGrabBag().end())
+        {
+            aMap << it->second;
+        }
+
+        aMap["Name"] <<= m_xThemeName->get_text();
+
+        beans::PropertyValues aTheme = aMap.getAsConstPropertyValueList();
+        aGrabBagItem.GetGrabBag()["Theme"] <<= aTheme;
+        pAttrs->Put(aGrabBagItem);
+    }
+
+    return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxThemePage::Create(weld::Container* pPage,
+                                                 weld::DialogController* 
pController,
+                                                 const SfxItemSet* rAttrs)
+{
+    return std::make_unique<SvxThemePage>(pPage, pController, *rAttrs);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/cui/uiconfig/ui/themetabpage.ui b/cui/uiconfig/ui/themetabpage.ui
new file mode 100644
index 000000000000..c94c6093958b
--- /dev/null
+++ b/cui/uiconfig/ui/themetabpage.ui
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkBox" id="ThemePage">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">6</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <child>
+      <object class="GtkFrame" id="frmGeneral">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label_xalign">0</property>
+        <property name="shadow_type">none</property>
+        <child>
+          <object class="GtkGrid" id="gdGeneral">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_start">6</property>
+            <property name="margin_end">6</property>
+            <property name="row_spacing">3</property>
+            <property name="column_spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="lbThemeName">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" 
context="themetabpage|lbThemeName">Name:</property>
+                <accessibility>
+                  <relation type="label-for" target="themeName"/>
+                </accessibility>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="themeName">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <accessibility>
+                  <relation type="labelled-by" target="lbThemeName"/>
+                </accessibility>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child type="label">
+          <object class="GtkLabel" id="general">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" 
context="themetabpage|general">General</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/include/svx/dialogs.hrc b/include/svx/dialogs.hrc
index f03600a74fe0..d3d7f6d8b17d 100644
--- a/include/svx/dialogs.hrc
+++ b/include/svx/dialogs.hrc
@@ -43,6 +43,7 @@
 #define RID_SVXPAGE_BKG                     (RID_SVX_START +  57)
 #define RID_SVXPAGE_SHADOW                  (RID_SVX_START +  61)
 #define RID_SVXPAGE_TRANSPARENCE            (RID_SVX_START +  54)
+#define RID_SVXPAGE_THEME                   (RID_SVX_START +  55)
 #define RID_SVXPAGE_TEXTATTR                (RID_SVX_START + 153)
 #define RID_SVXPAGE_TEXTANIMATION           (RID_SVX_START + 184)
 #define RID_SVXPAGE_TEXTCOLUMNS             (RID_SVX_START + 154)
diff --git a/sd/inc/sdabstdlg.hxx b/sd/inc/sdabstdlg.hxx
index 786c1121212a..9428325cdca0 100644
--- a/sd/inc/sdabstdlg.hxx
+++ b/sd/inc/sdabstdlg.hxx
@@ -171,7 +171,7 @@ public:
     virtual VclPtr<AbstractCopyDlg>            CreateCopyDlg(weld::Window* 
pWindow, const SfxItemSet& rInAttrs, ::sd::View* pView ) = 0;
     virtual VclPtr<AbstractSdCustomShowDlg>    
CreateSdCustomShowDlg(weld::Window* pWindow, SdDrawDocument& rDrawDoc) = 0;
     virtual VclPtr<SfxAbstractTabDialog>       
CreateSdTabCharDialog(weld::Window* pWindow, const SfxItemSet* pAttr, 
SfxObjectShell* pDocShell) = 0;
-    virtual VclPtr<SfxAbstractTabDialog>       
CreateSdTabPageDialog(weld::Window* pWindow, const SfxItemSet* pAttr, 
SfxObjectShell* pDocShell, bool bAreaPage, bool bIsImpressDoc) = 0;
+    virtual VclPtr<SfxAbstractTabDialog>       
CreateSdTabPageDialog(weld::Window* pWindow, const SfxItemSet* pAttr, 
SfxObjectShell* pDocShell, bool bAreaPage, bool bIsImpressDoc, bool 
bIsImpressMaster) = 0;
     virtual VclPtr<AbstractSdModifyFieldDlg>   
CreateSdModifyFieldDlg(weld::Window* pWindow, const SvxFieldData* pInField, 
const SfxItemSet& rSet) = 0;
     virtual VclPtr<AbstractSdSnapLineDlg>      
CreateSdSnapLineDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, 
::sd::View* pView) = 0;
     virtual VclPtr<AbstractSdInsertLayerDlg>   
CreateSdInsertLayerDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, bool 
bDeletable, const OUString& rStr) = 0;
diff --git a/sd/qa/unit/dialogs-test.cxx b/sd/qa/unit/dialogs-test.cxx
index 363732c75b44..c6e90419869d 100644
--- a/sd/qa/unit/dialogs-test.cxx
+++ b/sd/qa/unit/dialogs-test.cxx
@@ -308,7 +308,7 @@ VclPtr<VclAbstractDialog> 
SdDialogsTest::createDialogByID(sal_uInt32 nID)
                 getViewShell()->GetFrameWeld(),
                 &getEmptyFillStyleSfxItemSet(),
                 getDocShell(),
-                true, false);
+                true, /*bIsImpressDoc=*/false, /*bIsImpressMaster=*/false);
             break;
         }
         case 6:
diff --git a/sd/source/ui/dlg/dlgpage.cxx b/sd/source/ui/dlg/dlgpage.cxx
index b6d04173d814..e3bc5978bd8c 100644
--- a/sd/source/ui/dlg/dlgpage.cxx
+++ b/sd/source/ui/dlg/dlgpage.cxx
@@ -36,7 +36,7 @@
  * Constructor of tab dialog: appends pages to the dialog
  */
 SdPageDlg::SdPageDlg(SfxObjectShell const* pDocSh, weld::Window* pParent, 
const SfxItemSet* pAttr,
-                     bool bAreaPage, bool bIsImpressDoc)
+                     bool bAreaPage, bool bIsImpressDoc, bool bIsImpressMaster)
     : SfxTabDialogController(pParent, "modules/sdraw/ui/drawpagedialog.ui", 
"DrawPageDialog", pAttr)
     , mbIsImpressDoc(bIsImpressDoc)
 {
@@ -58,6 +58,7 @@ SdPageDlg::SdPageDlg(SfxObjectShell const* pDocSh, 
weld::Window* pParent, const
     AddTabPage("RID_SVXPAGE_AREA", 
pFact->GetTabPageCreatorFunc(RID_SVXPAGE_AREA), nullptr);
     AddTabPage("RID_SVXPAGE_TRANSPARENCE", 
pFact->GetTabPageCreatorFunc(RID_SVXPAGE_TRANSPARENCE),
                nullptr);
+    AddTabPage("RID_SVXPAGE_THEME", 
pFact->GetTabPageCreatorFunc(RID_SVXPAGE_THEME), nullptr);
 
     if (!bAreaPage) // I have to add the page before I remove it !
     {
@@ -65,6 +66,12 @@ SdPageDlg::SdPageDlg(SfxObjectShell const* pDocSh, 
weld::Window* pParent, const
         RemoveTabPage("RID_SVXPAGE_TRANSPARENCE");
     }
 
+    if (!bIsImpressMaster)
+    {
+        // Only slide masters can have a theme.
+        RemoveTabPage("RID_SVXPAGE_THEME");
+    }
+
     if (mbIsImpressDoc)
     {
         set_title(SdResId(STR_SLIDE_SETUP_TITLE));
diff --git a/sd/source/ui/dlg/sddlgfact.cxx b/sd/source/ui/dlg/sddlgfact.cxx
index 506b741e677d..c526df75d44f 100644
--- a/sd/source/ui/dlg/sddlgfact.cxx
+++ b/sd/source/ui/dlg/sddlgfact.cxx
@@ -618,9 +618,9 @@ VclPtr<SfxAbstractTabDialog>  
SdAbstractDialogFactory_Impl::CreateSdTabCharDialo
     return 
VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdCharDlg>(pParent,
 pAttr, pDocShell));
 }
 
-VclPtr<SfxAbstractTabDialog>  
SdAbstractDialogFactory_Impl::CreateSdTabPageDialog(weld::Window* pParent, 
const SfxItemSet* pAttr, SfxObjectShell* pDocShell, bool bAreaPage, bool 
bIsImpressDoc )
+VclPtr<SfxAbstractTabDialog>  
SdAbstractDialogFactory_Impl::CreateSdTabPageDialog(weld::Window* pParent, 
const SfxItemSet* pAttr, SfxObjectShell* pDocShell, bool bAreaPage, bool 
bIsImpressDoc, bool bIsImpressMaster )
 {
-    return 
VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdPageDlg>(pDocShell,
 pParent, pAttr, bAreaPage, bIsImpressDoc));
+    return 
VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdPageDlg>(pDocShell,
 pParent, pAttr, bAreaPage, bIsImpressDoc, bIsImpressMaster));
 }
 
 VclPtr<AbstractSdModifyFieldDlg> 
SdAbstractDialogFactory_Impl::CreateSdModifyFieldDlg(weld::Window* pParent, 
const SvxFieldData* pInField, const SfxItemSet& rSet)
diff --git a/sd/source/ui/dlg/sddlgfact.hxx b/sd/source/ui/dlg/sddlgfact.hxx
index 5a8637586b8e..8da5c74ddc8d 100644
--- a/sd/source/ui/dlg/sddlgfact.hxx
+++ b/sd/source/ui/dlg/sddlgfact.hxx
@@ -410,7 +410,7 @@ public:
     virtual VclPtr<AbstractCopyDlg>            CreateCopyDlg(weld::Window* 
pParent, const SfxItemSet& rInAttrs, ::sd::View* pView) override;
     virtual VclPtr<AbstractSdCustomShowDlg>    
CreateSdCustomShowDlg(weld::Window* pParent, SdDrawDocument& rDrawDoc) override;
     virtual VclPtr<SfxAbstractTabDialog>       
CreateSdTabCharDialog(weld::Window* pWindow, const SfxItemSet* pAttr, 
SfxObjectShell* pDocShell) override;
-    virtual VclPtr<SfxAbstractTabDialog>       
CreateSdTabPageDialog(weld::Window* pWindow, const SfxItemSet* pAttr, 
SfxObjectShell* pDocShell, bool bAreaPage, bool bIsImpressDoc) override;
+    virtual VclPtr<SfxAbstractTabDialog>       
CreateSdTabPageDialog(weld::Window* pWindow, const SfxItemSet* pAttr, 
SfxObjectShell* pDocShell, bool bAreaPage, bool bIsImpressDoc, bool 
bIsImpressMaster) override;
     virtual VclPtr<AbstractSdModifyFieldDlg>   
CreateSdModifyFieldDlg(weld::Window* pWindow, const SvxFieldData* pInField, 
const SfxItemSet& rSet) override;
     virtual VclPtr<AbstractSdSnapLineDlg>      
CreateSdSnapLineDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, 
::sd::View* pView) override;
     virtual VclPtr<AbstractSdInsertLayerDlg>   
CreateSdInsertLayerDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, bool 
bDeletable, const OUString& aStr) override;
diff --git a/sd/source/ui/func/fupage.cxx b/sd/source/ui/func/fupage.cxx
index 366e99b691ff..2c1abb8123f7 100644
--- a/sd/source/ui/func/fupage.cxx
+++ b/sd/source/ui/func/fupage.cxx
@@ -47,6 +47,7 @@
 #include <editeng/sizeitem.hxx>
 #include <editeng/pbinitem.hxx>
 #include <sfx2/opengrf.hxx>
+#include <sal/log.hxx>
 
 #include <strings.hrc>
 #include <sdpage.hxx>
@@ -261,6 +262,19 @@ const SfxItemSet* FuPage::ExecuteDialog(weld::Window* 
pParent, const SfxRequest&
 
     SfxGrabBagItem grabBag(SID_ATTR_CHAR_GRABBAG);
     grabBag.GetGrabBag()["BackgroundFullSize"] <<= bFullSize;
+
+    if (mpDoc->GetDocumentType() == DocumentType::Impress && 
mpPage->IsMasterPage())
+    {
+        // A master slide may have a theme.
+        svx::Theme* pTheme = mpPage->getSdrPageProperties().GetTheme();
+        if (pTheme)
+        {
+            uno::Any aTheme;
+            pTheme->ToAny(aTheme);
+            grabBag.GetGrabBag()["Theme"] = aTheme;
+        }
+    }
+
     aNewAttr.Put(grabBag);
 
     // Merge ItemSet for dialog
@@ -350,7 +364,7 @@ const SfxItemSet* FuPage::ExecuteDialog(weld::Window* 
pParent, const SfxRequest&
 
         // create the dialog
         SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
-        ScopedVclPtr<SfxAbstractTabDialog> pDlg( 
pFact->CreateSdTabPageDialog(mpViewShell->GetFrameWeld(), &aMergedAttr, 
mpDocSh, mbDisplayBackgroundTabPage, bIsImpressDoc) );
+        ScopedVclPtr<SfxAbstractTabDialog> pDlg( 
pFact->CreateSdTabPageDialog(mpViewShell->GetFrameWeld(), &aMergedAttr, 
mpDocSh, mbDisplayBackgroundTabPage, bIsImpressDoc, mbMasterPage) );
         if( pDlg->Execute() == RET_OK )
             pTempSet.emplace( *pDlg->GetOutputItemSet() );
     }
@@ -554,6 +568,21 @@ void FuPage::ApplyItemSet( const SfxItemSet* pArgs )
                 bSetPageSizeAndBorder = true;
             }
         }
+
+        if (mpDoc->GetDocumentType() == DocumentType::Impress && 
mpPage->IsMasterPage())
+        {
+            // The item set may have a theme.
+            auto it = pGrabBag->GetGrabBag().find("Theme");
+            if (it != pGrabBag->GetGrabBag().end())
+            {
+                std::unique_ptr<svx::Theme> pTheme = 
svx::Theme::FromAny(it->second);
+                
pMasterPage->getSdrPageProperties().SetTheme(std::move(pTheme));
+            }
+            else
+            {
+                SAL_WARN("sd.ui", "FuPage::ApplyItemSet: got no theme");
+            }
+        }
     }
 
     // Paper Bin
diff --git a/sd/source/ui/inc/dlgpage.hxx b/sd/source/ui/inc/dlgpage.hxx
index c4cd90e6045a..718ccf0c614b 100644
--- a/sd/source/ui/inc/dlgpage.hxx
+++ b/sd/source/ui/inc/dlgpage.hxx
@@ -40,7 +40,7 @@ private:
     XPatternListRef       mpPatternList;
 public:
 
-    SdPageDlg(SfxObjectShell const * pDocSh, weld::Window* pParent, const 
SfxItemSet* pAttr, bool bAreaPage, bool bIsImpressDoc);
+    SdPageDlg(SfxObjectShell const * pDocSh, weld::Window* pParent, const 
SfxItemSet* pAttr, bool bAreaPage, bool bIsImpressDoc, bool bIsImpressMaster);
 
     virtual void PageCreated(const OString& rId, SfxTabPage& rPage) override;
 };
diff --git a/sd/uiconfig/sdraw/ui/drawpagedialog.ui 
b/sd/uiconfig/sdraw/ui/drawpagedialog.ui
index 36aee9ac926f..d638e0e76081 100644
--- a/sd/uiconfig/sdraw/ui/drawpagedialog.ui
+++ b/sd/uiconfig/sdraw/ui/drawpagedialog.ui
@@ -235,6 +235,54 @@
                 <property name="tab_fill">False</property>
               </packing>
             </child>
+            <child>
+              <!-- n-columns=1 n-rows=1 -->
+              <object class="GtkGrid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="RID_SVXPAGE_THEME">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" 
context="drawpagedialog|RID_SVXPAGE_THEME">Theme</property>
+              </object>
+              <packing>
+                <property name="position">3</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>

Reply via email to