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 
 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/formatflysplit.hxx               |    5 --
 sw/source/core/attr/formatflysplit.cxx  |    9 +++
 sw/source/core/layout/fly.cxx           |   16 ++++++
 xmloff/inc/XMLThemeContext.hxx          |   13 ++---
 xmloff/qa/unit/draw.cxx                 |   52 ++++++++++++++-------
 xmloff/source/draw/sdxmlexp.cxx         |   78 +++++++++++++-------------------
 xmloff/source/style/XMLThemeContext.cxx |   72 ++++++++++++++++++++++++-----
 18 files changed, 253 insertions(+), 122 deletions(-)

New commits:
commit 75c0d7827625c683d52a9e2f3a7c514df890107b
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Jan 27 15:03:09 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Jan 31 08:59:09 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>

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 e311087673ab..4eb16f50713b 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>
@@ -1195,14 +1196,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 9b9ed18dbfc6..b5c9e64a61bc 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 2dfff467ceb7..5292349b4ba8 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[] =
@@ -974,6 +978,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);
@@ -1296,6 +1313,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: */
commit ed9d987e2ad8f6af554a5fc1f858ca48c6970446
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jan 31 08:29:44 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Jan 31 08:58:54 2023 +0000

    sw: if the fly is to be split, then limit its growth in SwFlyFrame::Format()
    
    It seems the first direct cause why flys are not split is because flys
    can grow forever, so an inner paragraph's SwContentFrame::MakeAll() will
    never hit the nBottomDist < 0 condition, which is necessary to call into
    SwFlowFrame::MoveFwd().
    
    With this, at least nBottomDist is negative when a fly with two
    paragraphs is at the bottom of a page and only one of them fits the body
    frame.
    
    Also add a debug environment variable, so I can debug the "fly split"
    case till we don't have import/export filters for this.
    
    Towards an initial layout for multi-page fly frames.
    
    Change-Id: I43114b5795dd42e518a1d776ccd2e7ab607ad859
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146376
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/formatflysplit.hxx b/sw/inc/formatflysplit.hxx
index a7cbb82847bb..5f7dda675ed2 100644
--- a/sw/inc/formatflysplit.hxx
+++ b/sw/inc/formatflysplit.hxx
@@ -29,10 +29,7 @@
 class SW_DLLPUBLIC SwFormatFlySplit final : public SfxBoolItem
 {
 public:
-    SwFormatFlySplit(bool bSplit = false)
-        : SfxBoolItem(RES_FLY_SPLIT, bSplit)
-    {
-    }
+    SwFormatFlySplit(bool bSplit = false);
 
     SwFormatFlySplit* Clone(SfxItemPool* pPool = nullptr) const override;
 
diff --git a/sw/source/core/attr/formatflysplit.cxx 
b/sw/source/core/attr/formatflysplit.cxx
index 72816b2ead4e..bcbfcc2d5e96 100644
--- a/sw/source/core/attr/formatflysplit.cxx
+++ b/sw/source/core/attr/formatflysplit.cxx
@@ -21,6 +21,15 @@
 
 #include <libxml/xmlwriter.h>
 
+SwFormatFlySplit::SwFormatFlySplit(bool bSplit)
+    : SfxBoolItem(RES_FLY_SPLIT, bSplit)
+{
+    if (getenv("SW_FORCE_FLY_SPLIT"))
+    {
+        SetValue(true);
+    }
+}
+
 SwFormatFlySplit* SwFormatFlySplit::Clone(SfxItemPool*) const
 {
     return new SwFormatFlySplit(*this);
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 4cee6d9e712d..1ece49fb78b5 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -75,6 +75,7 @@
 #include <bodyfrm.hxx>
 #include <FrameControlsManager.hxx>
 #include <ndtxt.hxx>
+#include <formatflysplit.hxx>
 
 using namespace ::com::sun::star;
 
@@ -1303,6 +1304,21 @@ void SwFlyFrame::Format( vcl::RenderContext* 
/*pRenderContext*/, const SwBorderA
             if ( nRemaining < MINFLY )
                 nRemaining = MINFLY;
 
+            const SwFrame* pAnchor = GetAnchorFrame();
+            const SwFrame* pAnchorUpper = pAnchor ? pAnchor->GetUpper() : 
nullptr;
+            if (pAnchorUpper && GetFormat()->GetFlySplit().GetValue())
+            {
+                // If the fly is allowed to be split, then limit its size to 
the upper of the
+                // anchor.
+                SwTwips nDeadline = aRectFnSet.GetPrtBottom(*pAnchorUpper);
+                SwTwips nTop = aRectFnSet.GetTop(getFrameArea());
+                SwTwips nBottom = aRectFnSet.GetTop(getFrameArea()) + 
nRemaining;
+                if (nBottom > nDeadline)
+                {
+                    nRemaining = nDeadline - nTop;
+                }
+            }
+
             {
                 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
                 aRectFnSet.SetHeight( aPrt, nRemaining );

Reply via email to