summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-04-06 08:40:31 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-04-22 08:31:31 +0200
commit8fdb2baf5400f7225aa78d950fd53071950877e8 (patch)
tree3a1f73ace1482dcb5abf6c76acf723ca5c7a7107
parentb6f3fc87699c16db2ccc73f992bbcccfb60695bf (diff)
sw content controls: add overlay to render a border around the text portions
- introduce SwSelPaintRects::HighlightContentControl() to create the overlay - use GetTextAttrAt() to enable this when we're inside a content control (not only when the cursor is exactly at the dummy char of the content control, which is at the start) - tested that this works correctly even if the portions inside the content control don't have the same height (similar to the selection overlay) (cherry picked from commit c2999f9f3e0efa04f89055399f2d176c9c95e92d) Change-Id: I1db51cdb1ddc87c45740cd8677de645dc8906697 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133244 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--sw/inc/viscrs.hxx5
-rw-r--r--sw/source/core/crsr/crsrsh.cxx2
-rw-r--r--sw/source/core/crsr/viscrs.cxx78
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx1
4 files changed, 86 insertions, 0 deletions
diff --git a/sw/inc/viscrs.hxx b/sw/inc/viscrs.hxx
index 6755b548e8a0..2eb2f787fbc7 100644
--- a/sw/inc/viscrs.hxx
+++ b/sw/inc/viscrs.hxx
@@ -84,8 +84,11 @@ class SwSelPaintRects : public SwRects
bool m_bShowTextInputFieldOverlay;
std::unique_ptr<sw::overlay::OverlayRangesOutline> m_pTextInputFieldOverlay;
+ bool m_bShowContentControlOverlay;
+ std::unique_ptr<sw::overlay::OverlayRangesOutline> m_pContentControlOverlay;
void HighlightInputField();
+ void HighlightContentControl();
public:
SwSelPaintRects( const SwCursorShell& rCSh );
@@ -108,6 +111,8 @@ public:
m_bShowTextInputFieldOverlay = bShow;
}
+ void SetShowContentControlOverlay(const bool bShow) { m_bShowContentControlOverlay = bShow; }
+
const SwCursorShell* GetShell() const { return m_pCursorShell; }
// check current MapMode of the shell and set possibly the static members.
// Optional set the parameters pX, pY
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index ae7b2c81133d..4e9f54aab2e8 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -2393,6 +2393,7 @@ void SwCursorShell::ShowCursor()
m_bSVCursorVis = true;
m_pCurrentCursor->SetShowTextInputFieldOverlay( true );
+ m_pCurrentCursor->SetShowContentControlOverlay(true);
if (comphelper::LibreOfficeKit::isActive())
{
@@ -2413,6 +2414,7 @@ void SwCursorShell::HideCursor()
// possibly reverse selected areas!!
CurrShell aCurr( this );
m_pCurrentCursor->SetShowTextInputFieldOverlay( false );
+ m_pCurrentCursor->SetShowContentControlOverlay(false);
m_pVisibleCursor->Hide();
if (comphelper::LibreOfficeKit::isActive())
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 0501162a2a16..d72289bdbb36 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -59,6 +59,7 @@
#include <svtools/optionsdrawinglayer.hxx>
#include <cellfrm.hxx>
#include <wrtsh.hxx>
+#include <textcontentcontrol.hxx>
// Here static members are defined. They will get changed on alteration of the
// MapMode. This is done so that on ShowCursor the same size does not have to be
@@ -350,6 +351,7 @@ SwSelPaintRects::SwSelPaintRects( const SwCursorShell& rCSh )
: m_pCursorShell( &rCSh )
#if HAVE_FEATURE_DESKTOP
, m_bShowTextInputFieldOverlay(true)
+ , m_bShowContentControlOverlay(true)
#endif
{
}
@@ -368,6 +370,8 @@ void SwSelPaintRects::swapContent(SwSelPaintRects& rSwap)
std::swap(m_pCursorOverlay, rSwap.m_pCursorOverlay);
std::swap(m_bShowTextInputFieldOverlay, rSwap.m_bShowTextInputFieldOverlay);
std::swap(m_pTextInputFieldOverlay, rSwap.m_pTextInputFieldOverlay);
+ std::swap(m_bShowContentControlOverlay, rSwap.m_bShowContentControlOverlay);
+ std::swap(m_pContentControlOverlay, rSwap.m_pContentControlOverlay);
#endif
}
@@ -376,6 +380,7 @@ void SwSelPaintRects::Hide()
#if HAVE_FEATURE_DESKTOP
m_pCursorOverlay.reset();
m_pTextInputFieldOverlay.reset();
+ m_pContentControlOverlay.reset();
#endif
SwRects::clear();
@@ -466,6 +471,7 @@ void SwSelPaintRects::Show(std::vector<OString>* pSelectionRectangles)
}
HighlightInputField();
+ HighlightContentControl();
#endif
// Tiled editing does not expose the draw and writer cursor, it just
@@ -625,6 +631,78 @@ void SwSelPaintRects::HighlightInputField()
}
}
+void SwSelPaintRects::HighlightContentControl()
+{
+ std::vector<basegfx::B2DRange> aContentControlRanges;
+
+ if (m_bShowContentControlOverlay)
+ {
+ const SwPosition* pStart = GetShell()->GetCursor()->Start();
+ SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode();
+ SwTextContentControl* pCurContentControlAtCursor = nullptr;
+ if (pTextNode)
+ {
+ // SwTextNode::PARENT because this way we highlight when the cursor is on the right side
+ // of the dummy character: ideally the end of the range would have the same behavior.
+ SwTextAttr* pAttr = pTextNode->GetTextAttrAt(
+ pStart->nContent.GetIndex(), RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT);
+ if (pAttr)
+ {
+ pCurContentControlAtCursor = static_txtattr_cast<SwTextContentControl*>(pAttr);
+ }
+ }
+ if (pCurContentControlAtCursor)
+ {
+ auto pCursorForContentControl = std::make_unique<SwShellCursor>(
+ *GetShell(), SwPosition(*pTextNode, pCurContentControlAtCursor->GetStart()));
+ pCursorForContentControl->SetMark();
+ pCursorForContentControl->GetMark()->nNode = *pTextNode;
+ pCursorForContentControl->GetMark()->nContent.Assign(
+ pTextNode, *(pCurContentControlAtCursor->End()));
+
+ pCursorForContentControl->FillRects();
+ SwRects* pRects = pCursorForContentControl.get();
+ for (const auto& rRect : *pRects)
+ {
+ tools::Rectangle aRect(rRect.SVRect());
+
+ aContentControlRanges.emplace_back(aRect.Left(), aRect.Top(), aRect.Right() + 1,
+ aRect.Bottom() + 1);
+ }
+ }
+ }
+
+ if (!aContentControlRanges.empty())
+ {
+ if (m_pContentControlOverlay)
+ {
+ m_pContentControlOverlay->setRanges(std::move(aContentControlRanges));
+ }
+ else
+ {
+ SdrView* pView = const_cast<SdrView*>(GetShell()->GetDrawView());
+ SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
+ const rtl::Reference<sdr::overlay::OverlayManager>& xTargetOverlay
+ = pCandidate->GetOverlayManager();
+
+ if (xTargetOverlay.is())
+ {
+ // Use the system's highlight color with decreased luminance as highlight color.
+ Color aHighlight(SvtOptionsDrawinglayer::getHilightColor());
+ aHighlight.DecreaseLuminance(128);
+
+ m_pContentControlOverlay.reset(new sw::overlay::OverlayRangesOutline(
+ aHighlight, std::move(aContentControlRanges)));
+ xTargetOverlay->add(*m_pContentControlOverlay);
+ }
+ }
+ }
+ else
+ {
+ m_pContentControlOverlay.reset();
+ }
+}
+
void SwSelPaintRects::Invalidate( const SwRect& rRect )
{
size_type nSz = size();
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 4d109a8add1c..e5040c50a1a7 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1715,6 +1715,7 @@ SwTextNode::GetTextAttrAt(sal_Int32 const nIndex, sal_uInt16 const nWhich,
|| (nWhich == RES_TXTATR_INETFMT)
|| (nWhich == RES_TXTATR_CJK_RUBY)
|| (nWhich == RES_TXTATR_UNKNOWN_CONTAINER)
+ || (nWhich == RES_TXTATR_CONTENTCONTROL)
|| (nWhich == RES_TXTATR_INPUTFIELD ) );
// "GetTextAttrAt() will give wrong result for this hint!")