[Libreoffice-commits] core.git: include/svx include/xmloff svx/source sw/qa sw/source xmloff/source

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Mon Mar 15 09:16:47 UTC 2021


 include/svx/strings.hrc                   |    1 
 include/xmloff/shapeexport.hxx            |    9 +++++
 svx/source/svdraw/svdpage.cxx             |   20 ++++++++++++
 sw/qa/extras/odfexport/data/MadeByLO7.odt |binary
 sw/qa/extras/odfexport/odfexport.cxx      |   14 ++++++++
 sw/source/filter/xml/wrtxml.cxx           |   18 +++++++----
 sw/source/filter/xml/xmlexp.cxx           |    9 +++++
 xmloff/source/draw/shapeexport.cxx        |   47 ++++++++++++++++++++++++++++++
 8 files changed, 112 insertions(+), 6 deletions(-)

New commits:
commit 9bc6160e0acbc78be998129ea55ed7e4529959fa
Author:     Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Mon Mar 8 20:03:35 2021 +0100
Commit:     Michael Stahl <michael.stahl at allotropia.de>
CommitDate: Mon Mar 15 10:15:57 2021 +0100

    tdf#133487 sw ODF export: reorder flys' ZOrder/z-index...
    
    ... so background shapes have lower z-index than foreground shapes,
    as is recommended by ODF 1.3.
    
    Also let SdrObjList::sort() record Undo actions, because earlier Undo
    actions could expect the previous sort order.
    
    Change-Id: Idbecf0a2acd525d42efc0ac92677b1c7987cc6ad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112180
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>

diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc
index 1b59e4d765e8..3a307cdc6a36 100644
--- a/include/svx/strings.hrc
+++ b/include/svx/strings.hrc
@@ -155,6 +155,7 @@
 #define STR_EditPutToTop                                    NC_("STR_EditPutToTop", "Move %1 to front")
 #define STR_EditPutToBtm                                    NC_("STR_EditPutToBtm", "Move %1 to back")
 #define STR_EditRevOrder                                    NC_("STR_EditRevOrder", "Reverse order of %1")
+#define STR_SortShapes                                      NC_("STR_SortShapes", "Sort shapes")
 #define STR_EditMove                                        NC_("STR_EditMove", "Move %1")
 #define STR_EditResize                                      NC_("STR_EditResize", "Resize %1")
 #define STR_EditRotate                                      NC_("STR_EditRotate", "Rotate %1")
diff --git a/include/xmloff/shapeexport.hxx b/include/xmloff/shapeexport.hxx
index ff38aeaf4cab..e5012d84836d 100644
--- a/include/xmloff/shapeexport.hxx
+++ b/include/xmloff/shapeexport.hxx
@@ -28,6 +28,7 @@
 #include <rtl/ustrbuf.hxx>
 #include <salhelper/simplereferenceobject.hxx>
 
+#include <functional>
 #include <map>
 #include <xmloff/animexp.hxx>
 #include <xmloff/families.hxx>
@@ -297,6 +298,14 @@ public:
     const rtl::Reference< XMLTableExport >&     GetShapeTableExport();
 };
 
+namespace xmloff {
+
+XMLOFF_DLLPUBLIC void FixZOrder(
+    css::uno::Reference<css::drawing::XShapes> const& xShapes,
+    std::function<bool(css::uno::Reference<css::beans::XPropertySet> const&)> const& rIsInBackground);
+
+} // namespace xmloff
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdpage.cxx b/svx/source/svdraw/svdpage.cxx
index 0c7c806ad4a8..d07f40e4f701 100644
--- a/svx/source/svdraw/svdpage.cxx
+++ b/svx/source/svdraw/svdpage.cxx
@@ -40,6 +40,9 @@
 #include <svx/svdmodel.hxx>
 #include <svx/svdlayer.hxx>
 #include <svx/svdpagv.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
 #include <svx/xfillit0.hxx>
 #include <svx/fmdpage.hxx>
 
@@ -667,12 +670,29 @@ void SdrObjList::sort( std::vector<sal_Int32>& sortOrder)
     }
 #endif
 
+    SdrModel & rModel(getSdrPageFromSdrObjList()->getSdrModelFromSdrPage());
+    bool const isUndo(rModel.IsUndoEnabled());
+    if (isUndo)
+    {
+        rModel.BegUndo(SvxResId(STR_SortShapes));
+    }
+
     for (size_t i = 0; i < aNewSortOrder.size(); ++i)
     {
         aNewList[i] = maList[ aNewSortOrder[i] ];
+        if (isUndo && i != sal::static_int_cast<size_t>(aNewSortOrder[i]))
+        {
+            rModel.AddUndo(rModel.GetSdrUndoFactory().CreateUndoObjectOrdNum(
+                        *aNewList[i], aNewSortOrder[i], i));
+        }
         aNewList[i]->SetOrdNum(i);
     }
 
+    if (isUndo)
+    {
+        rModel.EndUndo();
+    }
+
     std::swap(aNewList, maList);
 }
 
diff --git a/sw/qa/extras/odfexport/data/MadeByLO7.odt b/sw/qa/extras/odfexport/data/MadeByLO7.odt
new file mode 100644
index 000000000000..9587fffe6470
Binary files /dev/null and b/sw/qa/extras/odfexport/data/MadeByLO7.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 7e49bbd1b048..285da20616e0 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -232,6 +232,20 @@ DECLARE_ODFEXPORT_TEST(testTdf130314, "tdf130314.docx")
     CPPUNIT_ASSERT_EQUAL(2, getPages());
 }
 
+DECLARE_ODFEXPORT_EXPORTONLY_TEST(testTdf133487, "MadeByLO7.odt")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+    // shape in background has lowest index
+    assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[2]/draw:custom-shape", "z-index", "0");
+    assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[2]/draw:custom-shape[@draw:z-index = '0']/attribute::draw:style-name]/style:graphic-properties", "run-through", "background");
+    // shape in foreground, previously index 1
+    assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[1]/draw:custom-shape", "z-index", "2");
+    assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[1]/draw:custom-shape[@draw:z-index = '2']/attribute::draw:style-name]/style:graphic-properties", "run-through", "foreground");
+    // shape in foreground, previously index 0
+    assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[3]/draw:custom-shape", "z-index", "1");
+    assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[3]/draw:custom-shape[@draw:z-index = '1']/attribute::draw:style-name]/style:graphic-properties", "run-through", "foreground");
+}
+
 DECLARE_ODFEXPORT_TEST(testTdf139126, "tdf139126.odt")
 {
     CPPUNIT_ASSERT_EQUAL(1, getPages());
diff --git a/sw/source/filter/xml/wrtxml.cxx b/sw/source/filter/xml/wrtxml.cxx
index 4ae5964a7d2e..288814017c25 100644
--- a/sw/source/filter/xml/wrtxml.cxx
+++ b/sw/source/filter/xml/wrtxml.cxx
@@ -23,6 +23,7 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/task/XStatusIndicator.hpp>
 #include <com/sun/star/xml/sax/Writer.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/document/XExporter.hpp>
 #include <com/sun/star/document/XFilter.hpp>
 #include <com/sun/star/frame/XModule.hpp>
@@ -34,6 +35,7 @@
 #include <comphelper/propertysetinfo.hxx>
 #include <vcl/errinf.hxx>
 #include <sal/log.hxx>
+#include <o3tl/any.hxx>
 #include <svx/xmlgrhlp.hxx>
 #include <svx/xmleohlp.hxx>
 #include <unotools/saveopt.hxx>
@@ -52,6 +54,7 @@
 #include <docstat.hxx>
 #include <docsh.hxx>
 
+#include <xmloff/shapeexport.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 #include <swerror.h>
 #include "wrtxml.hxx"
@@ -180,6 +183,15 @@ ErrCode SwXMLWriter::Write_( const uno::Reference < task::XStatusIndicator >& xS
     SvtSaveOptions aSaveOpt;
     xInfoSet->setPropertyValue( "UsePrettyPrinting", makeAny(aSaveOpt.IsPrettyPrinting()) );
 
+    uno::Reference<lang::XComponent> const xModelComp(m_pDoc->GetDocShell()->GetModel());
+    uno::Reference<drawing::XDrawPageSupplier> const xDPS(xModelComp, uno::UNO_QUERY);
+    assert(xDPS.is());
+    xmloff::FixZOrder(xDPS->getDrawPage(),
+        [](uno::Reference<beans::XPropertySet> const& xShape)
+        {
+            return !*o3tl::doAccess<bool>(xShape->getPropertyValue("Opaque"));
+        });
+
     // save show redline mode ...
     RedlineFlags const nOrigRedlineFlags = m_pDoc->getIDocumentRedlineAccess().GetRedlineFlags();
     RedlineFlags nRedlineFlags(nOrigRedlineFlags);
@@ -248,12 +260,6 @@ ErrCode SwXMLWriter::Write_( const uno::Reference < task::XStatusIndicator >& xS
     if( xStatusIndicator.is() )
         *pArgs++ <<= xStatusIndicator;
 
-    //Get model
-    uno::Reference< lang::XComponent > xModelComp = m_pDoc->GetDocShell()->GetModel();
-    OSL_ENSURE( xModelComp.is(), "XMLWriter::Write: got no model" );
-    if( !xModelComp.is() )
-        return ERR_SWG_WRITE_ERROR;
-
     PutNumFormatFontsInAttrPool();
     PutEditEngFontsInAttrPool();
 
diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx
index 2c646dc0268e..d8e4ba10df5a 100644
--- a/sw/source/filter/xml/xmlexp.cxx
+++ b/sw/source/filter/xml/xmlexp.cxx
@@ -269,6 +269,15 @@ ErrCode SwXMLExport::exportDoc( enum XMLTokenEnum eClass )
     m_bSavedShowChanges = pLayout == nullptr || !pLayout->IsHideRedlines();
     if( bSaveRedline )
     {
+        // tdf#133487 call this once in flat-ODF case
+        uno::Reference<drawing::XDrawPageSupplier> const xDPS(GetModel(), uno::UNO_QUERY);
+        assert(xDPS.is());
+        xmloff::FixZOrder(xDPS->getDrawPage(),
+            [](uno::Reference<beans::XPropertySet> const& xShape)
+            {
+                return !*o3tl::doAccess<bool>(xShape->getPropertyValue("Opaque"));
+            });
+
         // now save and switch redline mode
         nRedlineFlags = pDoc->getIDocumentRedlineAccess().GetRedlineFlags();
         pDoc->getIDocumentRedlineAccess().SetRedlineFlags(
diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
index c8bbcbfa3ca2..27f280d7ed9b 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -61,6 +61,7 @@
 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
 #include <com/sun/star/drawing/QRCode.hpp>
 #include <com/sun/star/drawing/QRCodeErrorCorrection.hpp>
+#include <com/sun/star/drawing/XShapes3.hpp>
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/embed/XStorage.hpp>
 #include <com/sun/star/embed/XTransactedObject.hpp>
@@ -981,6 +982,52 @@ void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xS
     maCurrentShapesIter = aOldCurrentShapesIter;
 }
 
+namespace xmloff {
+
+void FixZOrder(uno::Reference<drawing::XShapes> const& xShapes,
+    std::function<bool(uno::Reference<beans::XPropertySet> const&)> const& rIsInBackground)
+{
+    uno::Reference<drawing::XShapes3> const xShapes3(xShapes, uno::UNO_QUERY);
+    assert(xShapes3.is());
+    if (!xShapes3.is())
+    {
+        return; // only SvxDrawPage implements this
+    }
+    std::vector<sal_Int32> background;
+    std::vector<sal_Int32> foreground;
+    // shapes are sorted by ZOrder
+    sal_Int32 const nCount(xShapes->getCount());
+    for (sal_Int32 i = 0; i < nCount; ++i)
+    {
+        uno::Reference<beans::XPropertySet> const xShape(xShapes->getByIndex(i), uno::UNO_QUERY);
+        if (rIsInBackground(xShape))
+        {
+            background.emplace_back(i);
+        }
+        else
+        {
+            foreground.emplace_back(i);
+        }
+    }
+    if (background.empty() || foreground.empty())
+    {
+        return; // nothing to do
+    }
+    uno::Sequence<sal_Int32> aNewOrder(nCount);
+    std::copy(background.begin(), background.end(), aNewOrder.begin());
+    std::copy(foreground.begin(), foreground.end(), aNewOrder.begin() + background.size());
+    try
+    {
+        xShapes3->sort(aNewOrder);
+    }
+    catch (uno::Exception const&)
+    {
+        SAL_WARN("xmloff", "FixZOrder: exception");
+    }
+}
+
+} // namespace xmloff
+
 void XMLShapeExport::seekShapes( const uno::Reference< drawing::XShapes >& xShapes ) throw()
 {
     if( xShapes.is() )


More information about the Libreoffice-commits mailing list