sw/source/core/crsr/contentcontrolbutton.cxx         |   18 ++++++++++++++++-
 sw/source/core/crsr/dropdowncontentcontrolbutton.cxx |    1 
 sw/source/core/crsr/viscrs.cxx                       |   20 ++++++++++++++++++-
 sw/source/core/inc/contentcontrolbutton.hxx          |    2 +
 4 files changed, 39 insertions(+), 2 deletions(-)

New commits:
commit e716ed8687a4eb99d9e8e1480dd7bfb2c872df7f
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Nov 11 08:46:32 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Nov 11 13:03:40 2022 +0100

    tdf#151980 sw content controls: fix RTL render of dropdowns
    
    - check if this widget is meant to be RTL in
      SwSelPaintRects::HighlightContentControl()
    
    - route RTLness to the underlying tree view / drop-down in
      SwDropDownContentControlButton::InitDropdown()
    
    - fix up SwContentControlButton (positioning, rendering, hit testing) to
      assume the button on the left of the first text portion in the RTL
      case
    
    Change-Id: I637ee8f08311e1273f8b19ddf3ab572af839760b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142577
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/source/core/crsr/contentcontrolbutton.cxx 
b/sw/source/core/crsr/contentcontrolbutton.cxx
index cd3deb5459bb..908d5f1bff01 100644
--- a/sw/source/core/crsr/contentcontrolbutton.cxx
+++ b/sw/source/core/crsr/contentcontrolbutton.cxx
@@ -71,6 +71,10 @@ void SwContentControlButton::CalcPosAndSize(const SwRect& 
rPortionPaintArea)
     m_aFramePixel = tools::Rectangle(aBoxPos, aBoxSize);
 
     // Then extend the size with the button area
+    if (m_bRTL)
+    {
+        
aBoxPos.AdjustX(-GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
+    }
     
aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
 
     if (aBoxPos != GetPosPixel() || aBoxSize != GetSizePixel())
@@ -112,7 +116,14 @@ void SwContentControlButton::Paint(vcl::RenderContext& 
rRenderContext, const too
 
     // Draw the button next to the frame
     Point aButtonPos(aFrameRect.TopLeft());
-    aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - nPadding * 2);
+    if (m_bRTL)
+    {
+        aButtonPos.AdjustX(nPadding * 2);
+    }
+    else
+    {
+        aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - nPadding * 2);
+    }
     Size aButtonSize(aFrameRect.GetSize());
     aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getOpenWidth() 
- nPadding);
     const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, 
aButtonSize));
@@ -153,6 +164,11 @@ WindowHitTest SwContentControlButton::ImplHitTest(const 
Point& rFramePos)
         return aResult;
     else
     {
+        if (m_bRTL)
+        {
+            return rFramePos.X() <= m_aFramePixel.Left() ? 
WindowHitTest::Inside
+                                                         : 
WindowHitTest::Transparent;
+        }
         return rFramePos.X() >= m_aFramePixel.Right() ? WindowHitTest::Inside
                                                       : 
WindowHitTest::Transparent;
     }
diff --git a/sw/source/core/crsr/dropdowncontentcontrolbutton.cxx 
b/sw/source/core/crsr/dropdowncontentcontrolbutton.cxx
index 14f1ba7e84b0..ba47c33f2607 100644
--- a/sw/source/core/crsr/dropdowncontentcontrolbutton.cxx
+++ b/sw/source/core/crsr/dropdowncontentcontrolbutton.cxx
@@ -42,6 +42,7 @@ void SwDropDownContentControlButton::InitDropdown()
     tools::Long nMinListWidth = GetSizePixel().Width();
     aSize.setWidth(std::max(aSize.Width(), nMinListWidth));
     m_xTreeView->set_size_request(aSize.Width(), aSize.Height());
+    m_xTreeView->set_direction(m_bRTL);
 }
 
 IMPL_LINK(SwDropDownContentControlButton, ListBoxHandler, weld::TreeView&, 
rBox, bool)
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 4d34e9b89d35..dd4db78517a4 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -637,6 +637,7 @@ void SwSelPaintRects::HighlightContentControl()
     std::vector<OString> aLOKRectangles;
     SwRect aFirstPortionPaintArea;
     SwRect aLastPortionPaintArea;
+    bool bRTL = false;
     std::shared_ptr<SwContentControl> pContentControl;
 
     if (m_bShowContentControlOverlay)
@@ -683,6 +684,15 @@ void SwSelPaintRects::HighlightContentControl()
                 aLastPortionPaintArea = (*pRects)[pRects->size() - 1];
             }
             pContentControl = 
pCurContentControlAtCursor->GetContentControl().GetContentControl();
+
+            // The layout knows if the text node is RTL (either set directly, 
or inherited from the
+            // environment).
+            SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> 
aFrames(*pTextNode);
+            SwTextFrame* pFrame = aFrames.First();
+            if (pFrame)
+            {
+                bRTL = pFrame->IsRightToLeft();
+            }
         }
     }
 
@@ -756,7 +766,15 @@ void SwSelPaintRects::HighlightContentControl()
                     m_pContentControlButton = 
VclPtr<SwDropDownContentControlButton>::Create(
                         &rEditWin, pContentControl);
                 }
-                m_pContentControlButton->CalcPosAndSize(aLastPortionPaintArea);
+                m_pContentControlButton->SetRTL(bRTL);
+                if (bRTL)
+                {
+                    
m_pContentControlButton->CalcPosAndSize(aFirstPortionPaintArea);
+                }
+                else
+                {
+                    
m_pContentControlButton->CalcPosAndSize(aLastPortionPaintArea);
+                }
                 m_pContentControlButton->Show();
             }
         }
diff --git a/sw/source/core/inc/contentcontrolbutton.hxx 
b/sw/source/core/inc/contentcontrolbutton.hxx
index 37da5ece669e..28b9e49c3057 100644
--- a/sw/source/core/inc/contentcontrolbutton.hxx
+++ b/sw/source/core/inc/contentcontrolbutton.hxx
@@ -25,6 +25,7 @@ public:
     virtual void dispose() override;
 
     void CalcPosAndSize(const SwRect& rPortionPaintArea);
+    void SetRTL(bool bRTL) { m_bRTL = bRTL; }
 
     virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
     DECL_LINK(PopupModeEndHdl, weld::Popover&, void);
@@ -46,6 +47,7 @@ protected:
     std::shared_ptr<SwContentControl> m_pContentControl;
     std::unique_ptr<weld::Builder> m_xPopupBuilder;
     std::unique_ptr<weld::Popover> m_xPopup;
+    bool m_bRTL = false;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to