[Libreoffice-commits] core.git: vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Tue Jun 8 18:47:23 UTC 2021


 vcl/unx/gtk4/convert3to4.cxx |  195 +++++++++++++++++++++++++------------------
 vcl/unx/gtk4/convert3to4.hxx |   16 +++
 2 files changed, 133 insertions(+), 78 deletions(-)

New commits:
commit 130d097df4b324e3465723192833aaa68cc00a10
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jun 8 15:55:40 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Jun 8 20:46:35 2021 +0200

    gtk4: expand the first child of the end group
    
    if there are start group entries
    
    Change-Id: I91188b0e5961a53730f6e157e8ea9be6b69ff92d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116851
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/unx/gtk4/convert3to4.cxx b/vcl/unx/gtk4/convert3to4.cxx
index 8aef3470defa..a5282b0cece7 100644
--- a/vcl/unx/gtk4/convert3to4.cxx
+++ b/vcl/unx/gtk4/convert3to4.cxx
@@ -59,6 +59,16 @@ bool ToplevelIsMessageDialog(const css::uno::Reference<css::xml::dom::XNode>& xN
     return false;
 }
 
+void insertAsFirstChild(const css::uno::Reference<css::xml::dom::XNode>& xParentNode,
+                        const css::uno::Reference<css::xml::dom::XNode>& xChildNode)
+{
+    auto xFirstChild = xParentNode->getFirstChild();
+    if (xFirstChild.is())
+        xParentNode->insertBefore(xChildNode, xFirstChild);
+    else
+        xParentNode->appendChild(xChildNode);
+}
+
 void SetPropertyOnTopLevel(const css::uno::Reference<css::xml::dom::XNode>& xNode,
                            const css::uno::Reference<css::xml::dom::XNode>& xProperty)
 {
@@ -72,12 +82,7 @@ void SetPropertyOnTopLevel(const css::uno::Reference<css::xml::dom::XNode>& xNod
             css::uno::Reference<css::xml::dom::XNode> xClass = xObjectMap->getNamedItem("class");
             if (xClass->getNodeValue() == "GtkDialog")
             {
-                auto xFirstChild = xObjectCandidate->getFirstChild();
-                if (xFirstChild.is())
-                    xObjectCandidate->insertBefore(xProperty, xFirstChild);
-                else
-                    xObjectCandidate->appendChild(xProperty);
-
+                insertAsFirstChild(xObjectCandidate, xProperty);
                 break;
             }
         }
@@ -93,6 +98,18 @@ OUString GetParentObjectType(const css::uno::Reference<css::xml::dom::XNode>& xN
     return xClass->getNodeValue();
 }
 
+css::uno::Reference<css::xml::dom::XNode>
+GetChildObject(const css::uno::Reference<css::xml::dom::XNode>& xChild)
+{
+    for (css::uno::Reference<css::xml::dom::XNode> xObjectCandidate = xChild->getFirstChild();
+         xObjectCandidate.is(); xObjectCandidate = xObjectCandidate->getNextSibling())
+    {
+        if (xObjectCandidate->getNodeName() == "object")
+            return xObjectCandidate;
+    }
+    return nullptr;
+}
+
 // currently runs the risk of duplicate margin-* properties if there was already such as well
 // as the border
 void AddBorderAsMargins(const css::uno::Reference<css::xml::dom::XNode>& xNode,
@@ -101,13 +118,7 @@ void AddBorderAsMargins(const css::uno::Reference<css::xml::dom::XNode>& xNode,
     auto xDoc = xNode->getOwnerDocument();
 
     auto xMarginEnd = CreateProperty(xDoc, "margin-end", rBorderWidth);
-
-    auto xFirstChild = xNode->getFirstChild();
-    if (xFirstChild.is())
-        xNode->insertBefore(xMarginEnd, xFirstChild);
-    else
-        xNode->appendChild(xMarginEnd);
-
+    insertAsFirstChild(xNode, xMarginEnd);
     xNode->insertBefore(CreateProperty(xDoc, "margin-top", rBorderWidth), xMarginEnd);
     xNode->insertBefore(CreateProperty(xDoc, "margin-bottom", rBorderWidth), xMarginEnd);
     xNode->insertBefore(CreateProperty(xDoc, "margin-start", rBorderWidth), xMarginEnd);
@@ -258,16 +269,18 @@ struct ConvertResult
     bool m_bHasSymbolicIconName;
     bool m_bAlwaysShowImage;
     bool m_bUseUnderline;
+    bool m_bVertOrientation;
     css::uno::Reference<css::xml::dom::XNode> m_xPropertyLabel;
 
     ConvertResult(bool bChildCanFocus, bool bHasVisible, bool bHasSymbolicIconName,
-                  bool bAlwaysShowImage, bool bUseUnderline,
+                  bool bAlwaysShowImage, bool bUseUnderline, bool bVertOrientation,
                   const css::uno::Reference<css::xml::dom::XNode>& rPropertyLabel)
         : m_bChildCanFocus(bChildCanFocus)
         , m_bHasVisible(bHasVisible)
         , m_bHasSymbolicIconName(bHasSymbolicIconName)
         , m_bAlwaysShowImage(bAlwaysShowImage)
         , m_bUseUnderline(bUseUnderline)
+        , m_bVertOrientation(bVertOrientation)
         , m_xPropertyLabel(rPropertyLabel)
     {
     }
@@ -283,7 +296,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
 {
     css::uno::Reference<css::xml::dom::XNodeList> xNodeList = xNode->getChildNodes();
     if (!xNodeList.is())
-        return ConvertResult(false, false, false, false, false, nullptr);
+        return ConvertResult(false, false, false, false, false, false, nullptr);
 
     std::vector<css::uno::Reference<css::xml::dom::XNode>> xRemoveList;
 
@@ -293,6 +306,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
     bool bHasSymbolicIconName = false;
     bool bAlwaysShowImage = false;
     bool bUseUnderline = false;
+    bool bVertOrientation = false;
     css::uno::Reference<css::xml::dom::XNode> xPropertyLabel;
     css::uno::Reference<css::xml::dom::XNode> xCantFocus;
 
@@ -493,6 +507,9 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
             if (sName == "use-underline")
                 bUseUnderline = toBool(xChild->getFirstChild()->getNodeValue());
 
+            if (sName == "orientation")
+                bVertOrientation = xChild->getFirstChild()->getNodeValue() == "vertical";
+
             if (sName == "relief")
             {
                 if (GetParentObjectType(xChild) == "GtkToggleButton"
@@ -684,28 +701,18 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
 
             if (bContentArea)
             {
-                for (css::uno::Reference<css::xml::dom::XNode> xObjectCandidate
-                     = xChild->getFirstChild();
-                     xObjectCandidate.is(); xObjectCandidate = xObjectCandidate->getNextSibling())
+                css::uno::Reference<css::xml::dom::XNode> xObject = GetChildObject(xChild);
+                if (xObject)
                 {
-                    if (xObjectCandidate->getNodeName() == "object")
-                    {
-                        auto xDoc = xChild->getOwnerDocument();
-
-                        auto xVExpand = CreateProperty(xDoc, "vexpand", "True");
-                        auto xFirstChild = xObjectCandidate->getFirstChild();
-                        if (xFirstChild.is())
-                            xObjectCandidate->insertBefore(xVExpand, xFirstChild);
-                        else
-                            xObjectCandidate->appendChild(xVExpand);
+                    auto xDoc = xChild->getOwnerDocument();
 
-                        if (!sBorderWidth.isEmpty())
-                        {
-                            AddBorderAsMargins(xObjectCandidate, sBorderWidth);
-                            sBorderWidth.clear();
-                        }
+                    auto xVExpand = CreateProperty(xDoc, "vexpand", "True");
+                    insertAsFirstChild(xObject, xVExpand);
 
-                        break;
+                    if (!sBorderWidth.isEmpty())
+                    {
+                        AddBorderAsMargins(xObject, sBorderWidth);
+                        sBorderWidth.clear();
                     }
                 }
             }
@@ -788,16 +795,9 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
                 // go back to parent and find the object child and insert this "layout" as a
                 // new child of the object
                 auto xParent = xChild->getParentNode();
-                for (css::uno::Reference<css::xml::dom::XNode> xObjectCandidate
-                     = xParent->getFirstChild();
-                     xObjectCandidate.is(); xObjectCandidate = xObjectCandidate->getNextSibling())
-                {
-                    if (xObjectCandidate->getNodeName() == "object")
-                    {
-                        xObjectCandidate->appendChild(xNew);
-                        break;
-                    }
-                }
+                css::uno::Reference<css::xml::dom::XNode> xObject = GetChildObject(xParent);
+                if (xObject)
+                    xObject->appendChild(xNew);
             }
 
             xRemoveList.push_back(xChild);
@@ -819,6 +819,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
         bool bChildHasVisible = false;
         bool bChildAlwaysShowImage = false;
         bool bChildUseUnderline = false;
+        bool bChildVertOrientation = false;
         css::uno::Reference<css::xml::dom::XNode> xChildPropertyLabel;
         if (xChild->hasChildNodes())
         {
@@ -835,6 +836,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
                 bChildHasSymbolicIconName = aChildRes.m_bHasSymbolicIconName;
                 bChildAlwaysShowImage = aChildRes.m_bAlwaysShowImage;
                 bChildUseUnderline = aChildRes.m_bUseUnderline;
+                bChildVertOrientation = aChildRes.m_bVertOrientation;
                 xChildPropertyLabel = aChildRes.m_xPropertyLabel;
             }
         }
@@ -871,11 +873,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
 
                 {
                     auto xVisible = CreateProperty(xDoc, "visible", "False");
-                    auto xFirstChild = xChild->getFirstChild();
-                    if (xFirstChild.is())
-                        xChild->insertBefore(xVisible, xFirstChild);
-                    else
-                        xChild->appendChild(xVisible);
+                    insertAsFirstChild(xChild, xVisible);
                 }
             }
 
@@ -886,11 +884,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
                 {
                     xClass->setNodeValue("GtkHeaderBar");
                     auto xSpacingNode = CreateProperty(xDoc, "show-title-buttons", "False");
-                    auto xFirstChild = xChild->getFirstChild();
-                    if (xFirstChild.is())
-                        xChild->insertBefore(xSpacingNode, xFirstChild);
-                    else
-                        xChild->appendChild(xSpacingNode);
+                    insertAsFirstChild(xChild, xSpacingNode);
 
                     // move the replacement GtkHeaderBar up to before the content_area
                     auto xContentAreaCandidate = xChild->getParentNode();
@@ -928,20 +922,15 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
                                 {
                                     OUString sNodeId;
 
-                                    for (css::uno::Reference<css::xml::dom::XNode> xObjectCandidate
-                                         = xTitleChild->getFirstChild();
-                                         xObjectCandidate.is();
-                                         xObjectCandidate = xObjectCandidate->getNextSibling())
+                                    css::uno::Reference<css::xml::dom::XNode> xObject
+                                        = GetChildObject(xTitleChild);
+                                    if (xObject)
                                     {
-                                        if (xObjectCandidate->getNodeName() == "object")
-                                        {
-                                            css::uno::Reference<css::xml::dom::XNamedNodeMap>
-                                                xObjectMap = xObjectCandidate->getAttributes();
-                                            css::uno::Reference<css::xml::dom::XNode> xObjectId
-                                                = xObjectMap->getNamedItem("id");
-                                            sNodeId = xObjectId->getNodeValue();
-                                            break;
-                                        }
+                                        css::uno::Reference<css::xml::dom::XNamedNodeMap> xObjectMap
+                                            = xObject->getAttributes();
+                                        css::uno::Reference<css::xml::dom::XNode> xObjectId
+                                            = xObjectMap->getNamedItem("id");
+                                        sNodeId = xObjectId->getNodeValue();
                                     }
 
                                     aChildren.push_back(std::make_pair(xTitleChild, sNodeId));
@@ -1011,7 +1000,8 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
             else if (sClass == "GtkBox")
             {
                 // reverse the order of the pack-type=end widgets
-                std::vector<css::uno::Reference<css::xml::dom::XNode>> xPackEnds;
+                std::vector<css::uno::Reference<css::xml::dom::XNode>> aPackEnds;
+                std::vector<css::uno::Reference<css::xml::dom::XNode>> aPackStarts;
                 css::uno::Reference<css::xml::dom::XNode> xBoxChild = xChild->getFirstChild();
                 while (xBoxChild.is())
                 {
@@ -1024,16 +1014,69 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
                         css::uno::Reference<css::xml::dom::XNode> xType
                             = xBoxChildMap->getNamedItem("type");
                         if (xType && xType->getNodeValue() == "end")
-                            xPackEnds.push_back(xChild->removeChild(xBoxChild));
+                            aPackEnds.push_back(xChild->removeChild(xBoxChild));
+                        else
+                            aPackStarts.push_back(xBoxChild);
                     }
 
                     xBoxChild = xNextBoxChild;
                 }
 
-                std::reverse(xPackEnds.begin(), xPackEnds.end());
+                if (!aPackEnds.empty())
+                {
+                    std::reverse(aPackEnds.begin(), aPackEnds.end());
 
-                for (auto& xPackEnd : xPackEnds)
-                    xChild->appendChild(xPackEnd);
+                    if (!bChildVertOrientation)
+                    {
+                        bool bHasStartObject = false;
+                        bool bLastStartExpands = false;
+                        if (!aPackStarts.empty())
+                        {
+                            css::uno::Reference<css::xml::dom::XNode> xLastStartObject;
+                            for (auto it = aPackStarts.rbegin(); it != aPackStarts.rend(); ++it)
+                            {
+                                xLastStartObject = GetChildObject(*it);
+                                if (xLastStartObject.is())
+                                {
+                                    bHasStartObject = true;
+                                    for (css::uno::Reference<css::xml::dom::XNode> xExpandCandidate
+                                         = xLastStartObject->getFirstChild();
+                                         xExpandCandidate.is();
+                                         xExpandCandidate = xExpandCandidate->getNextSibling())
+                                    {
+                                        if (xExpandCandidate->getNodeName() == "property")
+                                        {
+                                            css::uno::Reference<css::xml::dom::XNamedNodeMap>
+                                                xExpandMap = xExpandCandidate->getAttributes();
+                                            css::uno::Reference<css::xml::dom::XNode> xName
+                                                = xExpandMap->getNamedItem("name");
+                                            OUString sPropName(xName->getNodeValue());
+                                            if (sPropName == "hexpand")
+                                            {
+                                                bLastStartExpands
+                                                    = toBool(xExpandCandidate->getFirstChild()
+                                                                 ->getNodeValue());
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+
+                        if (bHasStartObject && !bLastStartExpands)
+                        {
+                            auto xAlign = CreateProperty(xDoc, "halign", "end");
+                            insertAsFirstChild(GetChildObject(aPackEnds[0]), xAlign);
+                            auto xExpand = CreateProperty(xDoc, "hexpand", "True");
+                            insertAsFirstChild(GetChildObject(aPackEnds[0]), xExpand);
+                        }
+                    }
+
+                    for (auto& xPackEnd : aPackEnds)
+                        xChild->appendChild(xPackEnd);
+                }
             }
             else if (sClass == "GtkRadioButton")
             {
@@ -1046,11 +1089,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
             else if (sClass == "GtkPopover" && !bHasVisible)
             {
                 auto xVisible = CreateProperty(xDoc, "visible", "False");
-                auto xFirstChild = xChild->getFirstChild();
-                if (xFirstChild.is())
-                    xChild->insertBefore(xVisible, xFirstChild);
-                else
-                    xChild->appendChild(xVisible);
+                insertAsFirstChild(xChild, xVisible);
             }
             else if (sClass == "GtkMenu")
             {
@@ -1142,7 +1181,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
         xNode->removeChild(xRemove);
 
     return ConvertResult(bChildCanFocus, bHasVisible, bHasSymbolicIconName, bAlwaysShowImage,
-                         bUseUnderline, xPropertyLabel);
+                         bUseUnderline, bVertOrientation, xPropertyLabel);
 }
 }
 
diff --git a/vcl/unx/gtk4/convert3to4.hxx b/vcl/unx/gtk4/convert3to4.hxx
new file mode 100644
index 000000000000..d75d9fd910f9
--- /dev/null
+++ b/vcl/unx/gtk4/convert3to4.hxx
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 <gtk/gtk.h>
+
+// convert gtk3 .ui to gtk4 and load it
+void builder_add_from_gtk3_file(GtkBuilder* pBuilder, const OUString& rUri);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list