offapi/com/sun/star/text/BaseFrameProperties.idl            |   10 +
 oox/source/token/namespaces-strict.txt                      |    2 
 oox/source/token/namespaces.txt                             |    2 
 oox/source/token/tokens.txt                                 |    1 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |   10 +
 sw/inc/hintids.hxx                                          |   32 +--
 sw/qa/extras/globalfilter/data/tdf143311-1.docx             |binary
 sw/qa/extras/globalfilter/globalfilter.cxx                  |  101 ++++++++++++
 sw/source/core/bastyp/init.cxx                              |    4 
 sw/source/core/text/EnhancedPDFExportHelper.cxx             |    3 
 sw/source/core/unocore/unoframe.cxx                         |    9 +
 sw/source/core/unocore/unomapproperties.hxx                 |    1 
 sw/source/filter/ww8/docxattributeoutput.cxx                |   15 +
 sw/source/ui/frmdlg/frmpage.cxx                             |   10 +
 sw/source/uibase/inc/frmpage.hxx                            |    1 
 sw/uiconfig/swriter/ui/frmaddpage.ui                        |   20 ++
 writerfilter/source/dmapper/DomainMapper.cxx                |    3 
 writerfilter/source/dmapper/GraphicImport.cxx               |    6 
 writerfilter/source/dmapper/PropertyIds.cxx                 |    1 
 writerfilter/source/dmapper/PropertyIds.hxx                 |    1 
 writerfilter/source/ooxml/model.xml                         |   32 +++
 xmloff/source/text/XMLTextFrameContext.cxx                  |   10 +
 xmloff/source/text/txtparae.cxx                             |    6 
 23 files changed, 258 insertions(+), 22 deletions(-)

New commits:
commit 31084ebb59093be7dfe5ab53a20fdb3bcfde34b6
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Thu Dec 8 10:54:18 2022 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Dec 9 16:03:20 2022 +0000

    tdf#143311 offapi,oox,writerfilter,xmloff,sw: decorative flag on flys
    
    * sw core RES_DECORATIVE as a FRMATR
    * sw API SwXFrame property "Decorative"
    * UI checkbox "Decorative"
    * ODF import/export as loext:decorative on draw:frame
    * DOCX export
    * DOCX import - very non-obvious how to get it from model.xml to dmapper
    * PDF/UA export: tag flys with this flag as Artifact
    * test for DOCX filters, ODF filters, PDF export
    
    Change-Id: I1ceb67fdd4e1cfa212aafdeb1c5f4ccd873d433e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143815
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/offapi/com/sun/star/text/BaseFrameProperties.idl 
b/offapi/com/sun/star/text/BaseFrameProperties.idl
index 72bec7ffe63c..3108067a0ad5 100644
--- a/offapi/com/sun/star/text/BaseFrameProperties.idl
+++ b/offapi/com/sun/star/text/BaseFrameProperties.idl
@@ -363,6 +363,16 @@ published service BaseFrameProperties
         @since LibreOffice 7.4
     */
     [optional, property] string Tooltip;
+
+    /** Determines if the frame is purely decorative.
+
+        If `TRUE`, it is considered not part of the document content,
+        and may be ignored by assistive technologies.
+
+        @since LibreOffice 7.5
+    */
+    [optional, property] boolean Decorative;
+
 };
 
 
diff --git a/oox/source/token/namespaces-strict.txt 
b/oox/source/token/namespaces-strict.txt
index 7449dca99a33..59631432eb2f 100644
--- a/oox/source/token/namespaces-strict.txt
+++ b/oox/source/token/namespaces-strict.txt
@@ -92,6 +92,8 @@ xr2                     
http://schemas.microsoft.com/office/spreadsheetml/2015/r
 
 # extlst namespaces
 
+adec                    
http://schemas.microsoft.com/office/drawing/2017/decorative
+
 # xls14Lst for features introduced by excel 2010
 xls14Lst               
http://schemas.microsoft.com/office/spreadsheetml/2009/9/main
 
diff --git a/oox/source/token/namespaces.txt b/oox/source/token/namespaces.txt
index 849caa547695..0790c65d8817 100644
--- a/oox/source/token/namespaces.txt
+++ b/oox/source/token/namespaces.txt
@@ -92,6 +92,8 @@ xr2                     
http://schemas.microsoft.com/office/spreadsheetml/2015/r
 
 # extlst namespaces
 
+adec                    
http://schemas.microsoft.com/office/drawing/2017/decorative
+
 # xls14Lst for features introduced by excel 2010
 xls14Lst               
http://schemas.microsoft.com/office/spreadsheetml/2009/9/main
 
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
index d1a40140add9..8ed5687983b6 100644
--- a/oox/source/token/tokens.txt
+++ b/oox/source/token/tokens.txt
@@ -480,6 +480,7 @@ additive
 addlxml
 addressBook
 addressFieldName
+adec
 adj
 adjLst
 adjust
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index 3b2e0d4b2bbc..ee9b89ded8a9 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -3304,4 +3304,14 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
       <rng:value>folHlink</rng:value>
     </rng:choice>
   </rng:define>
+
+  <!-- TODO no proposal -->
+  <rng:define name="draw-frame-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:decorative">
+        <rng:ref name="boolean"/>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
 </rng:grammar>
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index 22dba273ec1b..e2392cf0007e 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -368,24 +368,24 @@ constexpr TypedWhichId<SfxGrabBagItem> 
RES_FRMATR_GRABBAG(129);
 constexpr TypedWhichId<SdrTextVertAdjustItem> RES_TEXT_VERT_ADJUST(130);
 constexpr TypedWhichId<SfxBoolItem> RES_BACKGROUND_FULL_SIZE(131);
 constexpr TypedWhichId<SfxBoolItem> RES_RTL_GUTTER(132);
-constexpr sal_uInt16 RES_FRMATR_END(133);
+constexpr TypedWhichId<SfxBoolItem> RES_DECORATIVE(133);
+constexpr sal_uInt16 RES_FRMATR_END(134);
 
 constexpr sal_uInt16 RES_GRFATR_BEGIN(RES_FRMATR_END);
-constexpr TypedWhichId<SwMirrorGrf> RES_GRFATR_MIRRORGRF(RES_GRFATR_BEGIN); // 
133
-constexpr TypedWhichId<SwCropGrf> RES_GRFATR_CROPGRF(134);
-
-constexpr TypedWhichId<SwRotationGrf> RES_GRFATR_ROTATION(135);
-constexpr TypedWhichId<SwLuminanceGrf> RES_GRFATR_LUMINANCE(136);
-constexpr TypedWhichId<SwContrastGrf> RES_GRFATR_CONTRAST(137);
-constexpr TypedWhichId<SwChannelRGrf> RES_GRFATR_CHANNELR(138);
-constexpr TypedWhichId<SwChannelGGrf> RES_GRFATR_CHANNELG(139);
-constexpr TypedWhichId<SwChannelBGrf> RES_GRFATR_CHANNELB(140);
-constexpr TypedWhichId<SwGammaGrf> RES_GRFATR_GAMMA(141);
-constexpr TypedWhichId<SwInvertGrf> RES_GRFATR_INVERT(142);
-constexpr TypedWhichId<SwTransparencyGrf> RES_GRFATR_TRANSPARENCY(143);
-constexpr TypedWhichId<SwDrawModeGrf> RES_GRFATR_DRAWMODE(144);
-
-constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY1(145);
+constexpr TypedWhichId<SwMirrorGrf> RES_GRFATR_MIRRORGRF(RES_GRFATR_BEGIN);
+constexpr TypedWhichId<SwCropGrf> RES_GRFATR_CROPGRF(135);
+
+constexpr TypedWhichId<SwRotationGrf> RES_GRFATR_ROTATION(136);
+constexpr TypedWhichId<SwLuminanceGrf> RES_GRFATR_LUMINANCE(137);
+constexpr TypedWhichId<SwContrastGrf> RES_GRFATR_CONTRAST(138);
+constexpr TypedWhichId<SwChannelRGrf> RES_GRFATR_CHANNELR(139);
+constexpr TypedWhichId<SwChannelGGrf> RES_GRFATR_CHANNELG(140);
+constexpr TypedWhichId<SwChannelBGrf> RES_GRFATR_CHANNELB(141);
+constexpr TypedWhichId<SwGammaGrf> RES_GRFATR_GAMMA(142);
+constexpr TypedWhichId<SwInvertGrf> RES_GRFATR_INVERT(143);
+constexpr TypedWhichId<SwTransparencyGrf> RES_GRFATR_TRANSPARENCY(144);
+constexpr TypedWhichId<SwDrawModeGrf> RES_GRFATR_DRAWMODE(145);
+
 constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY2(146);
 constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY3(147);
 constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY4(148);
diff --git a/sw/qa/extras/globalfilter/data/tdf143311-1.docx 
b/sw/qa/extras/globalfilter/data/tdf143311-1.docx
new file mode 100644
index 000000000000..b6b2d089812b
Binary files /dev/null and b/sw/qa/extras/globalfilter/data/tdf143311-1.docx 
differ
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx 
b/sw/qa/extras/globalfilter/globalfilter.cxx
index 188340354a88..7beb928dd344 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -15,7 +15,10 @@
 #include <com/sun/star/text/XText.hpp>
 #include <com/sun/star/text/XDocumentIndex.hpp>
 #include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
 #include <officecfg/Office/Common.hxx>
+#include <tools/zcodec.hxx>
+#include <vcl/filter/pdfdocument.hxx>
 #include <sfx2/linkmgr.hxx>
 #include <comphelper/propertysequence.hxx>
 #include <unotxdoc.hxx>
@@ -1227,6 +1230,104 @@ void Test::testBulletAsImage()
     }
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf143311)
+{
+    createSwDoc("tdf143311-1.docx");
+    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Decorative"));
+    // check DOCX filters
+    saveAndReload("Office Open XML Text");
+    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Decorative"));
+    // check ODF filters
+    saveAndReload("writer8");
+    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Decorative"));
+
+    // check PDF export
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+    // Enable PDF/UA
+    uno::Sequence<beans::PropertyValue> aFilterData(
+        comphelper::InitPropertySequence({ { "PDFUACompliance", uno::Any(true) 
} }));
+    aMediaDescriptor["FilterData"] <<= aFilterData;
+    css::uno::Reference<frame::XStorable> xStorable(mxComponent, 
css::uno::UNO_QUERY_THROW);
+    xStorable->storeToURL(maTempFile.GetURL(), 
aMediaDescriptor.getAsConstPropertyValueList());
+
+    vcl::filter::PDFDocument aDocument;
+    SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    // The document has one page.
+    std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    vcl::filter::PDFObjectElement* pContents = 
aPages[0]->LookupObject("Contents");
+    CPPUNIT_ASSERT(pContents);
+    vcl::filter::PDFStreamElement* pStream = pContents->GetStream();
+    CPPUNIT_ASSERT(pStream);
+    SvMemoryStream& rObjectStream = pStream->GetMemory();
+    // Uncompress it.
+    SvMemoryStream aUncompressed;
+    ZCodec aZCodec;
+    aZCodec.BeginCompression();
+    rObjectStream.Seek(0);
+    aZCodec.Decompress(rObjectStream, aUncompressed);
+    CPPUNIT_ASSERT(aZCodec.EndCompression());
+
+    auto pStart = static_cast<const char*>(aUncompressed.GetData());
+    const char* const pEnd = pStart + aUncompressed.GetSize();
+
+    enum
+    {
+        Default,
+        Artifact,
+        Tagged
+    } state
+        = Default;
+
+    auto nLine(0);
+    auto nTagged(0);
+    auto nArtifacts(0);
+    while (true)
+    {
+        ++nLine;
+        auto const pLine = ::std::find(pStart, pEnd, '\n');
+        if (pLine == pEnd)
+        {
+            break;
+        }
+        std::string_view const line(pStart, pLine - pStart);
+        pStart = pLine + 1;
+        if (!line.empty() && line[0] != '%')
+        {
+            ::std::cerr << nLine << ": " << line << "\n";
+            if (line == "/Artifact BMC")
+            {
+                CPPUNIT_ASSERT_EQUAL_MESSAGE("unexpected nesting", Default, 
state);
+                state = Artifact;
+                ++nArtifacts;
+            }
+            else if (o3tl::starts_with(line, "/Standard<</MCID") && 
o3tl::ends_with(line, ">>BDC"))
+            {
+                CPPUNIT_ASSERT_EQUAL_MESSAGE("unexpected nesting", Default, 
state);
+                state = Tagged;
+                ++nTagged;
+            }
+            else if (line == "EMC")
+            {
+                CPPUNIT_ASSERT_MESSAGE("unexpected end", state != Default);
+                state = Default;
+            }
+            else if (nLine > 1) // first line is expected "0.1 w"
+            {
+                CPPUNIT_ASSERT_MESSAGE("unexpected content outside MCS", state 
!= Default);
+            }
+        }
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("unclosed MCS", Default, state);
+    CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nTagged)>(25), nTagged); // text 
in body
+    // 1 decorative image + 1 pre-existing rectangle border or something
+    CPPUNIT_ASSERT(nArtifacts >= 2);
+}
+
 void Test::testTextFormField()
 {
     const OUString aFilterNames[] = {
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index 461d7bc2da6e..a7e1a41db639 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -404,6 +404,7 @@ SfxItemInfo aSlotTab[] =
     { 0, true },                           // RES_TEXT_VERT_ADJUST
     { 0, true },                           // RES_BACKGROUND_FULL_SIZE
     { 0, true },                           // RES_RTL_GUTTER
+    { 0, true },                           // RES_DECORATIVE
 
     { 0, true },                           // RES_GRFATR_MIRRORGRF
     { SID_ATTR_GRAF_CROP, true },          // RES_GRFATR_CROPGRF
@@ -416,7 +417,6 @@ SfxItemInfo aSlotTab[] =
     { 0, true },                           // RES_GRFATR_GAMMA,
     { 0, true },                           // RES_GRFATR_INVERT,
     { 0, true },                           // RES_GRFATR_TRANSPARENCY,
-    { 0, true },                           // RES_GRFATR_DUMMY1,
     { 0, true },                           // RES_GRFATR_DUMMY2,
     { 0, true },                           // RES_GRFATR_DUMMY3,
     { 0, true },                           // RES_GRFATR_DUMMY4,
@@ -609,6 +609,7 @@ void InitCore()
     aAttrTab[ RES_TEXT_VERT_ADJUST - POOLATTR_BEGIN ] = new 
SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP,RES_TEXT_VERT_ADJUST);
     aAttrTab[ RES_BACKGROUND_FULL_SIZE - POOLATTR_BEGIN ] = new 
SfxBoolItem(RES_BACKGROUND_FULL_SIZE, true);
     aAttrTab[ RES_RTL_GUTTER - POOLATTR_BEGIN ] = new 
SfxBoolItem(RES_RTL_GUTTER, false);
+    aAttrTab[ RES_DECORATIVE - POOLATTR_BEGIN ] = new 
SfxBoolItem(RES_DECORATIVE, false);
 
     aAttrTab[ RES_GRFATR_MIRRORGRF- POOLATTR_BEGIN ] =      new SwMirrorGrf;
     aAttrTab[ RES_GRFATR_CROPGRF- POOLATTR_BEGIN ] =        new SwCropGrf;
@@ -624,7 +625,6 @@ void InitCore()
     aAttrTab[ RES_GRFATR_DRAWMODE - POOLATTR_BEGIN ] =      new SwDrawModeGrf;
 
 // GraphicAttr - Dummies
-    aAttrTab[ RES_GRFATR_DUMMY1 - POOLATTR_BEGIN ] =        new SfxBoolItem( 
RES_GRFATR_DUMMY1 );
     aAttrTab[ RES_GRFATR_DUMMY2 - POOLATTR_BEGIN ] =        new SfxBoolItem( 
RES_GRFATR_DUMMY2 );
     aAttrTab[ RES_GRFATR_DUMMY3 - POOLATTR_BEGIN ] =        new SfxBoolItem( 
RES_GRFATR_DUMMY3 );
     aAttrTab[ RES_GRFATR_DUMMY4 - POOLATTR_BEGIN ] =        new SfxBoolItem( 
RES_GRFATR_DUMMY4 );
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx 
b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index e8221d4ebf12..42141b4013f9 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -1302,7 +1302,8 @@ void SwTaggedPDFHelper::BeginBlockStructureElements()
             // fly in content or fly at page
             {
                 const SwFlyFrame* pFly = static_cast<const 
SwFlyFrame*>(pFrame);
-                if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr)
+                if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr
+                    || 
pFly->GetFrameFormat().GetAttrSet().Get(RES_DECORATIVE).GetValue())
                 {
                     nPDFType = vcl::PDFWriter::NonStructElement;
                 }
diff --git a/sw/source/core/unocore/unoframe.cxx 
b/sw/source/core/unocore/unoframe.cxx
index 95b8956ea0a9..71e69a95192d 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -949,6 +949,15 @@ bool 
BaseFrameProperties_Impl::FillBaseProperties(SfxItemSet& rToSet, const SfxI
         }
     }
 
+    const ::uno::Any* pDecorative = nullptr;
+    GetProperty(RES_DECORATIVE, 0, pDecorative);
+    if (pDecorative)
+    {
+        SfxBoolItem item(RES_DECORATIVE);
+        bRet &= item.PutValue(*pDecorative, 0);
+        rToSet.Put(item);
+    }
+
     return bRet;
 }
 
diff --git a/sw/source/core/unocore/unomapproperties.hxx 
b/sw/source/core/unocore/unomapproperties.hxx
index c1e3f2fc20af..11a326d185c5 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -337,6 +337,7 @@
     { UNO_NAME_LAYOUT_SIZE, WID_LAYOUT_SIZE, 
cppu::UnoType<css::awt::Size>::get(), PropertyAttribute::MAYBEVOID | 
PropertyAttribute::READONLY, 0 }, \
     { UNO_NAME_LINE_STYLE, RES_BOX, 
cppu::UnoType<css::drawing::LineStyle>::get(),  0, LINE_STYLE }, \
     { UNO_NAME_LINE_WIDTH, RES_BOX, cppu::UnoType<sal_Int32>::get(),  0, 
LINE_WIDTH |CONVERT_TWIPS }, \
+    { u"Decorative", RES_DECORATIVE, cppu::UnoType<bool>::get(), 
PROPERTY_NONE, 0 }, \
     { UNO_NAME_TEXT_VERT_ADJUST, RES_TEXT_VERT_ADJUST, 
cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), PROPERTY_NONE ,0},
 
 #define COMMON_TEXT_CONTENT_PROPERTIES \
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 95f137ec771f..76d608ddc01e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -5693,6 +5693,21 @@ void DocxAttributeOutput::FlyFrameGraphic( const 
SwGrfNode* pGrfNode, const Size
                 FSNS( XML_xmlns, XML_a ), 
"http://schemas.openxmlformats.org/drawingml/2006/main";,
                 FSNS( XML_r, XML_id ), sRelId);
         }
+
+        if (xShapePropSet->getPropertyValue("Decorative").get<bool>())
+        {
+            m_pSerializer->startElementNS(XML_a, XML_extLst,
+                FSNS(XML_xmlns, XML_a), 
GetExport().GetFilter().getNamespaceURL(OOX_NS(dml)));
+            m_pSerializer->startElementNS(XML_a, XML_ext,
+                // Word uses this "URI" which is obviously not a URI
+                XML_uri, "{C183D7F6-B498-43B3-948B-1728B52AA6E4}");
+            rtl::Reference<::sax_fastparser::FastAttributeList> 
pAttrs(FastSerializerHelper::createAttrList());
+            m_pSerializer->singleElementNS(XML_adec, XML_decorative,
+                FSNS(XML_xmlns, XML_adec), 
"http://schemas.microsoft.com/office/drawing/2017/decorative";,
+                XML_val, "1");
+            m_pSerializer->endElementNS(XML_a, XML_ext);
+            m_pSerializer->endElementNS(XML_a, XML_extLst);
+        }
     }
 
     m_pSerializer->endElementNS( XML_wp, XML_docPr );
diff --git a/sw/source/ui/frmdlg/frmpage.cxx b/sw/source/ui/frmdlg/frmpage.cxx
index f1c20e73fa0b..2b8b9105caab 100644
--- a/sw/source/ui/frmdlg/frmpage.cxx
+++ b/sw/source/ui/frmdlg/frmpage.cxx
@@ -2792,6 +2792,7 @@ SwFrameAddPage::SwFrameAddPage(weld::Container* pPage, 
weld::DialogController* p
     , m_xAltNameFT(m_xBuilder->weld_label("altname_label"))
     , m_xAltNameED(m_xBuilder->weld_entry("altname"))
     , m_xDescriptionED(m_xBuilder->weld_text_view("description"))
+    , m_xDecorativeCB(m_xBuilder->weld_check_button("decorative"))
     , m_xSequenceFrame(m_xBuilder->weld_widget("frmSequence"))
     , m_xPrevLB(m_xBuilder->weld_combo_box("prev"))
     , m_xNextLB(m_xBuilder->weld_combo_box("next"))
@@ -2978,6 +2979,10 @@ void SwFrameAddPage::Reset(const SfxItemSet *rSet )
     m_xPrintFrameCB->set_active(rPrt.GetValue());
     m_xPrintFrameCB->save_state();
 
+    SfxBoolItem const& rDecorative = rSet->Get(RES_DECORATIVE);
+    m_xDecorativeCB->set_active(rDecorative.GetValue());
+    m_xDecorativeCB->save_state();
+
     // textflow
     if( (!m_bHtmlMode || (0 != (nHtmlMode&HTMLMODE_SOME_STYLES)))
         && m_sDlgType != "PictureDialog" && m_sDlgType != "ObjectDialog"
@@ -3043,6 +3048,11 @@ bool SwFrameAddPage::FillItemSet(SfxItemSet *rSet)
     if ( m_xPrintFrameCB->get_state_changed_from_saved() )
         bRet |= nullptr != rSet->Put( SvxPrintItem( RES_PRINT, 
m_xPrintFrameCB->get_active()));
 
+    if (m_xDecorativeCB->get_state_changed_from_saved())
+    {
+        bRet |= nullptr != rSet->Put(SfxBoolItem(RES_DECORATIVE, 
m_xDecorativeCB->get_active()));
+    }
+
     // textflow
     if (m_xTextFlowLB->get_visible() && 
m_xTextFlowLB->get_value_changed_from_saved())
     {
diff --git a/sw/source/uibase/inc/frmpage.hxx b/sw/source/uibase/inc/frmpage.hxx
index 2a6b280c68c6..db74d967ae3e 100644
--- a/sw/source/uibase/inc/frmpage.hxx
+++ b/sw/source/uibase/inc/frmpage.hxx
@@ -279,6 +279,7 @@ class SwFrameAddPage final : public SfxTabPage
     std::unique_ptr<weld::Label> m_xAltNameFT;
     std::unique_ptr<weld::Entry> m_xAltNameED;
     std::unique_ptr<weld::TextView> m_xDescriptionED;
+    std::unique_ptr<weld::CheckButton> m_xDecorativeCB;
     std::unique_ptr<weld::Widget> m_xSequenceFrame;
     std::unique_ptr<weld::ComboBox> m_xPrevLB;
     std::unique_ptr<weld::ComboBox> m_xNextLB;
diff --git a/sw/uiconfig/swriter/ui/frmaddpage.ui 
b/sw/uiconfig/swriter/ui/frmaddpage.ui
index dd949a5b69cf..51431a1ff493 100644
--- a/sw/uiconfig/swriter/ui/frmaddpage.ui
+++ b/sw/uiconfig/swriter/ui/frmaddpage.ui
@@ -146,6 +146,26 @@
                 <property name="top-attach">2</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkCheckButton" id="decorative">
+                <property name="label" translatable="yes" 
context="frmaddpage|decorative">Decorative</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">False</property>
+                <property name="use-underline">True</property>
+                <property name="draw-indicator">True</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="decorative-atkobject">
+                    <property name="AtkObject::accessible-description" 
translatable="yes" context="frmaddpage|extended_tip|decorative">The item is 
purely decorative, not part of the document content, and may be ignored by 
assistive technologies.</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">3</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
           </object>
         </child>
         <child type="label">
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index a3a4407a5971..b2ca35e6da51 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1341,6 +1341,9 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                 pParaContext->props().SetParaId(sStringValue);
             }
             break;
+        case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
+            
m_pImpl->GetGraphicImport(IMPORT_AS_DETECTED_ANCHOR)->attribute(nName, val);
+            break;
         default:
             SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled 
token: " << nName);
     }
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx 
b/writerfilter/source/dmapper/GraphicImport.cxx
index 8c2e1910a1f7..ba1408f2093e 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -254,6 +254,7 @@ public:
     bool            bSizeProtected;
     bool            bPositionProtected;
     bool            bHidden;
+    bool            bDecorative = false;
 
     sal_Int32       nShapeOptionType;
 
@@ -627,6 +628,9 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
     sal_Int32 nIntValue = rValue.getInt();
     switch( nName )
     {
+        case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
+            m_pImpl->bDecorative = true;
+        break;
         case NS_ooxml::LN_CT_Hyperlink_URL://90682;
             m_pImpl->sHyperlinkURL = rValue.getString();
         break;
@@ -1517,6 +1521,7 @@ void GraphicImport::lcl_sprm(Sprm& rSprm)
         case NS_ooxml::LN_EG_WrapType_wrapTight: // 90946;
         case NS_ooxml::LN_EG_WrapType_wrapThrough:
         case NS_ooxml::LN_CT_Anchor_docPr: // 90980;
+        case NS_ooxml::LN_CT_NonVisualDrawingProps_extLst:
         case NS_ooxml::LN_CT_Anchor_cNvGraphicFramePr: // 90981;
         case NS_ooxml::LN_CT_Anchor_a_graphic: // 90982;
         case NS_ooxml::LN_CT_WrapPath_start: // 90924;
@@ -1789,6 +1794,7 @@ uno::Reference<text::XTextContent> 
GraphicImport::createGraphicObject(uno::Refer
             sal_Int32 nWidth = - m_pImpl->nLeftPosition;
             if (m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
             {
+                
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_DECORATIVE), 
uno::Any(m_pImpl->bDecorative));
                 //adjust margins
                 if( (m_pImpl->nHoriOrient == text::HoriOrientation::LEFT &&
                     (m_pImpl->nHoriRelation == 
text::RelOrientation::PAGE_PRINT_AREA ||
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx 
b/writerfilter/source/dmapper/PropertyIds.cxx
index 61461ccc2dda..1c9bc314862b 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -364,6 +364,7 @@ OUString getPropertyName( PropertyIds eId )
             break;
         case PROP_CURSOR_NOT_IGNORE_TABLES_IN_HF: sName = 
"CursorNotIgnoreTables"; break;
         case PROP_PARA_CONNECT_BORDERS: sName= "ParaIsConnectBorder"; break;
+        case PROP_DECORATIVE: sName = "Decorative"; break;
     }
     assert(sName.getLength()>0);
     return sName;
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx 
b/writerfilter/source/dmapper/PropertyIds.hxx
index 6df95f955c12..6e45ca3f05eb 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -139,6 +139,7 @@ enum PropertyIds
         ,PROP_CREATE_FROM_MARKS
         ,PROP_CREATE_FROM_OUTLINE
         ,PROP_CURRENT_PRESENTATION
+        ,PROP_DECORATIVE
         ,PROP_DELETE
         ,PROP_DESCRIPTION
         ,PROP_DISTANCE
diff --git a/writerfilter/source/ooxml/model.xml 
b/writerfilter/source/ooxml/model.xml
index 134726d644af..158b764f355e 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -18,6 +18,7 @@
 -->
 <model
   xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main";
+  xmlns:adec="http://schemas.microsoft.com/office/drawing/2017/decorative";
   xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart";
   xmlns:dgm="http://schemas.openxmlformats.org/drawingml/2006/diagram";
   xmlns:lc="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas";
@@ -2622,10 +2623,24 @@
   <namespace name="dml-baseTypes">
     <grammar xmlns="http://relaxng.org/ns/structure/1.0"; 
ns="http://schemas.openxmlformats.org/drawingml/2006/main";>
       <include href="shared-relationshipReference"/>
-      <define name="CT_OfficeArtExtension">
-        <element>
-          <ref name="BUILT_IN_ANY_TYPE"/>
+      <define name="adec_decorative_val">
+        <attribute name="val">
+          <data type="boolean"/>
+        </attribute>
+      </define>
+      <define name="adec_decorative">
+        <element name="adec:decorative">
+          <ref name="adec_decorative_val"/>
         </element>
+      </define>
+      <define name="CT_OfficeArtExtension">
+        <choice>
+          <!-- add implemented extensions here so they can be processed -->
+          <ref name="adec_decorative"/>
+          <element>
+            <ref name="BUILT_IN_ANY_TYPE"/>
+          </element>
+        </choice>
         <attribute name="uri">
           <data type="token"/>
         </attribute>
@@ -3474,6 +3489,14 @@
         <data type="unsignedInt"/>
       </define>
     </grammar>
+    <resource name="CT_OfficeArtExtension" resource="Stream">
+      <element name="adec:decorative" 
tokenid="ooxml:CT_OfficeArtExtension_Decorative"/>
+    </resource>
+    <!-- this is not ideal, but unlike more obivous variants it appears to 
work -->
+    <resource name="adec_decorative" resource="Stream"/>
+    <resource name="adec_decorative_val" resource="Properties">
+      <attribute name="val" tokenid="ooxml:OfficeArtExtension_Decorative_val"/>
+    </resource>
     <resource name="ST_Coordinate" resource="Integer"/>
     <resource name="ST_PositiveCoordinate" resource="Integer"/>
     <resource name="ST_Angle" resource="Integer"/>
@@ -3978,6 +4001,9 @@
       <attribute name="noMove" 
tokenid="ooxml:CT_GraphicalObjectFrameLocking_noMove"/>
       <attribute name="noResize" 
tokenid="ooxml:CT_GraphicalObjectFrameLocking_noResize"/>
     </resource>
+    <resource name="CT_OfficeArtExtensionList" resource="Properties">
+      <element name="ext" tokenid="ooxml:CT_OfficeArtExtension"/>
+    </resource>
     <resource name="CT_NonVisualDrawingProps" resource="Properties">
       <element name="a:hlinkClick" 
tokenid="ooxml:CT_NonVisualDrawingProps_a_hlinkClick"/>
       <element name="hlinkHover" 
tokenid="ooxml:CT_NonVisualDrawingProps_hlinkHover"/>
diff --git a/xmloff/source/text/XMLTextFrameContext.cxx 
b/xmloff/source/text/XMLTextFrameContext.cxx
index cc3603d6e67f..ad7ca31254bc 100644
--- a/xmloff/source/text/XMLTextFrameContext.cxx
+++ b/xmloff/source/text/XMLTextFrameContext.cxx
@@ -370,6 +370,7 @@ class XMLTextFrameContext_Impl : public SvXMLImportContext
     bool    bCreateFailed : 1;
     bool    bOwnBase64Stream : 1;
     bool    mbMultipleContent : 1; // This context is created based on a 
multiple content (image)
+    bool    m_isDecorative = false;
 
     void Create();
 
@@ -682,6 +683,11 @@ void XMLTextFrameContext_Impl::Create()
         xPropSet->setPropertyValue( "AnchorPageNo", Any(nPage) );
     }
 
+    if (m_isDecorative && xPropSetInfo->hasPropertyByName("Decorative"))
+    {
+        xPropSet->setPropertyValue("Decorative", uno::Any(true));
+    }
+
     if( XML_TEXT_FRAME_OBJECT != nType  &&
         XML_TEXT_FRAME_OBJECT_OLE != nType  &&
         XML_TEXT_FRAME_APPLET != nType &&
@@ -1064,6 +1070,10 @@ XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
         case XML_ELEMENT(DRAW, XML_NOTIFY_ON_UPDATE_OF_TABLE):
             sTblName = aIter.toString();
             break;
+        case XML_ELEMENT(LO_EXT, XML_DECORATIVE):
+        case XML_ELEMENT(DRAW, XML_DECORATIVE):
+            ::sax::Converter::convertBool(m_isDecorative, aIter.toString());
+            break;
         default:
             SAL_INFO("xmloff", "unknown attribute " << 
SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << " value=" << 
aIter.toString());
         }
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 6a3e7c667c0b..8c0d53e8da93 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -3005,6 +3005,12 @@ XMLShapeExportFlags 
XMLTextParagraphExport::addTextFrameAttributes(
         }
     }
 
+    if (xPropSetInfo->hasPropertyByName("Decorative")
+        && rPropSet->getPropertyValue("Decorative").get<bool>())
+    {
+        GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_DECORATIVE, 
XML_TRUE);
+    }
+
     return nShapeFeatures;
 }
 

Reply via email to