support theme color for lines + oox support + tests

Extended XLineColor to handle model::ThemeColor which then maps
to the newly added LineColorThemeData property.

Extended oox import and export to map the scheme color elements
to and from ThemeColor. Added a new test to check the theme line
color in impress shapes.

Change-Id: I23ecc18c88b5b47608c9110f5681f189d02e2f36
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145071
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/include/editeng/unoprnms.hxx b/include/editeng/unoprnms.hxx
index 7f82cd0..300a0a2 100644
--- a/include/editeng/unoprnms.hxx
+++ b/include/editeng/unoprnms.hxx
@@ -77,6 +77,7 @@ inline constexpr OUStringLiteral UNO_NAME_LINESTYLE = u"LineStyle";
inline constexpr OUStringLiteral UNO_NAME_LINEDASH = u"LineDash";
inline constexpr OUStringLiteral UNO_NAME_LINEWIDTH = u"LineWidth";
inline constexpr OUStringLiteral UNO_NAME_LINECOLOR = u"LineColor";
inline constexpr OUStringLiteral UNO_NAME_LINECOLOR_THEME_REFERENCE = u"LineColorThemeReference";
inline constexpr OUStringLiteral UNO_NAME_LINEJOINT = u"LineJoint";
inline constexpr OUStringLiteral UNO_NAME_LINESTART = u"LineStart";
inline constexpr OUStringLiteral UNO_NAME_LINEEND = u"LineEnd";
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index eb0fea2..c131632 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -235,7 +235,7 @@ public:
    void WriteConnectorConnections( sal_Int32 nStartGlueId, sal_Int32 nEndGlueId, sal_Int32 nStartID, sal_Int32 nEndID );

    bool WriteCharColor(const css::uno::Reference<css::beans::XPropertySet>& xPropertySet);
    bool WriteFillColor(const css::uno::Reference<css::beans::XPropertySet>& xPropertySet);
    bool WriteSchemeColor(OUString const& rPropertyName, const css::uno::Reference<css::beans::XPropertySet>& xPropertySet);

    void WriteSolidFill( ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT );
    void WriteSolidFill( const OUString& sSchemeName, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx
index 8af8142..70be330 100644
--- a/include/svx/unoshprp.hxx
+++ b/include/svx/unoshprp.hxx
@@ -236,6 +236,7 @@
#define LINE_PROPERTIES_DEFAULTS\
    { UNO_NAME_LINECAP,           XATTR_LINECAP,          ::cppu::UnoType<css::drawing::LineCap>::get(),     0,     0}, \
    { UNO_NAME_LINECOLOR,         XATTR_LINECOLOR,        ::cppu::UnoType<sal_Int32>::get() ,           0,     0}, \
    { UNO_NAME_LINECOLOR_THEME_REFERENCE, XATTR_LINECOLOR, ::cppu::UnoType<css::uno::XInterface>::get() ,           0, MID_COLOR_THEME_REFERENCE}, \
    { UNO_NAME_LINEENDCENTER,     XATTR_LINEENDCENTER,    cppu::UnoType<bool>::get() ,           0,     0}, \
    { UNO_NAME_LINEENDWIDTH,      XATTR_LINEENDWIDTH,     ::cppu::UnoType<sal_Int32>::get() ,           0,     0, PropertyMoreFlags::METRIC_ITEM}, \
    { UNO_NAME_LINEJOINT,         XATTR_LINEJOINT,        ::cppu::UnoType<css::drawing::LineJoint>::get(),     0,     0}, \
diff --git a/oox/inc/drawingml/lineproperties.hxx b/oox/inc/drawingml/lineproperties.hxx
index f2d37a7..52c2782 100644
--- a/oox/inc/drawingml/lineproperties.hxx
+++ b/oox/inc/drawingml/lineproperties.hxx
@@ -69,7 +69,8 @@ struct LineProperties
    void                pushToPropMap(
                            ShapePropertyMap& rPropMap,
                            const GraphicHelper& rGraphicHelper,
                            ::Color nPhClr = API_RGB_TRANSPARENT ) const;
                            ::Color nPhClr = API_RGB_TRANSPARENT,
                            sal_Int16 nPhClrTheme = -1) const;

    /** Calculates the line style attribute from the internal state of the object */
    css::drawing::LineStyle  getLineStyle() const;
diff --git a/oox/qa/unit/data/ThemeShapesReference.pptx b/oox/qa/unit/data/ThemeShapesReference.pptx
new file mode 100644
index 0000000..d871cc5
--- /dev/null
+++ b/oox/qa/unit/data/ThemeShapesReference.pptx
Binary files differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index f47853e..5c09ca3 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -439,7 +439,7 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf132557_footerCustomShapes)
                         xShapeSlideNum->getShapeType());
}

CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testThemeTint)
CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testThemeColorTint_Table)
{
    // Given a document with a table style, using theme color with tinting in the A2 cell:
    loadFromURL(u"theme-tint.pptx");
@@ -483,6 +483,75 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testThemeTint)
    }
}

CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testThemeColor_Shape)
{
    // Given a document with a table style, using theme color with tinting in the A2 cell:
    loadFromURL(u"ThemeShapesReference.pptx");

    // Then make sure that we only import theming info to the doc model if the effects are limited
    // to lum mod / off that we can handle (i.e. no tint/shade):
    uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
                                                 uno::UNO_QUERY);

    // check line and fill theme color of shape1
    {
        model::ThemeColor aThemeColor;
        uno::Reference<util::XThemeColor> xThemeColor;
        uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);

        CPPUNIT_ASSERT(xShape->getPropertyValue("FillColorThemeReference") >>= xThemeColor);
        CPPUNIT_ASSERT(xThemeColor.is());
        model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
        CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent6, aThemeColor.getType());
        {
            auto const& rTrans = aThemeColor.getTransformations();
            CPPUNIT_ASSERT_EQUAL(size_t(2), rTrans.size());
            CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans[0].meType);
            CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTrans[0].mnValue);
            CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, rTrans[1].meType);
            CPPUNIT_ASSERT_EQUAL(sal_Int16(6000), rTrans[1].mnValue);
        }

        CPPUNIT_ASSERT(xShape->getPropertyValue("LineColorThemeReference") >>= xThemeColor);
        CPPUNIT_ASSERT(xThemeColor.is());
        model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
        CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent6, aThemeColor.getType());
        {
            auto const& rTrans = aThemeColor.getTransformations();
            CPPUNIT_ASSERT_EQUAL(size_t(1), rTrans.size());
            CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans[0].meType);
            CPPUNIT_ASSERT_EQUAL(sal_Int16(5000), rTrans[0].mnValue);
        }
    }
    // check line and fill theme color of shape2
    {
        model::ThemeColor aThemeColor;
        uno::Reference<util::XThemeColor> xThemeColor;
        uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);

        CPPUNIT_ASSERT(xShape->getPropertyValue("FillColorThemeReference") >>= xThemeColor);
        CPPUNIT_ASSERT(xThemeColor.is());
        model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
        CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aThemeColor.getType());
        {
            auto const& rTrans = aThemeColor.getTransformations();
            CPPUNIT_ASSERT_EQUAL(size_t(0), rTrans.size());
        }

        CPPUNIT_ASSERT(xShape->getPropertyValue("LineColorThemeReference") >>= xThemeColor);
        CPPUNIT_ASSERT(xThemeColor.is());
        model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
        CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aThemeColor.getType());
        {
            auto const& rTrans = aThemeColor.getTransformations();
            CPPUNIT_ASSERT_EQUAL(size_t(1), rTrans.size());
            CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans[0].meType);
            CPPUNIT_ASSERT_EQUAL(sal_Int16(7500), rTrans[0].mnValue);
        }
    }
}

CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testVert270AndTextRot)
{
    // tdf##149551. The document contains a shape with attributes 'rot="720000"' and 'vert="vert270"'
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx
index e1cef77..8e9d676 100644
--- a/oox/source/drawingml/lineproperties.cxx
+++ b/oox/source/drawingml/lineproperties.cxx
@@ -33,6 +33,9 @@
#include <oox/drawingml/shapepropertymap.hxx>
#include <oox/helper/graphichelper.hxx>
#include <oox/token/tokens.hxx>
#include <oox/token/properties.hxx>
#include <docmodel/uno/UnoThemeColor.hxx>


using namespace ::com::sun::star;
using namespace ::com::sun::star::beans;
@@ -430,7 +433,7 @@ void LineProperties::assignUsed( const LineProperties& rSourceProps )
}

void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap,
        const GraphicHelper& rGraphicHelper, ::Color nPhClr ) const
        const GraphicHelper& rGraphicHelper, ::Color nPhClr, sal_Int16 nPhClrTheme) const
{
    // line fill type must exist, otherwise ignore other properties
    if( !maLineFill.moFillType.has_value() )
@@ -491,11 +494,36 @@ void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap,

    // line color and transparence
    Color aLineColor = maLineFill.getBestSolidColor();
    if( aLineColor.isUsed() )
    if (aLineColor.isUsed())
    {
        rPropMap.setProperty( ShapeProperty::LineColor, aLineColor.getColor( rGraphicHelper, nPhClr ) );
        ::Color aColor = aLineColor.getColor(rGraphicHelper, nPhClr);
        rPropMap.setProperty(ShapeProperty::LineColor, aColor);
        if( aLineColor.hasTransparency() )
            rPropMap.setProperty( ShapeProperty::LineTransparency, aLineColor.getTransparency() );

        model::ThemeColor aThemeColor;

        if (aColor == nPhClr)
        {
            aThemeColor.setType(model::convertToThemeColorType(nPhClrTheme));
            rPropMap.setProperty(PROP_LineColorThemeReference, model::theme::createXThemeColor(aThemeColor));
        }
        else
        {
            aThemeColor.setType(model::convertToThemeColorType(aLineColor.getSchemeColorIndex()));
            if (aLineColor.getLumMod() != 10000)
                aThemeColor.addTransformation({model::TransformationType::LumMod, aLineColor.getLumMod()});
            if (aLineColor.getLumOff() != 0)
                aThemeColor.addTransformation({model::TransformationType::LumOff, aLineColor.getLumOff()});
            if (aLineColor.getTintOrShade() > 0)
                aThemeColor.addTransformation({model::TransformationType::Tint, aLineColor.getTintOrShade()});
            if (aLineColor.getTintOrShade() < 0)
            {
                sal_Int16 nShade = o3tl::narrowing<sal_Int16>(-aLineColor.getTintOrShade());
                aThemeColor.addTransformation({model::TransformationType::Shade, nShade});
            }
            rPropMap.setProperty(PROP_LineColorThemeReference, model::theme::createXThemeColor(aThemeColor));
        }
    }

    // line markers
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index c7d4567..b316238 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1167,6 +1167,7 @@ Reference< XShape > const & Shape::createAndInsert(
        ::Color nLinePhClr(ColorTransparency, 0xffffffff);
        ::Color nFillPhClr(ColorTransparency, 0xffffffff);
        sal_Int16 nFillPhClrTheme = -1;
        sal_Int16 nLinePhClrTheme = -1;
        // TODO: use ph color when applying effect properties
        //sal_Int32 nEffectPhClr = -1;

@@ -1183,6 +1184,7 @@ Reference< XShape > const & Shape::createAndInsert(
                if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
                    aLineProperties.assignUsed( *pLineProps );
                nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
                nLinePhClrTheme = pLineRef->maPhClr.getSchemeColorIndex();

                // Store style-related properties to InteropGrabBag to be able to export them back
                uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
@@ -1275,7 +1277,7 @@ Reference< XShape > const & Shape::createAndInsert(
        if(!bIsCroppedGraphic)
            aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, nFillPhClrTheme, mbFlipH, mbFlipV, bIsCustomShape );
        LineProperties aLineProperties = getActualLineProperties(pTheme);
        aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr );
        aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr, nLinePhClrTheme);
        EffectProperties aEffectProperties = getActualEffectProperties(pTheme);
        // TODO: use ph color when applying effect properties
        aEffectProperties.pushToPropMap( aShapeProps, rGraphicHelper );
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index dde41bd..751aabc 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -432,49 +432,6 @@ void DrawingML::WriteColorTransformations( const Sequence< PropertyValue >& aTra
    }
}

bool DrawingML::WriteCharColor(const css::uno::Reference<css::beans::XPropertySet>& xPropertySet)
{
    if (!xPropertySet->getPropertySetInfo()->hasPropertyByName("CharColorThemeReference"))
        return false;

    uno::Reference<util::XThemeColor> xThemeColor;
    xPropertySet->getPropertyValue("CharColorThemeReference") >>= xThemeColor;
    if (!xThemeColor.is())
        return false;

    model::ThemeColor aThemeColor;
    model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
    if (aThemeColor.getType() == model::ThemeColorType::Unknown)
        return false;
    const char* pColorName = g_aPredefinedClrNames[sal_Int16(aThemeColor.getType())];
    mpFS->startElementNS(XML_a, XML_solidFill);
    mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, pColorName);
    for (auto const& rTransform : aThemeColor.getTransformations())
    {
        switch (rTransform.meType)
        {
            case model::TransformationType::LumMod:
                mpFS->singleElementNS(XML_a, XML_lumMod, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            case model::TransformationType::LumOff:
                mpFS->singleElementNS(XML_a, XML_lumOff, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            case model::TransformationType::Tint:
                mpFS->singleElementNS(XML_a, XML_tint, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            case model::TransformationType::Shade:
                mpFS->singleElementNS(XML_a, XML_shade, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            default:
                break;
        }
    }
    mpFS->endElementNS(XML_a, XML_schemeClr);
    mpFS->endElementNS(XML_a, XML_solidFill);

    return true;
}

void DrawingML::WriteSolidFill( ::Color nColor, sal_Int32 nAlpha )
{
    mpFS->startElementNS(XML_a, XML_solidFill);
@@ -567,7 +524,7 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet )
    else if ( nFillColor != nOriginalColor )
    {
        // the user has set a different color for the shape
        if (!WriteFillColor(rXPropSet))
        if (!WriteSchemeColor(u"FillColorThemeReference", rXPropSet))
        {
            WriteSolidFill(::Color(ColorTransparency, nFillColor & 0xffffff), nAlpha);
        }
@@ -585,13 +542,13 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet )
    }
}

bool DrawingML::WriteFillColor(const uno::Reference<beans::XPropertySet>& xPropertySet)
bool DrawingML::WriteSchemeColor(OUString const& rPropertyName, const uno::Reference<beans::XPropertySet>& xPropertySet)
{
    if (!xPropertySet->getPropertySetInfo()->hasPropertyByName("FillColorThemeReference"))
    if (!xPropertySet->getPropertySetInfo()->hasPropertyByName(rPropertyName))
        return false;

    uno::Reference<util::XThemeColor> xThemeColor;
    xPropertySet->getPropertyValue("FillColorThemeReference") >>= xThemeColor;
    xPropertySet->getPropertyValue(rPropertyName) >>= xThemeColor;
    if (!xThemeColor.is())
        return false;

@@ -612,6 +569,12 @@ bool DrawingML::WriteFillColor(const uno::Reference<beans::XPropertySet>& xPrope
            case model::TransformationType::LumOff:
                mpFS->singleElementNS(XML_a, XML_lumOff, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            case model::TransformationType::Tint:
                mpFS->singleElementNS(XML_a, XML_tint, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            case model::TransformationType::Shade:
                mpFS->singleElementNS(XML_a, XML_shade, XML_val, OString::number(rTransform.mnValue * 10));
                break;
            default:
                break;
        }
@@ -1072,7 +1035,8 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc
        if( nColor != nOriginalColor )
        {
            // the user has set a different color for the line
            WriteSolidFill( nColor, nColorAlpha );
            if (!WriteSchemeColor(u"LineColorThemeReference", rXPropSet))
                    WriteSolidFill(nColor, nColorAlpha);
        }
        else if( !sColorFillScheme.isEmpty() )
        {
@@ -2396,7 +2360,7 @@ void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool 
                else
                {
                    color.SetAlpha(255);
                    if (!WriteCharColor(rXPropSet))
                    if (!WriteSchemeColor(u"CharColorThemeReference", rXPropSet))
                        WriteSolidFill(color, nTransparency);
                }
                mpFS->endElementNS(XML_a, XML_ln);
@@ -2409,7 +2373,7 @@ void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool 
            {
                color.SetAlpha(255);
                // TODO: special handle embossed/engraved
                if (!WriteCharColor(rXPropSet))
                if (!WriteSchemeColor(u"CharColorThemeReference", rXPropSet))
                {
                    WriteSolidFill(color, nTransparency);
                }
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index 439ecc9..43bed81 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -316,6 +316,7 @@ LeftPageHeaderContent
LegacyFragment
LineCap
LineColor
LineColorThemeReference
LineCount
LineDash
LineDashName
diff --git a/sd/source/core/stlsheet.cxx b/sd/source/core/stlsheet.cxx
index 95751693..96850f5 100644
--- a/sd/source/core/stlsheet.cxx
+++ b/sd/source/core/stlsheet.cxx
@@ -40,6 +40,7 @@

#include <svx/xflbmtit.hxx>
#include <svx/xflbstit.hxx>
#include <svx/xlnclit.hxx>
#include <editeng/bulletitem.hxx>
#include <editeng/lrspitem.hxx>
#include <svx/unoshprp.hxx>
@@ -1400,6 +1401,15 @@ PropertyState SAL_CALL SdStyleSheet::getPropertyState( const OUString& PropertyN
                    }
                }
                break;
            case XATTR_LINECOLOR:
                if (pEntry->nMemberId == MID_COLOR_THEME_REFERENCE)
                {
                    auto const* pColor = rStyleSet.GetItem<XLineColorItem>(pEntry->nWID);
                    if (pColor->GetThemeColor().getType() == model::ThemeColorType::Unknown)
                    {
                        eState = PropertyState_DEFAULT_VALUE;
                    }
                }
                break;
            }
        }
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
index b8ca46c..c39ac6a 100644
--- a/svx/source/table/cell.cxx
+++ b/svx/source/table/cell.cxx
@@ -56,6 +56,7 @@
#include <editeng/charrotateitem.hxx>
#include <svx/xflbstit.hxx>
#include <svx/xflbmtit.hxx>
#include <svx/xlnclit.hxx>
#include <svx/svdpool.hxx>
#include <svx/xflclit.hxx>
#include <comphelper/diagnose_ex.hxx>
@@ -1450,7 +1451,6 @@ PropertyState SAL_CALL Cell::getPropertyState( const OUString& PropertyName )
                    }
                    break;
                case XATTR_FILLCOLOR:

                    if (pMap->nMemberId == MID_COLOR_THEME_INDEX)
                    {
                        const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
@@ -1496,6 +1496,16 @@ PropertyState SAL_CALL Cell::getPropertyState( const OUString& PropertyName )
                        }
                    }
                    break;
                case XATTR_LINECOLOR:
                    if (pMap->nMemberId == MID_COLOR_THEME_REFERENCE)
                    {
                        auto const* pColor = rSet.GetItem<XLineColorItem>(pMap->nWID);
                        if (pColor->GetThemeColor().getType() == model::ThemeColorType::Unknown)
                        {
                            eState = PropertyState_DEFAULT_VALUE;
                        }
                    }
                    break;
                }
            }
        }
diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx
index 794df51..d5859fa 100644
--- a/svx/source/unodraw/unoshape.cxx
+++ b/svx/source/unodraw/unoshape.cxx
@@ -43,6 +43,7 @@
#include <svx/xflbmtit.hxx>
#include <svx/xlnstit.hxx>
#include <svx/xlnedit.hxx>
#include <svx/xlnclit.hxx>
#include <svx/svdmodel.hxx>
#include <svx/svdobjkind.hxx>
#include <svx/unopage.hxx>
@@ -1999,6 +2000,15 @@ beans::PropertyState SvxShape::_getPropertyState( const OUString& PropertyName )
                    }
                }
                break;
            case XATTR_LINECOLOR:
                if (pMap->nMemberId == MID_COLOR_THEME_REFERENCE)
                {
                    auto const* pColor = rSet.GetItem<XLineColorItem>(pMap->nWID);
                    if (pColor->GetThemeColor().getType() == model::ThemeColorType::Unknown)
                    {
                        eState = beans::PropertyState_DEFAULT_VALUE;
                    }
                }
                break;
            }
        }
diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx
index 4f402d0..f0d17db 100644
--- a/svx/source/xoutdev/xattr.cxx
+++ b/svx/source/xoutdev/xattr.cxx
@@ -991,19 +991,49 @@ bool XLineColorItem::GetPresentation
    return true;
}

bool XLineColorItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/) const
bool XLineColorItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId) const
{
    rVal <<= GetColorValue().GetRGBColor();
    nMemberId &= ~CONVERT_TWIPS;
    switch (nMemberId)
    {
        case MID_COLOR_THEME_REFERENCE:
        {
            auto xThemeColor = model::theme::createXThemeColor(GetThemeColor());
            rVal <<= xThemeColor;
            break;
        }
        default:
        {
            rVal <<= GetColorValue().GetRGBColor();
            break;
        }
    }
    return true;
}

bool XLineColorItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/)
bool XLineColorItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId)
{
    sal_Int32 nValue = 0;
    if(!(rVal >>= nValue))
        return false;
    nMemberId &= ~CONVERT_TWIPS;
    switch(nMemberId)
    {
        case MID_COLOR_THEME_REFERENCE:
        {
            css::uno::Reference<css::util::XThemeColor> xThemeColor;
            if (!(rVal >>= xThemeColor))
                return false;
            model::theme::setFromXThemeColor(GetThemeColor(), xThemeColor);
        }
        break;
        default:
        {
            sal_Int32 nValue;
            if(!(rVal >>= nValue ))
                return false;

    SetColorValue( Color(ColorTransparency, nValue) );
            SetColorValue( Color(ColorTransparency, nValue) );
            break;
        }
    }
    return true;
}