[Libreoffice-commits] core.git: oox/source sd/qa

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Jan 17 11:47:55 UTC 2019


 oox/source/drawingml/diagram/diagramlayoutatoms.cxx |   53 +++++++++++++++++++-
 sd/qa/unit/import-tests-smartart.cxx                |    6 ++
 2 files changed, 57 insertions(+), 2 deletions(-)

New commits:
commit 3a655975e5ea43417885513d0752da3627dd25ed
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Jan 17 11:22:28 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Thu Jan 17 12:47:30 2019 +0100

    oox smartart, org chart: improve width of non-manager nodes
    
    The default case is that all managers have assistants/employees, so
    nodes under a manager can only use the horizontal space under the
    manager to avoid overlapping.
    
    But in case the previous / next sibling of the manager have no child
    nodes (assistant/employee) then we can use that space to make the child
    nodes larger. This improves readability of the chart's text a lot and
    brings the layout closer to what PowerPoint does for the same input.
    
    Handle all this in the hierChild algorithm, i.e. the container for a
    list of assistants or a list of employees, which means "parent" in this
    context always refers to a manager node.
    
    Change-Id: Ib4125ea2a113339ab7bbcd78e43c5d204f442996
    Reviewed-on: https://gerrit.libreoffice.org/66504
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 1e68896b1e9c..fc5b1c059410 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -117,6 +117,49 @@ bool containsDataNodeType(const oox::drawingml::ShapePtr& pShape, sal_Int32 nTyp
 
     return false;
 }
+
+/**
+ * Calculates the offset and scaling for pShape (laid out with the hierChild
+ * algorithm) based on the siblings of pParent.
+ */
+void calculateHierChildOffsetScale(const oox::drawingml::ShapePtr& pShape,
+                                   const oox::drawingml::LayoutNode* pParent, sal_Int32& rXOffset,
+                                   double& rWidthScale)
+{
+    if (!pParent)
+        return;
+
+    const std::vector<oox::drawingml::ShapePtr>& rParents = pParent->getNodeShapes();
+    for (size_t nParent = 0; nParent < rParents.size(); ++nParent)
+    {
+        const oox::drawingml::ShapePtr& pParentShape = rParents[nParent];
+        const std::vector<oox::drawingml::ShapePtr>& rChildren = pParentShape->getChildren();
+        auto it = std::find_if(
+            rChildren.begin(), rChildren.end(),
+            [pShape](const oox::drawingml::ShapePtr& pChild) { return pChild == pShape; });
+        if (it == rChildren.end())
+            // This is not our parent.
+            continue;
+
+        if (nParent > 0)
+        {
+            if (rParents[nParent - 1]->getChildren().size() == 1)
+            {
+                // Previous sibling of our parent has no children: can use that
+                // space, so shift to the left and scale up.
+                rWidthScale += 1.0;
+                rXOffset -= pShape->getSize().Width;
+            }
+        }
+        if (nParent < rParents.size() - 1)
+        {
+            if (rParents[nParent + 1]->getChildren().size() == 1)
+                // Next sibling of our parent has no children: can use that
+                // space, so scale up.
+                rWidthScale += 1.0;
+        }
+    }
+}
 }
 
 namespace oox { namespace drawingml {
@@ -568,16 +611,22 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
                     std::swap(rChildren[1], rChildren[2]);
             }
 
+            sal_Int32 nXOffset = 0;
+            double fWidthScale = 1.0;
+            if (mnType == XML_hierChild)
+                calculateHierChildOffsetScale(rShape, pParent, nXOffset, fWidthScale);
+
             awt::Size aChildSize = rShape->getSize();
             if (nDir == XML_fromT)
             {
                 aChildSize.Height /= nCount;
-                aChildSize.Height *= fHeightScale;
             }
             else
                 aChildSize.Width /= nCount;
+            aChildSize.Height *= fHeightScale;
+            aChildSize.Width *= fWidthScale;
 
-            awt::Point aChildPos(0, 0);
+            awt::Point aChildPos(nXOffset, 0);
             for (auto& pChild : rShape->getChildren())
             {
                 pChild->setPosition(aChildPos);
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index 66fdfbc254cd..846a95ee6738 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -739,6 +739,7 @@ void SdImportTestSmartArt::testOrgChart()
     CPPUNIT_ASSERT(xEmployeeShape.is());
 
     awt::Point aEmployeePos = xEmployeeShape->getPosition();
+    awt::Size aEmployeeSize = xEmployeeShape->getSize();
 
     CPPUNIT_ASSERT_EQUAL(aManagerPos.X, aEmployeePos.X);
 
@@ -760,6 +761,7 @@ void SdImportTestSmartArt::testOrgChart()
     CPPUNIT_ASSERT(xEmployee2Shape.is());
 
     awt::Point aEmployee2Pos = xEmployee2Shape->getPosition();
+    awt::Size aEmployee2Size = xEmployee2Shape->getSize();
     CPPUNIT_ASSERT_GREATER(aEmployeePos.X, aEmployee2Pos.X);
 
     // Make sure that assistant is above employees.
@@ -791,6 +793,10 @@ void SdImportTestSmartArt::testOrgChart()
     // xManager2's height was 3 times larger than xManager's height.
     CPPUNIT_ASSERT_EQUAL(aManagerSize.Height, aManager2Size.Height);
 
+    // Make sure the employee nodes use the free space on the right, since
+    // manager2 has no assistants / employees.
+    CPPUNIT_ASSERT_GREATER(aManagerSize.Width, aEmployeeSize.Width + aEmployee2Size.Width);
+
     xDocShRef->DoClose();
 }
 


More information about the Libreoffice-commits mailing list