[Libreoffice-commits] core.git: svx/Library_svxcore.mk svx/qa svx/source

Regina Henschel (via logerrit) logerrit at kemper.freedesktop.org
Sat Aug 10 10:07:55 UTC 2019


 svx/Library_svxcore.mk                                   |    1 
 svx/qa/unit/customshapes.cxx                             |   47 ++
 svx/qa/unit/data/tdf126512_OOXMLHandleMovementInODF.odp  |binary
 svx/source/svdraw/presetooxhandleadjustmentrelations.cxx |  336 +++++++++++++++
 svx/source/svdraw/presetooxhandleadjustmentrelations.hxx |   29 +
 svx/source/svdraw/svdoashp.cxx                           |   40 +
 6 files changed, 453 insertions(+)

New commits:
commit ba61c3174bc24bc03e3f72fbc8d102b3312b5ff6
Author:     Regina Henschel <rb.henschel at t-online.de>
AuthorDate: Fri Aug 2 21:19:30 2019 +0200
Commit:     Regina Henschel <rb.henschel at t-online.de>
CommitDate: Sat Aug 10 12:07:21 2019 +0200

    tdf#126512 make handle of ooxml-shapes usable in odp
    
    The error was that handles in OOXML shapes can be used in LibreOffice
    as long as you work in OOXML format, but not anymore when you convert
    the file to ODF. Handles in OOXML reference the adjustment values by
    name, e.g. 'RefX = adj5'. ODF has no way to save this, so this
    information is lost. The patch reconstructs this information from the
    shape definition of the preset shape. It gets the preset shape name
    'foo' from the shape type 'ooxml-foo'. This means that it only works
    with our own naming convention. Still, I think it's an improvement for
    our users.
    
    Change-Id: Iebd9f36a5c36356a12c8687e961c7802111cbd85
    Reviewed-on: https://gerrit.libreoffice.org/76887
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.henschel at t-online.de>

diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index c36e0f6ae09a..4aca86ba0fb5 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -278,6 +278,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
     svx/source/svdraw/charthelper \
     svx/source/svdraw/gradtrns \
     svx/source/svdraw/polypolygoneditor \
+    svx/source/svdraw/presetooxhandleadjustmentrelations \
     svx/source/svdraw/sdrhittesthelper \
     svx/source/svdraw/sdrmasterpagedescriptor \
     svx/source/svdraw/sdrpagewindow \
diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx
index b70a8e536218..5d1d4c3f44fe 100644
--- a/svx/qa/unit/customshapes.cxx
+++ b/svx/qa/unit/customshapes.cxx
@@ -413,6 +413,53 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testQuadraticCurveTo)
     //Add some tolerance
     CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("bad height of quadraticcurveto", 3004, fHeight, 10.0);
 }
+
+CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf126512_OOXML_handle_in_ODP)
+{
+    // The test covers all preset shapes with handles. Connectors are included as ordinary
+    // shapes to prevent converting. The file was created in PowerPoint 365 and then
+    // opened and exported to ODF format by LibreOffice.
+    // Error was, that for shapes, which were originally imported from OOXML, the handles
+    // could not be moved at all.
+    const OUString sFileName("tdf126512_OOXMLHandleMovementInODF.odp");
+    OUString sURL = m_directories.getURLFromSrc(sDataDirectory) + sFileName;
+    mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.drawing.DrawingDocument");
+    CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is());
+
+    OUString sErrors; // sErrors collects shape type and handle index for failing cases
+    for (sal_uInt8 i = 0; i < countShapes(); i++)
+    {
+        uno::Reference<drawing::XShape> xShape(getShape(i));
+        SdrObjCustomShape& rSdrObjCustomShape(
+            static_cast<SdrObjCustomShape&>(*GetSdrObjectFromXShape(xShape)));
+        OUString sShapeType("non-primitive"); // only to initialize, value not used here
+        const SdrCustomShapeGeometryItem& rGeometryItem(
+            rSdrObjCustomShape.GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
+        const uno::Any* pAny = rGeometryItem.GetPropertyValueByName("Type");
+        if (pAny)
+            *pAny >>= sShapeType;
+
+        sal_uInt8 nHandlesCount = rSdrObjCustomShape.GetInteractionHandles().size();
+        for (sal_uInt8 j = 0; j < nHandlesCount; j++)
+        {
+            css::awt::Point aInitialPosition(
+                rSdrObjCustomShape.GetInteractionHandles()[j].aPosition);
+            // The handles are initialized in the test document, so that if the handle is moveable
+            // in that direction at all, then it can move at least with an amount of 100.
+            Point aDesiredPosition(aInitialPosition.X + 100, aInitialPosition.Y + 100);
+            rSdrObjCustomShape.DragMoveCustomShapeHdl(aDesiredPosition, j, false);
+            css::awt::Point aObservedPosition(
+                rSdrObjCustomShape.GetInteractionHandles()[j].aPosition);
+            if (aInitialPosition.X == aObservedPosition.X
+                && aInitialPosition.Y == aObservedPosition.Y)
+            {
+                sErrors += "\n";
+                sErrors += OUString::number(i) + " " + sShapeType + "  " + OUString::number(j);
+            }
+        }
+    }
+    CPPUNIT_ASSERT_EQUAL(OUString(), sErrors);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/qa/unit/data/tdf126512_OOXMLHandleMovementInODF.odp b/svx/qa/unit/data/tdf126512_OOXMLHandleMovementInODF.odp
new file mode 100644
index 000000000000..7dd283f8807d
Binary files /dev/null and b/svx/qa/unit/data/tdf126512_OOXMLHandleMovementInODF.odp differ
diff --git a/svx/source/svdraw/presetooxhandleadjustmentrelations.cxx b/svx/source/svdraw/presetooxhandleadjustmentrelations.cxx
new file mode 100644
index 000000000000..e334bb06bdc2
--- /dev/null
+++ b/svx/source/svdraw/presetooxhandleadjustmentrelations.cxx
@@ -0,0 +1,336 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtl/ustring.hxx>
+#include <unordered_map>
+#include "presetooxhandleadjustmentrelations.hxx"
+
+namespace
+{
+typedef std::unordered_map<OUString, OUString> HandleAdjRelHashMap;
+
+struct HandleAdjRel
+{
+    // Shape name without leading "ooxml-", underscore, zero based handle index
+    // e.g. The third handle in shape of type "ooxml-circularArrow" will be
+    // identified by key "circularArrow_2"
+    const OUString sShape_Handle;
+
+    // 4 tokens with separator "|"
+    // first: RefX or RefR, na if not exists
+    // second: adj, or adj1 or adj2, etc. as in preset, na if not exists
+    // third: RefY or RefAngle, na if not exists
+    // forth: adj, or adj1 or adj2, etc. as in preset, na if not exists
+    // e.g. The third handle in shape <circularArrow> has in the preset
+    // the tag <ahPolar gdRefR="adj5" minR="0" maxR="25000"> .
+    // The resulting value in the map here is "RefR|adj5|na|na"
+    const OUString sAdjReferences;
+};
+
+// The array initializer has been extracted from
+// oox/source/drawingml/customshapes/presetShapeDefinitions.xml
+// by using an XSLT file. That file is attached to tdf#126512.
+static const HandleAdjRel aHandleAdjRelArray[]
+    = { { "accentBorderCallout1_0", "RefX|adj2|RefY|adj1" },
+        { "accentBorderCallout1_1", "RefX|adj4|RefY|adj3" },
+        { "accentBorderCallout2_0", "RefX|adj2|RefY|adj1" },
+        { "accentBorderCallout2_1", "RefX|adj4|RefY|adj3" },
+        { "accentBorderCallout2_2", "RefX|adj6|RefY|adj5" },
+        { "accentBorderCallout3_0", "RefX|adj2|RefY|adj1" },
+        { "accentBorderCallout3_1", "RefX|adj4|RefY|adj3" },
+        { "accentBorderCallout3_2", "RefX|adj6|RefY|adj5" },
+        { "accentBorderCallout3_3", "RefX|adj8|RefY|adj7" },
+        { "accentCallout1_0", "RefX|adj2|RefY|adj1" },
+        { "accentCallout1_1", "RefX|adj4|RefY|adj3" },
+        { "accentCallout2_0", "RefX|adj2|RefY|adj1" },
+        { "accentCallout2_1", "RefX|adj4|RefY|adj3" },
+        { "accentCallout2_2", "RefX|adj6|RefY|adj5" },
+        { "accentCallout3_0", "RefX|adj2|RefY|adj1" },
+        { "accentCallout3_1", "RefX|adj4|RefY|adj3" },
+        { "accentCallout3_2", "RefX|adj6|RefY|adj5" },
+        { "accentCallout3_3", "RefX|adj8|RefY|adj7" },
+        { "arc_0", "na|na|RefAngle|adj1" },
+        { "arc_1", "na|na|RefAngle|adj2" },
+        { "bentArrow_0", "RefX|adj1|na|na" },
+        { "bentArrow_1", "na|na|RefY|adj2" },
+        { "bentArrow_2", "RefX|adj3|na|na" },
+        { "bentArrow_3", "RefX|adj4|na|na" },
+        { "bentConnector3_0", "RefX|adj1|na|na" },
+        { "bentConnector4_0", "RefX|adj1|na|na" },
+        { "bentConnector4_1", "na|na|RefY|adj2" },
+        { "bentConnector5_0", "RefX|adj1|na|na" },
+        { "bentConnector5_1", "na|na|RefY|adj2" },
+        { "bentConnector5_2", "RefX|adj3|na|na" },
+        { "bentUpArrow_0", "na|na|RefY|adj1" },
+        { "bentUpArrow_1", "RefX|adj2|na|na" },
+        { "bentUpArrow_2", "na|na|RefY|adj3" },
+        { "bevel_0", "RefX|adj|na|na" },
+        { "blockArc_0", "na|na|RefAngle|adj1" },
+        { "blockArc_1", "RefR|adj3|RefAngle|adj2" },
+        { "borderCallout1_0", "RefX|adj2|RefY|adj1" },
+        { "borderCallout1_1", "RefX|adj4|RefY|adj3" },
+        { "borderCallout2_0", "RefX|adj2|RefY|adj1" },
+        { "borderCallout2_1", "RefX|adj4|RefY|adj3" },
+        { "borderCallout2_2", "RefX|adj6|RefY|adj5" },
+        { "borderCallout3_0", "RefX|adj2|RefY|adj1" },
+        { "borderCallout3_1", "RefX|adj4|RefY|adj3" },
+        { "borderCallout3_2", "RefX|adj6|RefY|adj5" },
+        { "borderCallout3_3", "RefX|adj8|RefY|adj7" },
+        { "bracePair_0", "na|na|RefY|adj" },
+        { "bracketPair_0", "na|na|RefY|adj" },
+        { "callout1_0", "RefX|adj2|RefY|adj1" },
+        { "callout1_1", "RefX|adj4|RefY|adj3" },
+        { "callout2_0", "RefX|adj2|RefY|adj1" },
+        { "callout2_1", "RefX|adj4|RefY|adj3" },
+        { "callout2_2", "RefX|adj6|RefY|adj5" },
+        { "callout3_0", "RefX|adj2|RefY|adj1" },
+        { "callout3_1", "RefX|adj4|RefY|adj3" },
+        { "callout3_2", "RefX|adj6|RefY|adj5" },
+        { "callout3_3", "RefX|adj8|RefY|adj7" },
+        { "can_0", "na|na|RefY|adj" },
+        { "chevron_0", "RefX|adj|na|na" },
+        { "chord_0", "na|na|RefAngle|adj1" },
+        { "chord_1", "na|na|RefAngle|adj2" },
+        { "circularArrow_0", "na|na|RefAngle|adj2" },
+        { "circularArrow_1", "na|na|RefAngle|adj4" },
+        { "circularArrow_2", "RefR|adj1|RefAngle|adj3" },
+        { "circularArrow_3", "RefR|adj5|na|na" },
+        { "cloudCallout_0", "RefX|adj1|RefY|adj2" },
+        { "corner_0", "na|na|RefY|adj1" },
+        { "corner_1", "RefX|adj2|na|na" },
+        { "cube_0", "na|na|RefY|adj" },
+        { "curvedConnector3_0", "RefX|adj1|na|na" },
+        { "curvedConnector4_0", "RefX|adj1|na|na" },
+        { "curvedConnector4_1", "na|na|RefY|adj2" },
+        { "curvedConnector5_0", "RefX|adj1|na|na" },
+        { "curvedConnector5_1", "na|na|RefY|adj2" },
+        { "curvedConnector5_2", "RefX|adj3|na|na" },
+        { "curvedDownArrow_0", "RefX|adj1|na|na" },
+        { "curvedDownArrow_1", "RefX|adj2|na|na" },
+        { "curvedDownArrow_2", "na|na|RefY|adj3" },
+        { "curvedLeftArrow_0", "na|na|RefY|adj1" },
+        { "curvedLeftArrow_1", "na|na|RefY|adj2" },
+        { "curvedLeftArrow_2", "RefX|adj3|na|na" },
+        { "curvedRightArrow_0", "na|na|RefY|adj1" },
+        { "curvedRightArrow_1", "na|na|RefY|adj2" },
+        { "curvedRightArrow_2", "RefX|adj3|na|na" },
+        { "curvedUpArrow_0", "RefX|adj1|na|na" },
+        { "curvedUpArrow_1", "RefX|adj2|na|na" },
+        { "curvedUpArrow_2", "na|na|RefY|adj3" },
+        { "diagStripe_0", "na|na|RefY|adj" },
+        { "donut_0", "RefR|adj|na|na" },
+        { "doubleWave_0", "na|na|RefY|adj1" },
+        { "doubleWave_1", "RefX|adj2|na|na" },
+        { "downArrow_0", "RefX|adj1|na|na" },
+        { "downArrow_1", "na|na|RefY|adj2" },
+        { "downArrowCallout_0", "RefX|adj1|na|na" },
+        { "downArrowCallout_1", "RefX|adj2|na|na" },
+        { "downArrowCallout_2", "na|na|RefY|adj3" },
+        { "downArrowCallout_3", "na|na|RefY|adj4" },
+        { "ellipseRibbon_0", "na|na|RefY|adj1" },
+        { "ellipseRibbon_1", "RefX|adj2|na|na" },
+        { "ellipseRibbon_2", "na|na|RefY|adj3" },
+        { "ellipseRibbon2_0", "na|na|RefY|adj1" },
+        { "ellipseRibbon2_1", "RefX|adj2|na|na" },
+        { "ellipseRibbon2_2", "na|na|RefY|adj3" },
+        { "foldedCorner_0", "RefX|adj|na|na" },
+        { "frame_0", "RefX|adj1|na|na" },
+        { "gear6_0", "na|na|RefY|adj1" },
+        { "gear6_1", "RefX|adj2|na|na" },
+        { "gear9_0", "na|na|RefY|adj1" },
+        { "gear9_1", "RefX|adj2|na|na" },
+        { "halfFrame_0", "na|na|RefY|adj1" },
+        { "halfFrame_1", "RefX|adj2|na|na" },
+        { "hexagon_0", "RefX|adj|na|na" },
+        { "homePlate_0", "RefX|adj|na|na" },
+        { "horizontalScroll_0", "RefX|adj|na|na" },
+        { "leftArrow_0", "na|na|RefY|adj1" },
+        { "leftArrow_1", "RefX|adj2|na|na" },
+        { "leftArrowCallout_0", "na|na|RefY|adj1" },
+        { "leftArrowCallout_1", "na|na|RefY|adj2" },
+        { "leftArrowCallout_2", "RefX|adj3|na|na" },
+        { "leftArrowCallout_3", "RefX|adj4|na|na" },
+        { "leftBrace_0", "na|na|RefY|adj1" },
+        { "leftBrace_1", "na|na|RefY|adj2" },
+        { "leftBracket_0", "na|na|RefY|adj" },
+        { "leftCircularArrow_0", "na|na|RefAngle|adj2" },
+        { "leftCircularArrow_1", "na|na|RefAngle|adj4" },
+        { "leftCircularArrow_2", "RefR|adj1|RefAngle|adj3" },
+        { "leftCircularArrow_3", "RefR|adj5|na|na" },
+        { "leftRightArrow_0", "na|na|RefY|adj1" },
+        { "leftRightArrow_1", "RefX|adj2|na|na" },
+        { "leftRightArrowCallout_0", "na|na|RefY|adj1" },
+        { "leftRightArrowCallout_1", "na|na|RefY|adj2" },
+        { "leftRightArrowCallout_2", "RefX|adj3|na|na" },
+        { "leftRightArrowCallout_3", "RefX|adj4|na|na" },
+        { "leftRightCircularArrow_0", "na|na|RefAngle|adj2" },
+        { "leftRightCircularArrow_1", "na|na|RefAngle|adj4" },
+        { "leftRightCircularArrow_2", "RefR|adj1|RefAngle|adj3" },
+        { "leftRightCircularArrow_3", "RefR|adj5|na|na" },
+        { "leftRightRibbon_0", "na|na|RefY|adj1" },
+        { "leftRightRibbon_1", "RefX|adj2|na|na" },
+        { "leftRightRibbon_2", "na|na|RefY|adj3" },
+        { "leftRightUpArrow_0", "RefX|adj1|na|na" },
+        { "leftRightUpArrow_1", "RefX|adj2|na|na" },
+        { "leftRightUpArrow_2", "na|na|RefY|adj3" },
+        { "leftUpArrow_0", "na|na|RefY|adj1" },
+        { "leftUpArrow_1", "RefX|adj2|na|na" },
+        { "leftUpArrow_2", "na|na|RefY|adj3" },
+        { "mathDivide_0", "na|na|RefY|adj1" },
+        { "mathDivide_1", "na|na|RefY|adj2" },
+        { "mathDivide_2", "RefX|adj3|na|na" },
+        { "mathEqual_0", "na|na|RefY|adj1" },
+        { "mathEqual_1", "na|na|RefY|adj2" },
+        { "mathMinus_0", "na|na|RefY|adj1" },
+        { "mathMultiply_0", "na|na|RefY|adj1" },
+        { "mathNotEqual_0", "na|na|RefY|adj1" },
+        { "mathNotEqual_1", "na|na|RefAngle|adj2" },
+        { "mathNotEqual_2", "na|na|RefY|adj3" },
+        { "mathPlus_0", "na|na|RefY|adj1" },
+        { "moon_0", "RefX|adj|na|na" },
+        { "nonIsoscelesTrapezoid_0", "RefX|adj1|na|na" },
+        { "nonIsoscelesTrapezoid_1", "RefX|adj2|na|na" },
+        { "noSmoking_0", "RefR|adj|na|na" },
+        { "notchedRightArrow_0", "na|na|RefY|adj1" },
+        { "notchedRightArrow_1", "RefX|adj2|na|na" },
+        { "octagon_0", "RefX|adj|na|na" },
+        { "parallelogram_0", "RefX|adj|na|na" },
+        { "pie_0", "na|na|RefAngle|adj1" },
+        { "pie_1", "na|na|RefAngle|adj2" },
+        { "plaque_0", "RefX|adj|na|na" },
+        { "plus_0", "RefX|adj|na|na" },
+        { "quadArrow_0", "RefX|adj1|na|na" },
+        { "quadArrow_1", "RefX|adj2|na|na" },
+        { "quadArrow_2", "na|na|RefY|adj3" },
+        { "quadArrowCallout_0", "RefX|adj1|na|na" },
+        { "quadArrowCallout_1", "RefX|adj2|na|na" },
+        { "quadArrowCallout_2", "na|na|RefY|adj3" },
+        { "quadArrowCallout_3", "na|na|RefY|adj4" },
+        { "ribbon_0", "na|na|RefY|adj1" },
+        { "ribbon_1", "RefX|adj2|na|na" },
+        { "ribbon2_0", "na|na|RefY|adj1" },
+        { "ribbon2_1", "RefX|adj2|na|na" },
+        { "rightArrow_0", "na|na|RefY|adj1" },
+        { "rightArrow_1", "RefX|adj2|na|na" },
+        { "rightArrowCallout_0", "na|na|RefY|adj1" },
+        { "rightArrowCallout_1", "na|na|RefY|adj2" },
+        { "rightArrowCallout_2", "RefX|adj3|na|na" },
+        { "rightArrowCallout_3", "RefX|adj4|na|na" },
+        { "rightBrace_0", "na|na|RefY|adj1" },
+        { "rightBrace_1", "na|na|RefY|adj2" },
+        { "rightBracket_0", "na|na|RefY|adj" },
+        { "round1Rect_0", "RefX|adj|na|na" },
+        { "round2DiagRect_0", "RefX|adj1|na|na" },
+        { "round2DiagRect_1", "RefX|adj2|na|na" },
+        { "round2SameRect_0", "RefX|adj1|na|na" },
+        { "round2SameRect_1", "RefX|adj2|na|na" },
+        { "roundRect_0", "RefX|adj|na|na" },
+        { "smileyFace_0", "na|na|RefY|adj" },
+        { "snip1Rect_0", "RefX|adj|na|na" },
+        { "snip2DiagRect_0", "RefX|adj1|na|na" },
+        { "snip2DiagRect_1", "RefX|adj2|na|na" },
+        { "snip2SameRect_0", "RefX|adj1|na|na" },
+        { "snip2SameRect_1", "RefX|adj2|na|na" },
+        { "snipRoundRect_0", "RefX|adj1|na|na" },
+        { "snipRoundRect_1", "RefX|adj2|na|na" },
+        { "star10_0", "na|na|RefY|adj" },
+        { "star12_0", "na|na|RefY|adj" },
+        { "star16_0", "na|na|RefY|adj" },
+        { "star24_0", "na|na|RefY|adj" },
+        { "star32_0", "na|na|RefY|adj" },
+        { "star4_0", "na|na|RefY|adj" },
+        { "star5_0", "na|na|RefY|adj" },
+        { "star6_0", "na|na|RefY|adj" },
+        { "star7_0", "na|na|RefY|adj" },
+        { "star8_0", "na|na|RefY|adj" },
+        { "stripedRightArrow_0", "na|na|RefY|adj1" },
+        { "stripedRightArrow_1", "RefX|adj2|na|na" },
+        { "sun_0", "RefX|adj|na|na" },
+        { "swooshArrow_0", "na|na|RefY|adj1" },
+        { "swooshArrow_1", "RefX|adj2|na|na" },
+        { "teardrop_0", "RefX|adj|na|na" },
+        { "trapezoid_0", "RefX|adj|na|na" },
+        { "triangle_0", "RefX|adj|na|na" },
+        { "upArrowCallout_0", "RefX|adj1|na|na" },
+        { "upArrowCallout_1", "RefX|adj2|na|na" },
+        { "upArrowCallout_2", "na|na|RefY|adj3" },
+        { "upArrowCallout_3", "na|na|RefY|adj4" },
+        { "upDownArrow_0", "RefX|adj1|na|na" },
+        { "upDownArrow_1", "na|na|RefY|adj2" },
+        { "upArrow_0", "RefX|adj1|na|na" },
+        { "upArrow_1", "na|na|RefY|adj2" },
+        { "upDownArrowCallout_0", "RefX|adj1|na|na" },
+        { "upDownArrowCallout_1", "RefX|adj2|na|na" },
+        { "upDownArrowCallout_2", "na|na|RefY|adj3" },
+        { "upDownArrowCallout_3", "na|na|RefY|adj4" },
+        { "uturnArrow_0", "RefX|adj1|na|na" },
+        { "uturnArrow_1", "RefX|adj2|na|na" },
+        { "uturnArrow_2", "na|na|RefY|adj3" },
+        { "uturnArrow_3", "RefX|adj4|na|na" },
+        { "uturnArrow_4", "na|na|RefY|adj5" },
+        { "verticalScroll_0", "na|na|RefY|adj" },
+        { "wave_0", "na|na|RefY|adj1" },
+        { "wave_1", "RefX|adj2|na|na" },
+        { "wedgeEllipseCallout_0", "RefX|adj1|RefY|adj2" },
+        { "wedgeRectCallout_0", "RefX|adj1|RefY|adj2" },
+        { "wedgeRoundRectCallout_0", "RefX|adj1|RefY|adj2" } };
+}
+
+static sal_Int32 lcl_getAdjIndexFromToken(const sal_Int32& nTokenPos, const OUString& rMapValue)
+{
+    OUString sAdjRef = rMapValue.getToken(nTokenPos, '|');
+    OUString sNumber; // number part from "adj1", "adj2" etc.
+    if (sAdjRef.startsWith("adj", &sNumber))
+    {
+        if (sNumber.isEmpty() || sNumber == "1")
+            return 0;
+        else
+            return sNumber.toInt32() - 1;
+    }
+    else
+        return -1;
+}
+
+void PresetOOXHandleAdj::GetOOXHandleAdjRelation(
+    const OUString& sFullOOXShapeName, const sal_Int32 nHandleIndex, OUString& rFirstRefType,
+    sal_Int32& rFirstAdjValueIndex, OUString& rSecondRefType, sal_Int32& rSecondAdjValueIndex)
+{
+    static const HandleAdjRelHashMap s_HashMap = []() {
+        HandleAdjRelHashMap aH;
+        for (const auto& item : aHandleAdjRelArray)
+            aH[item.sShape_Handle] = item.sAdjReferences;
+        return aH;
+    }();
+
+    OUString sKey;
+    OUString sValue;
+    rFirstRefType = "na";
+    rFirstAdjValueIndex = -1;
+    rSecondRefType = "na";
+    rSecondAdjValueIndex = -1;
+    if (sFullOOXShapeName.startsWith("ooxml-", &sKey))
+    {
+        sKey = sKey + "_" + OUString::number(nHandleIndex);
+        HandleAdjRelHashMap::const_iterator aHashIter(s_HashMap.find(sKey));
+        if (aHashIter != s_HashMap.end())
+            sValue = (*aHashIter).second;
+        else
+            return;
+    }
+    else
+        return;
+
+    rFirstRefType = sValue.getToken(0, '|');
+    rFirstAdjValueIndex = lcl_getAdjIndexFromToken(1, sValue);
+    rSecondRefType = sValue.getToken(2, '|');
+    rSecondAdjValueIndex = lcl_getAdjIndexFromToken(3, sValue);
+    return;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/svx/source/svdraw/presetooxhandleadjustmentrelations.hxx b/svx/source/svdraw/presetooxhandleadjustmentrelations.hxx
new file mode 100644
index 000000000000..8bd2536f5d9e
--- /dev/null
+++ b/svx/source/svdraw/presetooxhandleadjustmentrelations.hxx
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SVX_SOURCE_SVDRAW_PRESETOOXHANDLEADJUSTMENTRELATIONS_HXX
+#define INCLUDED_SVX_SOURCE_SVDRAW_PRESETOOXHANDLEADJUSTMENTRELATIONS_HXX
+#include <rtl/ustring.hxx>
+
+namespace PresetOOXHandleAdj
+{
+/* This method is used in SdrObjCustomShape::MergeDefaultAttributes() */
+void GetOOXHandleAdjRelation(
+    const OUString& sFullOOXShapeName, /* e.g. "ooxml-circularArrow" */
+    const sal_Int32 nHandleIndex, /* index in sequence from property "Handles" */
+    OUString& rFirstRefType, /* Propertyname, same as by pptx import, e.g. "RefX" */
+    sal_Int32& rFirstAdjValueIndex, /* index in sequence from property "AdjustmentValues" */
+    OUString& rSecondRefType, /* Propertyname, same as by pptx import, e.g. "RefY" */
+    sal_Int32& rSecondAdjValueIndex /* index in sequence from property "AdjustmentValues" */
+);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 23ab67c9d1ae..843cf14fba12 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -32,6 +32,7 @@
 #include <com/sun/star/awt/Rectangle.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
 #include <svl/urihelper.hxx>
 #include <com/sun/star/uno/Sequence.h>
 #include <svx/svdogrp.hxx>
@@ -91,6 +92,7 @@
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <svdobjplusdata.hxx>
+#include "presetooxhandleadjustmentrelations.hxx"
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -1051,6 +1053,44 @@ void SdrObjCustomShape::MergeDefaultAttributes( const OUString* pType )
         aPropVal.Value <<= seqHandles;
         aGeometryItem.SetPropertyValue( aPropVal );
     }
+    else if (pAny && sShapeType.startsWith("ooxml-") && sShapeType != "ooxml-non-primitive")
+    {
+        // ODF is not able to store the ooxml way of connecting handle to an adjustment
+        // value by name, e.g. attribute RefX="adj". So the information is lost, when exporting
+        // a pptx to odp, for example. This part reconstructs this information for the
+        // ooxml preset shapes from their definition.
+        css::uno::Sequence<css::beans::PropertyValues> seqHandles;
+        *pAny >>= seqHandles;
+        bool bChanged(false);
+        for (sal_Int32 i = 0; i < seqHandles.getLength(); i++)
+        {
+            comphelper::SequenceAsHashMap aHandleProps(seqHandles[i]);
+            OUString sFirstRefType;
+            sal_Int32 nFirstAdjRef;
+            OUString sSecondRefType;
+            sal_Int32 nSecondAdjRef;
+            PresetOOXHandleAdj::GetOOXHandleAdjRelation(sShapeType, i, sFirstRefType, nFirstAdjRef,
+                                                        sSecondRefType, nSecondAdjRef);
+            if (sFirstRefType != "na" && 0 <= nFirstAdjRef
+                && nFirstAdjRef < seqAdjustmentValues.getLength())
+            {
+                bChanged |= aHandleProps.createItemIfMissing(sFirstRefType, nFirstAdjRef);
+            }
+            if (sSecondRefType != "na" && 0 <= nSecondAdjRef
+                && nSecondAdjRef < seqAdjustmentValues.getLength())
+            {
+                bChanged |= aHandleProps.createItemIfMissing(sSecondRefType, nSecondAdjRef);
+            }
+            aHandleProps >> seqHandles[i];
+        }
+        if (bChanged)
+        {
+            aPropVal.Name = sHandles;
+            aPropVal.Value <<= seqHandles;
+            aGeometryItem.SetPropertyValue(aPropVal);
+        }
+    }
+
     SetMergedItem( aGeometryItem );
 }
 


More information about the Libreoffice-commits mailing list