cui/qa/uitest/dialogs/chardlg.py        |    2 
 cui/qa/uitest/tabpages/themepage.py     |    4 -
 cui/qa/uitest/tabpages/tpcolor.py       |    2 
 docmodel/source/theme/Theme.cxx         |    2 
 filter/source/svg/svgexport.cxx         |   12 ++-
 include/docmodel/theme/Theme.hxx        |    1 
 oox/qa/unit/drawingml.cxx               |   28 ++++---
 sd/CppunitTest_sd_filter_eppt.mk        |    1 
 sd/qa/filter/eppt/eppt.cxx              |   28 ++++---
 sd/qa/unit/uiimpress.cxx                |   27 ++++---
 sd/source/ui/unoidl/unomodel.cxx        |    3 
 sd/source/ui/unoidl/unopage.cxx         |   32 +++++++-
 sw/inc/unodraw.hxx                      |   22 ++++-
 sw/inc/unomap.hxx                       |   18 ++++
 sw/qa/unoapi/knownissues.xcl            |    8 +-
 sw/source/core/unocore/unodraw.cxx      |  122 +++++++++++++++++++++++++++++++-
 sw/source/core/unocore/unomap.cxx       |   23 ++++++
 sw/source/core/unocore/unomap1.cxx      |    6 +
 xmloff/inc/XMLThemeContext.hxx          |   13 +--
 xmloff/qa/unit/draw.cxx                 |   52 +++++++++----
 xmloff/source/draw/sdxmlexp.cxx         |   78 ++++++++------------
 xmloff/source/style/XMLThemeContext.cxx |   72 +++++++++++++++---
 22 files changed, 423 insertions(+), 133 deletions(-)

New commits:
commit 961c8ea29294d7409419b117ba87e218460b725f
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Jan 27 15:04:33 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Fri Feb 17 05:23:53 2023 +0000

    sw: implement "Theme" property for the XDrawPage in Writer
    
    Change-Id: I8eed04f0ccb2e626a648abcaecd957b6f62c39d8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146226
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit 7ab51def766ad6bfdcf5111e7b751bbc2bbf1d73)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146451
    Tested-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 55e4be02052b..c27481baf79b 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -935,10 +935,14 @@ bool SVGFilter::implExportDocument()
     // #i124608#
     mbExportShapeSelection = mbSinglePage && maShapeSelection.is() && 
maShapeSelection->getCount();
 
-    if(xDefaultPagePropertySet.is())
-    {
-        xDefaultPagePropertySet->getPropertyValue( "Width" ) >>= nDocWidth;
-        xDefaultPagePropertySet->getPropertyValue( "Height" ) >>= nDocHeight;
+    if (xDefaultPagePropertySet.is())
+    {
+        sal_Int32 nWidth = 0;
+        sal_Int32 nHeight = 0;
+        if (xDefaultPagePropertySet->getPropertyValue("Width") >>= nWidth)
+            nDocWidth = nWidth;
+        if (xDefaultPagePropertySet->getPropertyValue("Height") >>= nHeight)
+            nDocHeight = nHeight;
     }
 
     if(mbExportShapeSelection)
diff --git a/sw/inc/unodraw.hxx b/sw/inc/unodraw.hxx
index d7a768317bbf..176830d2aebc 100644
--- a/sw/inc/unodraw.hxx
+++ b/sw/inc/unodraw.hxx
@@ -30,7 +30,8 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/XPropertyState.hpp>
 #include <com/sun/star/drawing/XShapes.hpp>
-#include <cppuhelper/implbase6.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/implbase2.hxx>
 #include <com/sun/star/container/XEnumerationAccess.hpp>
 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
 
@@ -39,16 +40,20 @@ class SdrView;
 class SwDoc;
 class SwXShape;
 
-typedef cppu::ImplInheritanceHelper
+typedef cppu::AggImplInheritanceHelper2
 <
     SvxFmDrawPage,
-    css::container::XEnumerationAccess
-> SwFmDrawPage_Base;
+    css::container::XEnumerationAccess,
+    css::beans::XPropertySet>
+        SwFmDrawPage_Base;
+
 class SwFmDrawPage final : public SwFmDrawPage_Base
 {
     SwDoc*          m_pDoc;
     SdrPageView*        m_pPageView;
     std::vector<rtl::Reference<SwXShape>> m_vShapes;
+    const SfxItemPropertySet* m_pPropertySet;
+
 public:
     SwFmDrawPage( SwDoc* pDoc, SdrPage* pPage );
     virtual ~SwFmDrawPage() noexcept override;
@@ -100,6 +105,15 @@ public:
     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 
override;
     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() 
override;
 
+    //XPropertySet
+    virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL 
getPropertySetInfo() override;
+    virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, 
const css::uno::Any& aValue) override;
+    virtual css::uno::Any SAL_CALL getPropertyValue(const OUString& 
PropertyName) override;
+    virtual void SAL_CALL addPropertyChangeListener(const OUString& 
aPropertyName, const css::uno::Reference<css::beans::XPropertyChangeListener>& 
xListener) override;
+    virtual void SAL_CALL removePropertyChangeListener(const OUString& 
aPropertyName, const css::uno::Reference<css::beans::XPropertyChangeListener>& 
aListener) override;
+    virtual void SAL_CALL addVetoableChangeListener(const OUString& 
PropertyName, const css::uno::Reference<css::beans::XVetoableChangeListener>& 
aListener) override;
+    virtual void SAL_CALL removeVetoableChangeListener(const OUString& 
PropertyName, const css::uno::Reference<css::beans::XVetoableChangeListener>& 
aListener) override;
+
     // renamed and outlined to detect where it's called
     void    InvalidateSwDoc(); // {pDoc = 0;}
 };
diff --git a/sw/inc/unomap.hxx b/sw/inc/unomap.hxx
index 689fa87063a1..84245bea2d14 100644
--- a/sw/inc/unomap.hxx
+++ b/sw/inc/unomap.hxx
@@ -128,7 +128,8 @@ class SfxItemPropertySet;
 #define PROPERTY_MAP_FIELDMARK                          102
 #define PROPERTY_MAP_LINEBREAK                          103
 #define PROPERTY_MAP_CONTENTCONTROL                     104
-#define PROPERTY_MAP_END                                105
+#define PROPERTY_MAP_TEXT_PAGE                          105
+#define PROPERTY_MAP_END                                106
 
 //S&E
 #define WID_WORDS                0
@@ -307,6 +308,21 @@ class SfxItemPropertySet;
 #define WID_IS_OUTLINE                  4
 #define WID_DEFAULT_LIST_ID             5
 
+#define WID_PAGE_BOTTOM 0
+#define WID_PAGE_LEFT   1
+#define WID_PAGE_RIGHT  2
+#define WID_PAGE_TOP    3
+#define WID_PAGE_WIDTH  4
+#define WID_PAGE_HEIGHT 5
+#define WID_PAGE_NUMBER 6
+#define WID_PAGE_ORIENT 7
+#define WID_PAGE_USERATTRIBS 8
+#define WID_PAGE_ISDARK 9
+#define WID_NAVORDER 10
+#define WID_PAGE_BACKFULL 11
+
+#define WID_PAGE_THEME 12
+
 // This define would need the include of <svx/unoshprp.hxx>, but this ends
 // in a mess; there *are* double used symbols which are used in a #define in
 // editengine and as an enum in sw; these will then collide and lead to severe
diff --git a/sw/qa/unoapi/knownissues.xcl b/sw/qa/unoapi/knownissues.xcl
index fdd88e231de9..7b62e95407e6 100644
--- a/sw/qa/unoapi/knownissues.xcl
+++ b/sw/qa/unoapi/knownissues.xcl
@@ -114,14 +114,14 @@ sw.SwXTextDocument::com::sun::star::frame::XStorable
 
 ### i85640 ###
 sw.SwXMailMerge
-#-> disabled in sw.sce 
+#-> disabled in sw.sce
 
 ### i86656 ###
 
sw.SwAccessibleDocumentView::com::sun::star::accessibility::XAccessibleComponent
 
 ### i86751 ###
 
sw.SwAccessibleDocumentPageView::com::sun::star::accessibility::XAccessibleEventBroadcaster
-#-> disabled in sw.sce 
+#-> disabled in sw.sce
 
 ### i87978 ###
 sw.DocumentSettings::com::sun::star::beans::XPropertySet
@@ -148,11 +148,11 @@ 
sw.SwAccessibleTextGraphicObject::com::sun::star::accessibility::XAccessibleCont
 
 ### i89021 ###
 sw.SwXTextDefaults
-#-> disabled in sw.sce 
+#-> disabled in sw.sce
 
 ### i89022 ###
 sw.SwAccessiblePageView
-#-> disabled in sw.sce 
+#-> disabled in sw.sce
 
 ### i89419 ###
 sw.SwXTextEmbeddedObject::com::sun::star::text::BaseFrameProperties
diff --git a/sw/source/core/unocore/unodraw.cxx 
b/sw/source/core/unocore/unodraw.cxx
index 517dd5aaa8cd..42977b41583d 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -77,6 +77,7 @@
 #include <com/sun/star/drawing/PointSequence.hpp>
 #include <com/sun/star/lang/IllegalArgumentException.hpp>
 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <docmodel/uno/UnoTheme.hxx>
 
 using namespace ::com::sun::star;
 
@@ -252,8 +253,11 @@ public:
     }
 };
 
-SwFmDrawPage::SwFmDrawPage( SwDoc* pDoc, SdrPage* pPage ) :
-    SwFmDrawPage_Base( pPage ), m_pDoc(pDoc), m_pPageView(nullptr)
+SwFmDrawPage::SwFmDrawPage( SwDoc* pDoc, SdrPage* pPage )
+    : SwFmDrawPage_Base(pPage)
+    , m_pDoc(pDoc)
+    , m_pPageView(nullptr)
+    , m_pPropertySet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_PAGE))
 {
 }
 
@@ -382,6 +386,120 @@ uno::Reference< drawing::XShape > 
SwFmDrawPage::CreateShape( SdrObject *pObj ) c
     return xRet;
 }
 
+uno::Reference<beans::XPropertySetInfo> SwFmDrawPage::getPropertySetInfo()
+{
+    static uno::Reference<beans::XPropertySetInfo> xRet = 
m_pPropertySet->getPropertySetInfo();
+    return xRet;
+}
+
+void SwFmDrawPage::setPropertyValue(const OUString& rPropertyName, const 
uno::Any& aValue)
+{
+    SolarMutexGuard aGuard;
+    const SfxItemPropertyMapEntry* pEntry = 
m_pPropertySet->getPropertyMap().getByName(rPropertyName);
+
+    switch (pEntry ? pEntry->nWID : -1)
+    {
+        case WID_PAGE_THEME:
+        {
+            SdrPage* pPage = GetSdrPage();
+            css::uno::Reference<css::util::XTheme> xTheme;
+            if (aValue >>= xTheme)
+            {
+                auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+                std::unique_ptr<model::Theme> pTheme(new 
model::Theme(pUnoTheme->getTheme()));
+                pPage->getSdrPageProperties().SetTheme(std::move(pTheme));
+            }
+        }
+        break;
+        case WID_PAGE_BOTTOM:
+        case WID_PAGE_LEFT:
+        case WID_PAGE_RIGHT:
+        case WID_PAGE_TOP:
+        case WID_PAGE_WIDTH:
+        case WID_PAGE_HEIGHT:
+        case WID_PAGE_NUMBER:
+        case WID_PAGE_ORIENT:
+        case WID_PAGE_USERATTRIBS:
+        case WID_PAGE_ISDARK:
+        case WID_NAVORDER:
+        case WID_PAGE_BACKFULL:
+            break;
+
+        default:
+            throw beans::UnknownPropertyException(rPropertyName, 
static_cast<cppu::OWeakObject*>(this));
+    }
+}
+
+uno::Any SwFmDrawPage::getPropertyValue(const OUString& rPropertyName)
+{
+    SolarMutexGuard aGuard;
+    const SfxItemPropertyMapEntry* pEntry = 
m_pPropertySet->getPropertyMap().getByName( rPropertyName);
+
+    uno::Any aAny;
+
+    switch (pEntry ? pEntry->nWID : -1)
+    {
+        case WID_PAGE_THEME:
+        {
+            css::uno::Reference<css::util::XTheme> xTheme;
+
+            auto* pTheme = GetSdrPage()->getSdrPageProperties().GetTheme();
+            if (pTheme)
+                xTheme = new UnoTheme(*pTheme);
+            aAny <<= xTheme;
+        }
+        break;
+
+        case WID_PAGE_NUMBER:
+        {
+            const sal_uInt16 nPageNumber(GetSdrPage()->GetPageNum());
+            aAny <<= o3tl::narrowing<sal_Int16>(nPageNumber);
+        }
+        break;
+
+        case WID_PAGE_BOTTOM:
+        case WID_PAGE_LEFT:
+        case WID_PAGE_RIGHT:
+        case WID_PAGE_TOP:
+        case WID_PAGE_WIDTH:
+        case WID_PAGE_HEIGHT:
+        case WID_PAGE_ORIENT:
+        case WID_PAGE_USERATTRIBS:
+        case WID_PAGE_ISDARK:
+        case WID_NAVORDER:
+        case WID_PAGE_BACKFULL:
+            break;
+
+        default:
+            throw beans::UnknownPropertyException(rPropertyName, 
static_cast<cppu::OWeakObject*>(this));
+    }
+    return aAny;
+}
+
+void SwFmDrawPage::addPropertyChangeListener(const OUString& /*PropertyName*/,
+    const uno::Reference<beans::XPropertyChangeListener> & /*aListener*/)
+{
+    OSL_FAIL("not implemented");
+}
+
+void SwFmDrawPage::removePropertyChangeListener(const OUString& 
/*PropertyName*/,
+    const uno::Reference<beans::XPropertyChangeListener> & /*aListener*/)
+{
+    OSL_FAIL("not implemented");
+}
+
+void SwFmDrawPage::addVetoableChangeListener(const OUString& /*PropertyName*/,
+    const uno::Reference<beans::XVetoableChangeListener> & /*aListener*/)
+{
+    OSL_FAIL("not implemented");
+}
+
+void SwFmDrawPage::removeVetoableChangeListener(const OUString& 
/*PropertyName*/,
+    const uno::Reference<beans::XVetoableChangeListener> & /*aListener*/)
+{
+    OSL_FAIL("not implemented");
+}
+
 namespace
 {
     class SwXShapesEnumeration
diff --git a/sw/source/core/unocore/unomap.cxx 
b/sw/source/core/unocore/unomap.cxx
index f6765dadd4b9..a978b5b378cd 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -45,6 +45,8 @@
 #include <com/sun/star/text/XTextSection.hpp>
 #include <com/sun/star/util/Date.hpp>
 #include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/XTheme.hpp>
+#include <com/sun/star/view/PaperOrientation.hpp>
 #include <com/sun/star/script/XLibraryContainer.hpp>
 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
 #include <osl/diagnose.h>
@@ -232,6 +234,27 @@ o3tl::span<const SfxItemPropertyMapEntry> 
SwUnoPropertyMapProvider::GetPropertyM
                 m_aMapEntriesArr[nPropertyId] = GetEmbeddedPropertyMap();
             }
             break;
+            case PROPERTY_MAP_TEXT_PAGE:
+            {
+                static SfxItemPropertyMapEntry const aPageMap_Impl[] =
+                {
+                    { u"BorderBottom", WID_PAGE_BOTTOM, 
::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"BorderLeft", WID_PAGE_LEFT,     
::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"BorderRight", WID_PAGE_RIGHT,   
::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"BorderTop", WID_PAGE_TOP,       
::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"Height", WID_PAGE_HEIGHT,       
::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"Width", WID_PAGE_WIDTH,         
::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"Number", WID_PAGE_NUMBER,       
::cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"Orientation", WID_PAGE_ORIENT,  
::cppu::UnoType<view::PaperOrientation>::get(), 
PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY,  0},
+                    { u"UserDefinedAttributes", WID_PAGE_USERATTRIBS, 
::cppu::UnoType<container::XNameContainer>::get(), 
PropertyAttribute::MAYBEVOID,  0},
+                    { u"IsBackgroundDark", WID_PAGE_ISDARK, 
::cppu::UnoType<bool>::get(), 
PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY,  0},
+                    { u"NavigationOrder", WID_NAVORDER,     
::cppu::UnoType<container::XIndexAccess>::get(), PropertyAttribute::MAYBEVOID,  
0},
+                    { u"BackgroundFullSize", WID_PAGE_BACKFULL, 
::cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID,  0},
+                    { u"Theme", WID_PAGE_THEME, 
cppu::UnoType<util::XTheme>::get(), PropertyAttribute::MAYBEVOID,  0}
+                };
+                m_aMapEntriesArr[nPropertyId] = aPageMap_Impl;
+            }
+            break;
             case PROPERTY_MAP_TEXT_SHAPE:
             {
                 static SfxItemPropertyMapEntry const aShapeMap_Impl[] =
diff --git a/sw/source/core/unocore/unomap1.cxx 
b/sw/source/core/unocore/unomap1.cxx
index e5fcd7779607..c42a49bd1b26 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1162,6 +1162,12 @@ const SfxItemPropertySet*  
SwUnoPropertyMapProvider::GetPropertySet( sal_uInt16
                 m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_GRAPHIC;
             }
             break;
+            case PROPERTY_MAP_TEXT_PAGE:
+            {
+                static SfxItemPropertySet aPROPERTY_MAP_TEXT_PAGE(pEntries);
+                m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_PAGE;
+            }
+            break;
             case PROPERTY_MAP_TEXT_SHAPE:
             {
                 static SfxItemPropertySet aPROPERTY_MAP_TEXT_SHAPE(pEntries);
commit 126d0db2c2315565d45e3b0408576d40ab97a443
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Jan 27 15:03:09 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Fri Feb 17 05:23:43 2023 +0000

    sd: use XTheme to transport the theme to xmloff import/export
    
    Refactor the existing places and tests in Impress code (sd) to
    use it instead.
    
    Also keep the old property of construction and view of the theme
    with a sequence of property values, but  under the new property
    named "ThemeUnoRepresentation". This is needed by the UI tests
    currently.
    
    Change-Id: I484567f4a603f1a5e2e03955fdd2b63132dcc66e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146225
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit 75c0d7827625c683d52a9e2f3a7c514df890107b)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146450
    Tested-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/cui/qa/uitest/dialogs/chardlg.py b/cui/qa/uitest/dialogs/chardlg.py
index c52664f36d0e..4a756cf6c979 100644
--- a/cui/qa/uitest/dialogs/chardlg.py
+++ b/cui/qa/uitest/dialogs/chardlg.py
@@ -74,7 +74,7 @@ class Test(UITestCase):
                     0x000000,  # folHlink
                 ])
             })
-            master.Theme = theme
+            master.ThemeUnoRepresentation = theme
 
             # Select the title shape.
             editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
diff --git a/cui/qa/uitest/tabpages/themepage.py 
b/cui/qa/uitest/tabpages/themepage.py
index f85af965f626..0145f0345492 100644
--- a/cui/qa/uitest/tabpages/themepage.py
+++ b/cui/qa/uitest/tabpages/themepage.py
@@ -41,7 +41,7 @@ class Test(UITestCase):
                     0x000000,  # folHlink
                 ])
             })
-            master.Theme = theme
+            master.ThemeUnoRepresentation = theme
 
             # When changing the name of the theme:
             self.xUITest.executeCommand(".uno:SlideMasterPage")
@@ -71,7 +71,7 @@ class Test(UITestCase):
             # 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)
+            theme = 
convert_property_values_to_dict(master.ThemeUnoRepresentation)
             self.assertEqual(theme["Name"], "nameB")
             # Without the accompanying fix in place, this test would have 
failed with:
             # AssertionError: 'colorSetA' != 'colorSetB'
diff --git a/cui/qa/uitest/tabpages/tpcolor.py 
b/cui/qa/uitest/tabpages/tpcolor.py
index e6ae91adaac3..ad52711857e4 100644
--- a/cui/qa/uitest/tabpages/tpcolor.py
+++ b/cui/qa/uitest/tabpages/tpcolor.py
@@ -41,7 +41,7 @@ class Test(UITestCase):
                     0x000000,  # folHlink
                 ])
             })
-            master.Theme = theme
+            master.ThemeUnoRepresentation = theme
             # Select the title shape.
             editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
 
diff --git a/docmodel/source/theme/Theme.cxx b/docmodel/source/theme/Theme.cxx
index 5f755b0774a3..b8fad072144a 100644
--- a/docmodel/source/theme/Theme.cxx
+++ b/docmodel/source/theme/Theme.cxx
@@ -24,6 +24,8 @@ using namespace com::sun::star;
 
 namespace model
 {
+Theme::Theme() = default;
+
 Theme::Theme(OUString const& rName)
     : maName(rName)
 {
diff --git a/include/docmodel/theme/Theme.hxx b/include/docmodel/theme/Theme.hxx
index 6ef239fc7578..9c9bc027d29d 100644
--- a/include/docmodel/theme/Theme.hxx
+++ b/include/docmodel/theme/Theme.hxx
@@ -134,6 +134,7 @@ private:
     FontScheme maFontScheme;
 
 public:
+    Theme();
     Theme(OUString const& rName);
 
     Theme(Theme const& rTheme);
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index 5c09ca3de463..3355b66e79f6 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -28,8 +28,10 @@
 #include <com/sun/star/lang/Locale.hpp>
 #include <com/sun/star/text/XTextRange.hpp>
 #include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/util/XTheme.hpp>
 
 #include <docmodel/uno/UnoThemeColor.hxx>
+#include <docmodel/uno/UnoTheme.hxx>
 
 #include <comphelper/sequenceashashmap.hxx>
 
@@ -373,19 +375,21 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testPptxTheme)
     uno::Reference<drawing::XMasterPageTarget> xDrawPage(
         xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<beans::XPropertySet> 
xMasterpage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
-    comphelper::SequenceAsHashMap aMap(xMasterpage->getPropertyValue("Theme"));
-    CPPUNIT_ASSERT_EQUAL(OUString("Office Theme"), 
aMap["Name"].get<OUString>());
-    // Without the accompanying fix in place, this test would have failed with:
-    // - Cannot extract an Any(void) to string!
-    // i.e. the name of the color scheme was lost on import.
-    CPPUNIT_ASSERT_EQUAL(OUString("Office"), 
aMap["ColorSchemeName"].get<OUString>());
 
-    // Check the last color in the color set, value is from 
ppt/theme/theme1.xml.
-    // Without the accompanying fix in place, this test would have failed with:
-    // - Cannot extract an Any(void) to []long!
-    auto aColorScheme = aMap["ColorScheme"].get<uno::Sequence<util::Color>>();
-    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(12), aColorScheme.getLength());
-    CPPUNIT_ASSERT_EQUAL(static_cast<util::Color>(0x954F72), aColorScheme[11]);
+    uno::Reference<util::XTheme> xTheme;
+    xMasterpage->getPropertyValue("Theme") >>= xTheme;
+
+    // We expect the theme to be set on the master page
+    CPPUNIT_ASSERT(xTheme.is());
+    auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+    CPPUNIT_ASSERT(pUnoTheme);
+    auto const& rTheme = pUnoTheme->getTheme();
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Office Theme"), rTheme.GetName());
+    CPPUNIT_ASSERT_EQUAL(OUString("Office"), rTheme.GetColorSet()->getName());
+
+    CPPUNIT_ASSERT_EQUAL(Color(0x954F72),
+                         
rTheme.GetColorSet()->getColor(model::ThemeColorType::FollowedHyperlink));
 
     // Check the reference to that theme:
     uno::Reference<drawing::XShapes> xDrawPageShapes(xDrawPage, 
uno::UNO_QUERY);
diff --git a/sd/CppunitTest_sd_filter_eppt.mk b/sd/CppunitTest_sd_filter_eppt.mk
index 2a570b5dcd92..261fa3052ee8 100644
--- a/sd/CppunitTest_sd_filter_eppt.mk
+++ b/sd/CppunitTest_sd_filter_eppt.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sd_filter_eppt, \
     comphelper \
     cppu \
     cppuhelper \
+    docmodel \
     sd \
     sal \
     subsequenttest \
diff --git a/sd/qa/filter/eppt/eppt.cxx b/sd/qa/filter/eppt/eppt.cxx
index 57c73456aea0..fe8151a67638 100644
--- a/sd/qa/filter/eppt/eppt.cxx
+++ b/sd/qa/filter/eppt/eppt.cxx
@@ -15,7 +15,7 @@
 #include <com/sun/star/util/Color.hpp>
 
 #include <test/xmldocptr.hxx>
-#include <comphelper/sequenceashashmap.hxx>
+#include <docmodel/uno/UnoTheme.hxx>
 
 using namespace ::com::sun::star;
 
@@ -66,14 +66,24 @@ CPPUNIT_TEST_FIXTURE(Test, testThemeExport)
     uno::Reference<drawing::XMasterPageTarget> xDrawPage(
         xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<beans::XPropertySet> 
xMasterPage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
-    comphelper::SequenceAsHashMap aMap;
-    aMap["Name"] <<= OUString("mytheme");
-    aMap["ColorSchemeName"] <<= OUString("mycolorscheme");
-    uno::Sequence<util::Color> aColorScheme
-        = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc };
-    aMap["ColorScheme"] <<= aColorScheme;
-    uno::Any aTheme(aMap.getAsConstPropertyValueList());
-    xMasterPage->setPropertyValue("Theme", aTheme);
+
+    model::Theme aTheme("mytheme");
+    std::unique_ptr<model::ColorSet> pColorSet(new 
model::ColorSet("mycolorscheme"));
+    pColorSet->add(model::ThemeColorType::Dark1, 0x1);
+    pColorSet->add(model::ThemeColorType::Light1, 0x2);
+    pColorSet->add(model::ThemeColorType::Dark2, 0x3);
+    pColorSet->add(model::ThemeColorType::Light2, 0x4);
+    pColorSet->add(model::ThemeColorType::Accent1, 0x5);
+    pColorSet->add(model::ThemeColorType::Accent2, 0x6);
+    pColorSet->add(model::ThemeColorType::Accent3, 0x7);
+    pColorSet->add(model::ThemeColorType::Accent4, 0x8);
+    pColorSet->add(model::ThemeColorType::Accent5, 0x9);
+    pColorSet->add(model::ThemeColorType::Accent6, 0xa);
+    pColorSet->add(model::ThemeColorType::Hyperlink, 0xb);
+    pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xc);
+    aTheme.SetColorSet(std::move(pColorSet));
+
+    xMasterPage->setPropertyValue("Theme", 
uno::Any(model::theme::createXTheme(aTheme)));
 
     // When exporting to PPTX:
     save("Impress Office Open XML");
diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx
index bcd78977890b..083ebf0b094c 100644
--- a/sd/qa/unit/uiimpress.cxx
+++ b/sd/qa/unit/uiimpress.cxx
@@ -46,6 +46,7 @@
 #include <docmodel/uno/UnoThemeColor.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/sequenceashashmap.hxx>
+#include <docmodel/uno/UnoTheme.hxx>
 
 #include <drawdoc.hxx>
 #include <DrawDocShell.hxx>
@@ -1142,14 +1143,24 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, 
testThemeShapeInsert)
     uno::Reference<drawing::XMasterPageTarget> xMasterPageTarget(xDrawPage, 
uno::UNO_QUERY);
     uno::Reference<beans::XPropertySet> 
xMasterPage(xMasterPageTarget->getMasterPage(),
                                                     uno::UNO_QUERY);
-    comphelper::SequenceAsHashMap aMap;
-    aMap["Name"] <<= OUString("mytheme");
-    aMap["ColorSchemeName"] <<= OUString("mycolorscheme");
-    uno::Sequence<util::Color> aColorScheme
-        = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb };
-    aMap["ColorScheme"] <<= aColorScheme;
-    uno::Any aTheme(aMap.getAsConstPropertyValueList());
-    xMasterPage->setPropertyValue("Theme", aTheme);
+
+    model::Theme aTheme("mytheme");
+    std::unique_ptr<model::ColorSet> pColorSet(new 
model::ColorSet("mycolorscheme"));
+    pColorSet->add(model::ThemeColorType::Dark1, 0x0);
+    pColorSet->add(model::ThemeColorType::Light1, 0x1);
+    pColorSet->add(model::ThemeColorType::Dark2, 0x2);
+    pColorSet->add(model::ThemeColorType::Light2, 0x3);
+    pColorSet->add(model::ThemeColorType::Accent1, 0x4);
+    pColorSet->add(model::ThemeColorType::Accent2, 0x5);
+    pColorSet->add(model::ThemeColorType::Accent3, 0x6);
+    pColorSet->add(model::ThemeColorType::Accent4, 0x7);
+    pColorSet->add(model::ThemeColorType::Accent5, 0x8);
+    pColorSet->add(model::ThemeColorType::Accent6, 0x9);
+    pColorSet->add(model::ThemeColorType::Hyperlink, 0xa);
+    pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xb);
+    aTheme.SetColorSet(std::move(pColorSet));
+
+    xMasterPage->setPropertyValue("Theme", 
uno::Any(model::theme::createXTheme(aTheme)));
 
     // When inserting a shape:
     uno::Sequence<beans::PropertyValue> aArgs = {
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 4f26c01046cd..2aab62dc02ab 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -28,6 +28,7 @@
 #include <com/sun/star/awt/XDevice.hpp>
 #include <com/sun/star/document/IndexedPropertyValues.hpp>
 #include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/util/XTheme.hpp>
 
 #include <com/sun/star/embed/Aspects.hpp>
 
@@ -245,7 +246,7 @@ static const SvxItemPropertySet* 
ImplGetDrawModelPropertySet()
         { sUNO_Prop_HasValidSignatures,   WID_MODEL_HASVALIDSIGNATURES, 
::cppu::UnoType<sal_Bool>::get(),                      
beans::PropertyAttribute::READONLY, 0},
         { u"Fonts",                        WID_MODEL_FONTS,              
cppu::UnoType<uno::Sequence<uno::Any>>::get(),                     
beans::PropertyAttribute::READONLY, 0},
         { sUNO_Prop_InteropGrabBag,       WID_MODEL_INTEROPGRABBAG,     
cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(),       0, 0},
-        { sUNO_Prop_Theme,                WID_MODEL_THEME,              
cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(),       0, 0},
+        { sUNO_Prop_Theme,                WID_MODEL_THEME,              
cppu::UnoType<util::XTheme>::get(),       0, 0},
     };
     static SvxItemPropertySet aDrawModelPropertySet_Impl( 
aDrawModelPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
     return &aDrawModelPropertySet_Impl;
diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx
index 20afdce58370..df1b57ed3354 100644
--- a/sd/source/ui/unoidl/unopage.cxx
+++ b/sd/source/ui/unoidl/unopage.cxx
@@ -29,6 +29,7 @@
 #include <com/sun/star/presentation/AnimationSpeed.hpp>
 #include <com/sun/star/view/PaperOrientation.hpp>
 #include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/util/XTheme.hpp>
 #include <cppuhelper/implbase.hxx>
 #include <comphelper/profilezone.hxx>
 #include <comphelper/servicehelper.hxx>
@@ -74,6 +75,7 @@
 #include <vcl/dibtools.hxx>
 #include <tools/debug.hxx>
 #include <tools/stream.hxx>
+#include <docmodel/uno/UnoTheme.hxx>
 #include <o3tl/string_view.hxx>
 
 using ::com::sun::star::animations::XAnimationNode;
@@ -100,7 +102,7 @@ enum WID_PAGE
     WID_PAGE_PAGENUMBERVISIBLE, WID_PAGE_DATETIMEVISIBLE, 
WID_PAGE_DATETIMEFIXED,
     WID_PAGE_DATETIMETEXT, WID_PAGE_DATETIMEFORMAT, WID_TRANSITION_TYPE, 
WID_TRANSITION_SUBTYPE,
     WID_TRANSITION_DIRECTION, WID_TRANSITION_FADE_COLOR, 
WID_TRANSITION_DURATION, WID_LOOP_SOUND,
-    WID_NAVORDER, WID_PAGE_PREVIEWMETAFILE, WID_PAGE_THEME
+    WID_NAVORDER, WID_PAGE_PREVIEWMETAFILE, WID_PAGE_THEME, 
WID_PAGE_THEME_UNO_REPRESENTATION
 };
 
 }
@@ -279,7 +281,9 @@ static const SvxItemPropertySet* 
ImplGetMasterPagePropertySet( PageKind ePageKin
         { u"BackgroundFullSize",           WID_PAGE_BACKFULL,  
cppu::UnoType<bool>::get(),                        0, 0},
         { sUNO_Prop_UserDefinedAttributes,WID_PAGE_USERATTRIBS, 
cppu::UnoType<css::container::XNameContainer>::get(),         0,     0},
         { u"IsBackgroundDark",             WID_PAGE_ISDARK,    
cppu::UnoType<bool>::get(),                        
beans::PropertyAttribute::READONLY, 0},
-        { u"Theme", WID_PAGE_THEME, cppu::UnoType<uno::Sequence< 
beans::PropertyValue >>::get(), 0,  0}
+        { u"Theme", WID_PAGE_THEME, cppu::UnoType<util::XTheme>::get(), 0,  0},
+        // backwards compatible view of the theme for use in tests
+        { u"ThemeUnoRepresentation", WID_PAGE_THEME_UNO_REPRESENTATION, 
cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get(), 0,  0}
     };
 
     static const SfxItemPropertyMapEntry aHandoutMasterPagePropertyMap_Impl[] =
@@ -970,6 +974,19 @@ void SAL_CALL SdGenericDrawPage::setPropertyValue( const 
OUString& aPropertyName
         }
 
         case WID_PAGE_THEME:
+        {
+            SdrPage* pPage = GetPage();
+            uno::Reference<util::XTheme> xTheme;
+            if (aValue >>= xTheme)
+            {
+                auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+                std::unique_ptr<model::Theme> pTheme(new 
model::Theme(pUnoTheme->getTheme()));
+                pPage->getSdrPageProperties().SetTheme(std::move(pTheme));
+            }
+            break;
+        }
+
+        case WID_PAGE_THEME_UNO_REPRESENTATION:
         {
             SdrPage* pPage = GetPage();
             std::unique_ptr<model::Theme> pTheme = 
model::Theme::FromAny(aValue);
@@ -1292,6 +1309,17 @@ Any SAL_CALL SdGenericDrawPage::getPropertyValue( const 
OUString& PropertyName )
         break;
 
     case WID_PAGE_THEME:
+    {
+        SdrPage* pPage = GetPage();
+        css::uno::Reference<css::util::XTheme> xTheme;
+        auto* pTheme = pPage->getSdrPageProperties().GetTheme();
+        if (pTheme)
+            xTheme = new UnoTheme(*pTheme);
+        aAny <<= xTheme;
+        break;
+    }
+
+    case WID_PAGE_THEME_UNO_REPRESENTATION:
     {
         SdrPage* pPage = GetPage();
         model::Theme* pTheme = pPage->getSdrPageProperties().GetTheme();
diff --git a/xmloff/inc/XMLThemeContext.hxx b/xmloff/inc/XMLThemeContext.hxx
index 706c1251a534..50889a0ddf98 100644
--- a/xmloff/inc/XMLThemeContext.hxx
+++ b/xmloff/inc/XMLThemeContext.hxx
@@ -14,14 +14,14 @@
 #include <com/sun/star/util/Color.hpp>
 #include <com/sun/star/container/XNameContainer.hpp>
 
-#include <comphelper/sequenceashashmap.hxx>
-#include <comphelper/namecontainer.hxx>
+#include <docmodel/theme/Theme.hxx>
+#include <docmodel/theme/ColorSet.hxx>
 
 /// Imports the theme
 class XMLThemeContext : public SvXMLImportContext
 {
     css::uno::Reference<css::drawing::XDrawPage> m_xPage;
-    comphelper::SequenceAsHashMap m_aTheme;
+    model::Theme maTheme;
 
 public:
     XMLThemeContext(SvXMLImport& rImport,
@@ -37,13 +37,14 @@ public:
 /// Imports the color table of a theme
 class XMLColorTableContext : public SvXMLImportContext
 {
-    comphelper::SequenceAsHashMap& m_rTheme;
+    model::Theme& mrTheme;
+    std::unique_ptr<model::ColorSet> mpColorSet;
     std::vector<css::util::Color> m_aColorScheme;
 
 public:
     XMLColorTableContext(SvXMLImport& rImport,
                          
css::uno::Reference<css::xml::sax::XFastAttributeList> const& xAttrList,
-                         comphelper::SequenceAsHashMap& rTheme);
+                         model::Theme& mrTheme);
     ~XMLColorTableContext();
 
     css::uno::Reference<css::xml::sax::XFastContextHandler> SAL_CALL 
createFastChildContext(
@@ -57,7 +58,7 @@ class XMLColorContext : public SvXMLImportContext
 public:
     XMLColorContext(SvXMLImport& rImport,
                     css::uno::Reference<css::xml::sax::XFastAttributeList> 
const& xAttrList,
-                    std::vector<css::util::Color>& rColorScheme);
+                    std::unique_ptr<model::ColorSet>& rpColorSet);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx
index d66a96e1350c..c4671d95859b 100644
--- a/xmloff/qa/unit/draw.cxx
+++ b/xmloff/qa/unit/draw.cxx
@@ -30,6 +30,7 @@
 #include <svx/svdpage.hxx>
 #include <svx/svdomedia.hxx>
 #include <docmodel/uno/UnoThemeColor.hxx>
+#include <docmodel/uno/UnoTheme.hxx>
 
 using namespace ::com::sun::star;
 
@@ -130,14 +131,25 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeExport)
     uno::Reference<drawing::XMasterPageTarget> xDrawPage(
         xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<beans::XPropertySet> 
xMasterPage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
-    comphelper::SequenceAsHashMap aMap;
-    aMap["Name"] <<= OUString("mytheme");
-    aMap["ColorSchemeName"] <<= OUString("mycolorscheme");
-    uno::Sequence<util::Color> aColorScheme
-        = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb };
-    aMap["ColorScheme"] <<= aColorScheme;
-    uno::Any aTheme(aMap.getAsConstPropertyValueList());
-    xMasterPage->setPropertyValue("Theme", aTheme);
+
+    model::Theme aTheme("mytheme");
+    std::unique_ptr<model::ColorSet> pColorSet(new 
model::ColorSet("mycolorscheme"));
+    pColorSet->add(model::ThemeColorType::Dark1, 0x0);
+    pColorSet->add(model::ThemeColorType::Light1, 0x1);
+    pColorSet->add(model::ThemeColorType::Dark2, 0x2);
+    pColorSet->add(model::ThemeColorType::Light2, 0x3);
+    pColorSet->add(model::ThemeColorType::Accent1, 0x4);
+    pColorSet->add(model::ThemeColorType::Accent2, 0x5);
+    pColorSet->add(model::ThemeColorType::Accent3, 0x6);
+    pColorSet->add(model::ThemeColorType::Accent4, 0x7);
+    pColorSet->add(model::ThemeColorType::Accent5, 0x8);
+    pColorSet->add(model::ThemeColorType::Accent6, 0x9);
+    pColorSet->add(model::ThemeColorType::Hyperlink, 0xa);
+    pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xb);
+    aTheme.SetColorSet(std::move(pColorSet));
+
+    uno::Reference<util::XTheme> xTheme = model::theme::createXTheme(aTheme);
+    xMasterPage->setPropertyValue("Theme", uno::Any(xTheme));
 
     // Export to ODP:
     save("impress8");
@@ -205,15 +217,21 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeImport)
     uno::Reference<drawing::XMasterPageTarget> xDrawPage(
         xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<beans::XPropertySet> 
xMasterpage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
-    comphelper::SequenceAsHashMap aMap(xMasterpage->getPropertyValue("Theme"));
-    // Without the accompanying fix in place, this test would have failed with:
-    // Cannot extract an Any(void) to string!
-    // i.e. the master page had no theme.
-    CPPUNIT_ASSERT_EQUAL(OUString("Office Theme"), 
aMap["Name"].get<OUString>());
-    CPPUNIT_ASSERT_EQUAL(OUString("Office"), 
aMap["ColorSchemeName"].get<OUString>());
-    auto aColorScheme = aMap["ColorScheme"].get<uno::Sequence<util::Color>>();
-    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(12), aColorScheme.getLength());
-    CPPUNIT_ASSERT_EQUAL(static_cast<util::Color>(0x954F72), aColorScheme[11]);
+
+    uno::Reference<util::XTheme> xTheme;
+    xMasterpage->getPropertyValue("Theme") >>= xTheme;
+
+    // We expect the theme to be set on the master page
+    CPPUNIT_ASSERT(xTheme.is());
+    auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+    CPPUNIT_ASSERT(pUnoTheme);
+    auto const& rTheme = pUnoTheme->getTheme();
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Office Theme"), rTheme.GetName());
+    CPPUNIT_ASSERT_EQUAL(OUString("Office"), rTheme.GetColorSet()->getName());
+
+    CPPUNIT_ASSERT_EQUAL(Color(0x954F72),
+                         
rTheme.GetColorSet()->getColor(model::ThemeColorType::FollowedHyperlink));
 }
 
 CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeColorExportImport)
diff --git a/xmloff/source/draw/sdxmlexp.cxx b/xmloff/source/draw/sdxmlexp.cxx
index df0c7e45aa27..0e7fc6160867 100644
--- a/xmloff/source/draw/sdxmlexp.cxx
+++ b/xmloff/source/draw/sdxmlexp.cxx
@@ -73,8 +73,8 @@
 #include <com/sun/star/document/XDocumentProperties.hpp>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <com/sun/star/util/Color.hpp>
-
-#include <comphelper/sequenceashashmap.hxx>
+#include <docmodel/uno/UnoTheme.hxx>
+#include <o3tl/enumrange.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -2367,56 +2367,42 @@ void SdXMLExport::exportFormsElement( const Reference< 
XDrawPage >& xDrawPage )
 
 void SdXMLExport::ExportThemeElement(const uno::Reference<drawing::XDrawPage>& 
xDrawPage)
 {
+    if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0)
+    {
+        // Do not export in standard ODF 1.3 or older.
+        return;
+    }
+
     uno::Reference<beans::XPropertySet> xPropertySet(xDrawPage, 
uno::UNO_QUERY);
     if (!xPropertySet.is())
         return;
 
-    comphelper::SequenceAsHashMap 
aMap(xPropertySet->getPropertyValue("Theme"));
-    if (aMap.empty())
-    {
+    uno::Reference<util::XTheme> xTheme;
+    xPropertySet->getPropertyValue("Theme") >>= xTheme;
+    if (!xTheme.is())
         return;
-    }
 
-    if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0)
-    {
-        // Do not export in standard ODF 1.3 or older.
+    auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+    if (!pUnoTheme)
         return;
-    }
 
-    auto it = aMap.find("Name");
-    if (it != aMap.end())
-    {
-        OUString aName;
-        it->second >>= aName;
-        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, aName);
-    }
-    SvXMLElementExport aTheme(*this, XML_NAMESPACE_LO_EXT, XML_THEME, true, 
true);
+    auto const& rTheme = pUnoTheme->getTheme();
 
-    uno::Sequence<util::Color> aColors;
-    it = aMap.find("ColorScheme");
-    if (it != aMap.end())
-    {
-        it->second >>= aColors;
-    }
-    if (!aColors.hasElements())
-    {
-        return;
-    }
+    if (!rTheme.GetName().isEmpty())
+        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, rTheme.GetName());
+    SvXMLElementExport aTheme(*this, XML_NAMESPACE_LO_EXT, XML_THEME, true, 
true);
 
-    it = aMap.find("ColorSchemeName");
-    if (it != aMap.end())
-    {
-        OUString aName;
-        it->second >>= aName;
-        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, aName);
-    }
+    auto* pColorSet = rTheme.GetColorSet();
+    if (!pColorSet->getName().isEmpty())
+        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pColorSet->getName());
     SvXMLElementExport aColorTable(*this, XML_NAMESPACE_LO_EXT, 
XML_COLOR_TABLE, true, true);
 
-    static const XMLTokenEnum aColorTokens[] = {
-        XML_DK1, // Background 1
-        XML_LT1, // Text 1
-        XML_DK2, // Background 2
-        XML_LT2, // Text 2
+    static const XMLTokenEnum aColorTokens[] =
+    {
+        XML_DK1, // Text 1
+        XML_LT1, // Background 1
+        XML_DK2, // Text 2
+        XML_LT2, // Background 2
         XML_ACCENT1,
         XML_ACCENT2,
         XML_ACCENT3,
@@ -2426,17 +2412,17 @@ void SdXMLExport::ExportThemeElement(const 
uno::Reference<drawing::XDrawPage>& x
         XML_HLINK, // Hyperlink
         XML_FOLHLINK, // Followed hyperlink
     };
-    for (size_t nColor = 0; nColor < aColors.size(); ++nColor)
+
+    for (auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
     {
-        // Import goes via model::Theme::FromAny(), which sanitizes user input.
-        assert(nColor < SAL_N_ELEMENTS(aColorTokens));
+        if (eThemeColorType == model::ThemeColorType::Unknown)
+            continue;
 
+        auto nColor = size_t(eThemeColorType);
         AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, 
GetXMLToken(aColorTokens[nColor]));
-
         OUStringBuffer sValue;
-        sax::Converter::convertColor(sValue, aColors[nColor]);
+        sax::Converter::convertColor(sValue, 
pColorSet->getColor(eThemeColorType));
         AddAttribute(XML_NAMESPACE_LO_EXT, XML_COLOR, 
sValue.makeStringAndClear());
-
         SvXMLElementExport aColor(*this, XML_NAMESPACE_LO_EXT, XML_COLOR, 
true, true);
     }
 }
diff --git a/xmloff/source/style/XMLThemeContext.cxx 
b/xmloff/source/style/XMLThemeContext.cxx
index 41602665a06b..8a9a5cdbc558 100644
--- a/xmloff/source/style/XMLThemeContext.cxx
+++ b/xmloff/source/style/XMLThemeContext.cxx
@@ -25,6 +25,8 @@
 #include <sax/tools/converter.hxx>
 #include <comphelper/sequence.hxx>
 
+#include <docmodel/uno/UnoTheme.hxx>
+
 using namespace css;
 using namespace xmloff::token;
 
@@ -40,7 +42,8 @@ XMLThemeContext::XMLThemeContext(SvXMLImport& rImport,
         {
             case XML_ELEMENT(LO_EXT, XML_NAME):
             {
-                m_aTheme["Name"] <<= rAttribute.toString();
+                OUString aName = rAttribute.toString();
+                maTheme.SetName(aName);
                 break;
             }
         }
@@ -49,9 +52,9 @@ XMLThemeContext::XMLThemeContext(SvXMLImport& rImport,
 
 XMLThemeContext::~XMLThemeContext()
 {
-    uno::Any aTheme(m_aTheme.getAsConstPropertyValueList());
     uno::Reference<beans::XPropertySet> xPropertySet(m_xPage, uno::UNO_QUERY);
-    xPropertySet->setPropertyValue("Theme", aTheme);
+    uno::Reference<util::XTheme> xTheme(new UnoTheme(maTheme));
+    xPropertySet->setPropertyValue("Theme", uno::Any(xTheme));
 }
 
 uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLThemeContext::createFastChildContext(
@@ -59,7 +62,7 @@ uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLThemeContext::createFa
 {
     if (nElement == XML_ELEMENT(LO_EXT, XML_COLOR_TABLE))
     {
-        return new XMLColorTableContext(GetImport(), xAttribs, m_aTheme);
+        return new XMLColorTableContext(GetImport(), xAttribs, maTheme);
     }
 
     return nullptr;
@@ -67,9 +70,9 @@ uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLThemeContext::createFa
 
 XMLColorTableContext::XMLColorTableContext(
     SvXMLImport& rImport, const uno::Reference<xml::sax::XFastAttributeList>& 
xAttrList,
-    comphelper::SequenceAsHashMap& rTheme)
+    model::Theme& rTheme)
     : SvXMLImportContext(rImport)
-    , m_rTheme(rTheme)
+    , mrTheme(rTheme)
 {
     for (const auto& rAttribute : 
sax_fastparser::castToFastAttributeList(xAttrList))
     {
@@ -77,7 +80,8 @@ XMLColorTableContext::XMLColorTableContext(
         {
             case XML_ELEMENT(LO_EXT, XML_NAME):
             {
-                m_rTheme["ColorSchemeName"] <<= rAttribute.toString();
+                OUString aName = rAttribute.toString();
+                mpColorSet.reset(new model::ColorSet(aName));
                 break;
             }
         }
@@ -86,7 +90,8 @@ XMLColorTableContext::XMLColorTableContext(
 
 XMLColorTableContext::~XMLColorTableContext()
 {
-    m_rTheme["ColorScheme"] <<= 
comphelper::containerToSequence(m_aColorScheme);
+    if (mpColorSet)
+        mrTheme.SetColorSet(std::move(mpColorSet));
 }
 
 uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLColorTableContext::createFastChildContext(
@@ -94,7 +99,8 @@ uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLColorTableContext::cre
 {
     if (nElement == XML_ELEMENT(LO_EXT, XML_COLOR))
     {
-        return new XMLColorContext(GetImport(), xAttribs, m_aColorScheme);
+        if (mpColorSet)
+            return new XMLColorContext(GetImport(), xAttribs, mpColorSet);
     }
 
     return nullptr;
@@ -102,22 +108,62 @@ uno::Reference<xml::sax::XFastContextHandler> SAL_CALL 
XMLColorTableContext::cre
 
 XMLColorContext::XMLColorContext(SvXMLImport& rImport,
                                  const 
uno::Reference<xml::sax::XFastAttributeList>& xAttrList,
-                                 std::vector<util::Color>& rColorScheme)
+                                 std::unique_ptr<model::ColorSet>& rpColorSet)
     : SvXMLImportContext(rImport)
 {
+    OUString aName;
+    ::Color aColor;
+
     for (const auto& rAttribute : 
sax_fastparser::castToFastAttributeList(xAttrList))
     {
         switch (rAttribute.getToken())
         {
+            case XML_ELEMENT(LO_EXT, XML_NAME):
+            {
+                aName = rAttribute.toString();
+                break;
+            }
             case XML_ELEMENT(LO_EXT, XML_COLOR):
             {
-                util::Color nColor;
-                sax::Converter::convertColor(nColor, rAttribute.toView());
-                rColorScheme.push_back(nColor);
+                sax::Converter::convertColor(aColor, rAttribute.toView());
                 break;
             }
         }
     }
+
+    if (!aName.isEmpty())
+    {
+        auto eType = model::ThemeColorType::Unknown;
+        if (aName == u"dk1")
+            eType = model::ThemeColorType::Dark1;
+        else if (aName == u"lt1")
+            eType = model::ThemeColorType::Light1;
+        else if (aName == u"dk2")
+            eType = model::ThemeColorType::Dark2;
+        else if (aName == u"lt2")
+            eType = model::ThemeColorType::Light2;
+        else if (aName == u"accent1")
+            eType = model::ThemeColorType::Accent1;
+        else if (aName == u"accent2")
+            eType = model::ThemeColorType::Accent2;
+        else if (aName == u"accent3")
+            eType = model::ThemeColorType::Accent3;
+        else if (aName == u"accent4")
+            eType = model::ThemeColorType::Accent4;
+        else if (aName == u"accent5")
+            eType = model::ThemeColorType::Accent5;
+        else if (aName == u"accent6")
+            eType = model::ThemeColorType::Accent6;
+        else if (aName == u"hlink")
+            eType = model::ThemeColorType::Hyperlink;
+        else if (aName == u"folHlink")
+            eType = model::ThemeColorType::FollowedHyperlink;
+
+        if (eType != model::ThemeColorType::Unknown)
+        {
+            rpColorSet->add(eType, aColor);
+        }
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to