summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-10-25 15:27:58 +0000
committerCaolán McNamara <caolanm@redhat.com>2020-10-27 17:00:59 +0100
commitb9405fbc4e19901c78d136895c5ab0437d8450ac (patch)
treef42d180c9f6b4450959ff94d6f40a2ae881d8984 /vcl/source
parent23c30c073495201acb82e6e2e83bb0840f25acce (diff)
Resolves: tdf#137620 add DeleteSurroundingText at vcl::Window level
a) give it a default implementation based on the current one b) re-use code introduced for WeldEditView::DeleteSurroundingText for the EditView containing vcl::Window in impress/draw and various similar Annotation windows Change-Id: I55547c70e90ee394795b5545450cf8131538fad8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104781 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/app/salvtables.cxx7
-rw-r--r--vcl/source/control/edit.cxx10
-rw-r--r--vcl/source/window/layout.cxx20
-rw-r--r--vcl/source/window/window.cxx60
-rw-r--r--vcl/source/window/winproc.cxx20
5 files changed, 110 insertions, 7 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 26e382af0536..303907501e96 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -5848,6 +5848,7 @@ SalInstanceDrawingArea::SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, Sal
m_xDrawingArea->SetCommandHdl(LINK(this, SalInstanceDrawingArea, CommandHdl));
m_xDrawingArea->SetQueryTooltipHdl(LINK(this, SalInstanceDrawingArea, QueryTooltipHdl));
m_xDrawingArea->SetGetSurroundingHdl(LINK(this, SalInstanceDrawingArea, GetSurroundingHdl));
+ m_xDrawingArea->SetDeleteSurroundingHdl(LINK(this, SalInstanceDrawingArea, DeleteSurroundingHdl));
m_xDrawingArea->SetStartDragHdl(LINK(this, SalInstanceDrawingArea, StartDragHdl));
}
@@ -5941,6 +5942,7 @@ void SalInstanceDrawingArea::enable_drag_source(rtl::Reference<TransferDataConta
SalInstanceDrawingArea::~SalInstanceDrawingArea()
{
+ m_xDrawingArea->SetDeleteSurroundingHdl(Link<const Selection&, bool>());
m_xDrawingArea->SetGetSurroundingHdl(Link<OUString&, int>());
m_xDrawingArea->SetQueryTooltipHdl(Link<tools::Rectangle&, OUString>());
m_xDrawingArea->SetCommandHdl(Link<const CommandEvent&, bool>());
@@ -6017,6 +6019,11 @@ IMPL_LINK(SalInstanceDrawingArea, GetSurroundingHdl, OUString&, rSurrounding, in
return m_aGetSurroundingHdl.Call(rSurrounding);
}
+IMPL_LINK(SalInstanceDrawingArea, DeleteSurroundingHdl, const Selection&, rSelection, bool)
+{
+ return m_aDeleteSurroundingHdl.Call(rSelection);
+}
+
IMPL_LINK(SalInstanceDrawingArea, QueryTooltipHdl, tools::Rectangle&, rHelpArea, OUString)
{
return m_aQueryTooltipHdl.Call(rHelpArea);
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index 18f4fb70ee66..27eaddaf1949 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -2908,7 +2908,15 @@ OUString Edit::GetSurroundingText() const
Selection Edit::GetSurroundingTextSelection() const
{
- return GetSelection();
+ return GetSelection();
+}
+
+bool Edit::DeleteSurroundingText(const Selection& rSelection)
+{
+ SetSelection(rSelection);
+ DeleteSelected();
+ // maybe we should update mpIMEInfos here
+ return true;
}
FactoryFunction Edit::GetUITestFactory() const
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 36ebf51a74ff..4c98d7a88ad5 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2859,19 +2859,27 @@ void VclDrawingArea::StartDrag(sal_Int8, const Point&)
OUString VclDrawingArea::GetSurroundingText() const
{
+ if (!m_aGetSurroundingHdl.IsSet())
+ return Control::GetSurroundingText();
OUString sSurroundingText;
- if (m_aGetSurroundingHdl.Call(sSurroundingText) != -1)
- return sSurroundingText;
- return Control::GetSurroundingText();
+ m_aGetSurroundingHdl.Call(sSurroundingText);
+ return sSurroundingText;
}
Selection VclDrawingArea::GetSurroundingTextSelection() const
{
+ if (!m_aGetSurroundingHdl.IsSet())
+ return Control::GetSurroundingTextSelection();
OUString sSurroundingText;
int nCursor = m_aGetSurroundingHdl.Call(sSurroundingText);
- if (nCursor != -1)
- return Selection(nCursor, nCursor);
- return Control::GetSurroundingTextSelection();
+ return Selection(nCursor, nCursor);
+}
+
+bool VclDrawingArea::DeleteSurroundingText(const Selection& rSelection)
+{
+ if (!m_aDeleteSurroundingHdl.IsSet())
+ return Control::DeleteSurroundingText(rSelection);
+ return m_aDeleteSurroundingHdl.Call(rSelection);
}
VclHPaned::~VclHPaned()
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 447cd0112cca..2d9cfd5966cd 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -21,6 +21,7 @@
#include <sal/log.hxx>
#include <sal/types.h>
+#include <tools/diagnose_ex.h>
#include <vcl/salgtype.hxx>
#include <vcl/event.hxx>
#include <vcl/help.hxx>
@@ -57,6 +58,7 @@
#include <com/sun/star/accessibility/AccessibleRelation.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
@@ -3771,6 +3773,64 @@ Selection Window::GetSurroundingTextSelection() const
return Selection( 0, 0 );
}
+namespace
+{
+ using namespace com::sun::star;
+
+ uno::Reference<accessibility::XAccessibleEditableText> lcl_GetxText(vcl::Window *pFocusWin)
+ {
+ uno::Reference<accessibility::XAccessibleEditableText> xText;
+ try
+ {
+ uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible() );
+ if (xAccessible.is())
+ xText = FindFocusedEditableText(xAccessible->getAccessibleContext());
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "vcl.gtk3", "Exception in getting input method surrounding text");
+ }
+ return xText;
+ }
+}
+
+// this is a rubbish implementation using a11y, ideally all subclasses implementing
+// GetSurroundingText/GetSurroundingTextSelection should implement this and then this
+// should be removed in favor of a stub that returns false
+bool Window::DeleteSurroundingText(const Selection& rSelection)
+{
+ uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(this);
+ if (xText.is())
+ {
+ sal_Int32 nPosition = xText->getCaretPosition();
+ // #i111768# range checking
+ sal_Int32 nDeletePos = rSelection.Min();
+ sal_Int32 nDeleteEnd = rSelection.Max();
+ if (nDeletePos < 0)
+ nDeletePos = 0;
+ if (nDeleteEnd < 0)
+ nDeleteEnd = 0;
+ if (nDeleteEnd > xText->getCharacterCount())
+ nDeleteEnd = xText->getCharacterCount();
+
+ xText->deleteText(nDeletePos, nDeleteEnd);
+ //tdf91641 adjust cursor if deleted chars shift it forward (normal case)
+ if (nDeletePos < nPosition)
+ {
+ if (nDeleteEnd <= nPosition)
+ nPosition = nPosition - (nDeleteEnd - nDeletePos);
+ else
+ nPosition = nDeletePos;
+
+ if (xText->getCharacterCount() >= nPosition)
+ xText->setCaretPosition( nPosition );
+ }
+ return true;
+ }
+
+ return false;
+}
+
bool Window::UsePolyPolygonForComplexGradient()
{
return meRasterOp != RasterOp::OverPaint;
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 39b76a85b100..aab2cb21bb21 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -2274,6 +2274,23 @@ static void ImplHandleSalSurroundingTextRequest( vcl::Window *pWindow,
pEvt->mnEnd = aSelRange.Max();
}
+static void ImplHandleSalDeleteSurroundingTextRequest( vcl::Window *pWindow,
+ SalSurroundingTextSelectionChangeEvent *pEvt )
+{
+ vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
+
+ Selection aSelection(pEvt->mnStart, pEvt->mnEnd);
+ if (pChild && pChild->DeleteSurroundingText(aSelection))
+ {
+ pEvt->mnStart = aSelection.Min();
+ pEvt->mnEnd = aSelection.Max();
+ }
+ else
+ {
+ pEvt->mnStart = pEvt->mnEnd = SAL_MAX_UINT32;
+ }
+}
+
static void ImplHandleSurroundingTextSelectionChange( vcl::Window *pWindow,
sal_uLong nStart,
sal_uLong nEnd )
@@ -2569,6 +2586,9 @@ bool ImplWindowFrameProc( vcl::Window* _pWindow, SalEvent nEvent, const void* pE
case SalEvent::SurroundingTextRequest:
ImplHandleSalSurroundingTextRequest( pWindow, const_cast<SalSurroundingTextRequestEvent *>(static_cast<SalSurroundingTextRequestEvent const *>(pEvent)) );
break;
+ case SalEvent::DeleteSurroundingTextRequest:
+ ImplHandleSalDeleteSurroundingTextRequest( pWindow, const_cast<SalSurroundingTextSelectionChangeEvent *>(static_cast<SalSurroundingTextSelectionChangeEvent const *>(pEvent)) );
+ break;
case SalEvent::SurroundingTextSelectionChange:
{
SalSurroundingTextSelectionChangeEvent const * pEvt