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 <vmiklos@collabora.com>
Tested-by: Jenkins
diff --git a/sw/source/core/crsr/contentcontrolbutton.cxx b/sw/source/core/crsr/contentcontrolbutton.cxx
index cd3deb5..908d5f1 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 14f1ba7..ba47c33 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 4d34e9b..dd4db78 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 37da5ec..28b9e49 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: */