oox/source/shape/LockedCanvasContext.cxx                             |   64 
+++++++---
 oox/source/shape/LockedCanvasContext.hxx                             |    4 
 sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_image_line.docx |binary
 sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_position.docx   |binary
 sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_twoShapes.docx  |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                             |    3 
 sw/qa/extras/ooxmlimport/ooxmlimport2.cxx                            |   38 
+++++
 writerfilter/source/dmapper/GraphicImport.cxx                        |    6 
 8 files changed, 96 insertions(+), 19 deletions(-)

New commits:
commit 4fb5817ecb614bd0c83afb3627d7caadbfe8c082
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Thu Jul 29 22:02:25 2021 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Aug 4 14:39:34 2021 +0200

    tdf#143476 improve import of lockedCanvas
    
    A lockedCanvas is used in Word 2007 to include dml-shapes. It is
    treated similar to a group, only that its content is not editable.
    
    This patch changes the implementation so, that the lockedCanvas is
    imported as group. Prior only content was imported in the case the
    content was a single custom-shape or a single group.
    That has resulted in these errors:
    Image or line in a lockedCanvas were not imported at all.
    Only one of several shapes in a lockedCanvas was imported.
    
    I have changed mpShape to mpShapePtr to reflect the data type and be
    consistent with ShapeContext.
    
    The patch changes GraphicImport so, that lockedCanvas as special
    version of a group is detected and handled. That solves regression
    from commit 3262fc5ef3bde5b158909d11ccb008161ea95519
    
    Change-Id: I57005e64ff073bca6ebb46a404486203fb6802ac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119684
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/oox/source/shape/LockedCanvasContext.cxx 
b/oox/source/shape/LockedCanvasContext.cxx
index 0a56a42eda46..88a3de0040e7 100644
--- a/oox/source/shape/LockedCanvasContext.cxx
+++ b/oox/source/shape/LockedCanvasContext.cxx
@@ -9,9 +9,13 @@
 
 #include "LockedCanvasContext.hxx"
 #include <sal/log.hxx>
+#include <drawingml/shapepropertiescontext.hxx>
+#include <oox/drawingml/connectorshapecontext.hxx>
+#include <oox/drawingml/graphicshapecontext.hxx>
 #include <oox/drawingml/shape.hxx>
 #include <oox/drawingml/shapecontext.hxx>
 #include <oox/drawingml/shapegroupcontext.hxx>
+#include <oox/helper/attributelist.hxx>
 #include <oox/token/namespaces.hxx>
 #include <oox/token/tokens.hxx>
 
@@ -22,34 +26,64 @@ namespace oox::shape
 LockedCanvasContext::LockedCanvasContext(FragmentHandler2 const& rParent)
     : FragmentHandler2(rParent)
 {
+    mpShapePtr = 
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape");
+    mpShapePtr->setLockedCanvas(true); // will be "LockedCanvas" in 
InteropGrabBag
 }
 
 LockedCanvasContext::~LockedCanvasContext() = default;
 
 ::oox::core::ContextHandlerRef
-LockedCanvasContext::onCreateContext(sal_Int32 nElementToken,
-                                     const ::oox::AttributeList& /*rAttribs*/)
+LockedCanvasContext::onCreateContext(sal_Int32 nElementToken, const 
::oox::AttributeList& rAttribs)
 {
     switch (getBaseToken(nElementToken))
     {
-        case XML_lockedCanvas:
-        case XML_nvGrpSpPr:
-        case XML_grpSpPr:
+        case XML_nvGrpSpPr: // CT_GvmlGroupShapeNonVisual, child see at end
+            return this;
+        case XML_grpSpPr: // CT_GroupShapeProporties
+            return new oox::drawingml::ShapePropertiesContext(*this, 
*mpShapePtr);
+        case XML_txSp: // CT_GvmlTextShape
             break;
-        case XML_sp:
+        case XML_sp: // CT_GvmlShape
         {
-            oox::drawingml::ShapePtr pMasterShape;
-            mpShape = 
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.CustomShape");
-            mpShape->setLockedCanvas(true);
-            return new oox::drawingml::ShapeContext(*this, pMasterShape, 
mpShape);
+            return new oox::drawingml::ShapeContext(
+                *this, mpShapePtr,
+                
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.CustomShape", 
true));
         }
-        case XML_grpSp:
+        case XML_cxnSp: // CT_GvmlConnector
         {
-            oox::drawingml::ShapePtr pMasterShape;
-            mpShape = 
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape");
-            mpShape->setLockedCanvas(true);
-            return new oox::drawingml::ShapeGroupContext(*this, pMasterShape, 
mpShape);
+            return new oox::drawingml::ConnectorShapeContext(
+                *this, mpShapePtr,
+                
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.ConnectorShape"));
         }
+        case XML_pic: // CT_GvmlPicture
+        {
+            return new oox::drawingml::GraphicShapeContext(
+                *this, mpShapePtr,
+                
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GraphicObjectShape"));
+        }
+        case XML_graphicFrame: // CT_GvmlGraphicObjectFrame
+        {
+            return new oox::drawingml::GraphicalObjectFrameContext(
+                *this, mpShapePtr,
+                
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GraphicObjectShape"),
+                true);
+        }
+        case XML_grpSp: // CT_GvmlGroupShape
+        {
+            return new oox::drawingml::ShapeGroupContext(
+                *this, mpShapePtr,
+                
std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape"));
+        }
+        // mandatory child elements of CT_GvmlGroupShapeNonVisual
+        case XML_cNvPr: // CT_NonVisualDrawingProps
+        {
+            mpShapePtr->setHidden(rAttribs.getBool(XML_hidden, false));
+            mpShapePtr->setId(rAttribs.getString(XML_id).get());
+            mpShapePtr->setName(rAttribs.getString(XML_name).get());
+            break;
+        }
+        case XML_cNvGrpSpPr: // CT_NonVisualGroupDrawingShapeProps
+            break;
         default:
             SAL_WARN("oox", "LockedCanvasContext::createFastChildContext: 
unhandled element:"
                                 << getBaseToken(nElementToken));
diff --git a/oox/source/shape/LockedCanvasContext.hxx 
b/oox/source/shape/LockedCanvasContext.hxx
index bf6766f36b79..076931d092c0 100644
--- a/oox/source/shape/LockedCanvasContext.hxx
+++ b/oox/source/shape/LockedCanvasContext.hxx
@@ -25,10 +25,10 @@ public:
     oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElementToken,
                                                  const ::oox::AttributeList& 
rAttribs) override;
 
-    const oox::drawingml::ShapePtr& getShape() const { return mpShape; }
+    const oox::drawingml::ShapePtr& getShape() const { return mpShapePtr; }
 
 private:
-    oox::drawingml::ShapePtr mpShape;
+    oox::drawingml::ShapePtr mpShapePtr;
 };
 }
 
diff --git 
a/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_image_line.docx 
b/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_image_line.docx
new file mode 100644
index 000000000000..9a5c87e347c4
Binary files /dev/null and 
b/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_image_line.docx differ
diff --git a/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_position.docx 
b/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_position.docx
new file mode 100644
index 000000000000..a63615a311b1
Binary files /dev/null and 
b/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_position.docx differ
diff --git 
a/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_twoShapes.docx 
b/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_twoShapes.docx
new file mode 100644
index 000000000000..6e654f3d3330
Binary files /dev/null and 
b/sw/qa/extras/ooxmlimport/data/tdf143476_lockedCanvas_twoShapes.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index f6d986544993..3b59da527c3f 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -720,7 +720,8 @@ CPPUNIT_TEST_FIXTURE(Test, testN820504)
 CPPUNIT_TEST_FIXTURE(Test, testFdo43641)
 {
     load(mpTestDocumentPath, "fdo43641.docx");
-    uno::Reference<container::XIndexAccess> xGroupShape(getShape(1), 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xGroupLockedCanvas(getShape(1), 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> 
xGroupShape(xGroupLockedCanvas->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<drawing::XShape> xLine(xGroupShape->getByIndex(1), 
uno::UNO_QUERY);
     // This was 2200, not 2579 in mm100, i.e. the size of the line shape was 
incorrect.
     // File cx=928694EMU = 2579.7Hmm, round up 2580Hmm. Currently off by 1.
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 86f91c91fcaf..e132befdd09f 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -48,6 +48,44 @@ public:
     }
 };
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf143476LockedCanvas_twoShapes)
+{
+    // Given a lockedCanvas in a docx document with compatibility to Word 
version 12 (2007).
+    // It contains two shapes. Error was, that the lockedCanvas was not 
imported as group at all,
+    // and only one shape was imported and that one was scaled to lockedCanvas 
area.
+    load(mpTestDocumentPath, "tdf143476_lockedCanvas_twoShapes.docx");
+    // The group shape corresponds to the lockedCanvas.
+    uno::Reference<container::XIndexAccess> xGroup(getShape(1), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xGroup.is());
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xGroup->getCount());
+    uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(1), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(14200), xShape->getPosition().X);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1120), xShape->getPosition().Y);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1928), xShape->getSize().Width);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1593), xShape->getSize().Height);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143476LockedCanvas_position)
+{
+    // Given a lockedCanvas in a docx document with compatibility to Word 
version 12 (2007).
+    // Tests fix for regression introduced by 
3262fc5ef3bde5b158909d11ccb008161ea95519
+    // Error was, that the imported shape had wrong position.
+    load(mpTestDocumentPath, "tdf143476_lockedCanvas_position.docx");
+    // The group shape corresponds to the lockedCanvas.
+    uno::Reference<drawing::XShape> xGroupShape(getShape(1), uno::UNO_QUERY);
+    // Without fix in place the test failed with position 185|947.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2351), xGroupShape->getPosition().X);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(26), xGroupShape->getPosition().Y);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143476LockedCanvas_image_line)
+{
+    // Given a lockedCanvas in a docx document with compatibility to Word 
version 12 (2007).
+    // It contains an image and a line. Error was, that both were not imported.
+    load(mpTestDocumentPath, "tdf143476_lockedCanvas_image_line.docx");
+    CPPUNIT_ASSERT_MESSAGE("No shapes imported", getShapes() > 0);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf143475rotatedWord2007imageInline)
 {
     // Given a docx document with compatibility to Word version 12 (2007), 
which has a shape
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx 
b/writerfilter/source/dmapper/GraphicImport.cxx
index d7c842ea9d69..f97fdec0fc68 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -913,8 +913,12 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
                         // and contour wrap is different to Word. As 
workaround diagrams are excluded
                         // here in various places.
                         const bool bIsDiagram = 
oox::drawingml::DrawingML::IsDiagram(m_xShape);
+                        // tdf#143476: A lockedCanvas (Word2007) is imported 
as group, but has not
+                        // got size and position. Values from m_Impl has to be 
used.
+                        bool bIsLockedCanvas(false);
+                        aInteropGrabBag.getValue("LockedCanvas") >>= 
bIsLockedCanvas;
                         const bool bIsGroupOrLine = 
(xServiceInfo->supportsService("com.sun.star.drawing.GroupShape")
-                            && !bIsDiagram)
+                            && !bIsDiagram && !bIsLockedCanvas)
                             || 
xServiceInfo->supportsService("com.sun.star.drawing.LineShape");
                         SdrObject* pShape = GetSdrObjectFromXShape(m_xShape);
                         if ((bIsGroupOrLine && 
!lcl_bHasGroupSlantedChild(pShape) && nOOXAngle == 0)

Reply via email to