tdf#134566 accept input engine commands in editview in custom widget

for the generic case first

Change-Id: I10bd707900b54c70c9bda79d5d09532cc159779e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103692
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
(cherry picked from commit 31342a1bda26f4e3dd29274dafd306fd0a9e7047)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103720
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index 3ea3ac4..7c6698f 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -169,12 +169,12 @@ EditView::~EditView()
{
}

void EditView::setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks)
void EditView::setEditViewCallbacks(EditViewCallbacks* pEditViewCallbacks)
{
    pImpEditView->setEditViewCallbacks(pEditViewCallbacks);
}

const EditViewCallbacks* EditView::getEditViewCallbacks() const
EditViewCallbacks* EditView::getEditViewCallbacks() const
{
    return pImpEditView->getEditViewCallbacks();
}
@@ -207,7 +207,7 @@ tools::Rectangle EditView::GetInvalidateRect() const

void EditView::InvalidateWindow(const tools::Rectangle& rClipRect)
{
    if (const EditViewCallbacks* pEditViewCallbacks = pImpEditView->getEditViewCallbacks())
    if (EditViewCallbacks* pEditViewCallbacks = pImpEditView->getEditViewCallbacks())
    {
        // do not invalidate and trigger a global repaint, but forward
        // the need for change to the applied EditViewCallback, can e.g.
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index e087305..3d138af 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -190,10 +190,10 @@ static void lcl_translateTwips(vcl::Window const & rParent, vcl::Window& rChild)
// change/update the Selection visualization for enhanced mechanisms
void ImpEditView::SelectionChanged()
{
    if (getEditViewCallbacks())
    if (EditViewCallbacks* pCallbacks = getEditViewCallbacks())
    {
        // use callback to tell about change in selection visualisation
        getEditViewCallbacks()->EditViewSelectionChange();
        pCallbacks->EditViewSelectionChange();
    }
}

@@ -701,12 +701,12 @@ void ImpEditView::SetOutputArea( const tools::Rectangle& rRect )

void ImpEditView::InvalidateAtWindow(const tools::Rectangle& rRect)
{
    if (getEditViewCallbacks())
    if (EditViewCallbacks* pCallbacks = getEditViewCallbacks())
    {
        // do not invalidate and trigger a global repaint, but forward
        // the need for change to the applied EditViewCallback, can e.g.
        // be used to visualize the active edit text in an OverlayObject
        getEditViewCallbacks()->EditViewInvalidate(rRect);
        pCallbacks->EditViewInvalidate(rRect);
    }
    else
    {
@@ -1247,11 +1247,12 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor )
        {
            SvxFont aFont;
            pEditEngine->SeekCursor( aPaM.GetNode(), aPaM.GetIndex()+1, aFont );
            if (vcl::Window* pWindow = GetWindow())
            {
                InputContextFlags const nContextFlags = InputContextFlags::Text | InputContextFlags::ExtText;
                pWindow->SetInputContext( InputContext( aFont, nContextFlags ) );
            }

            InputContext aInputContext(aFont, InputContextFlags::Text | InputContextFlags::ExtText);
            if (EditViewCallbacks* pCallbacks = getEditViewCallbacks())
                pCallbacks->EditViewInputContext(aInputContext);
            else if (auto xWindow = GetWindow())
                xWindow->SetInputContext(aInputContext);
        }
    }
    else
@@ -2416,8 +2417,8 @@ void ImpEditView::AddDragAndDropListeners()
        return;

    css::uno::Reference<css::datatransfer::dnd::XDropTarget> xDropTarget;
    if (getEditViewCallbacks())
        xDropTarget = getEditViewCallbacks()->GetDropTarget();
    if (EditViewCallbacks* pCallbacks = getEditViewCallbacks())
        xDropTarget = pCallbacks->GetDropTarget();
    else if (GetWindow())
        xDropTarget = GetWindow()->GetDropTarget();

@@ -2448,8 +2449,8 @@ void ImpEditView::RemoveDragAndDropListeners()
        return;

    css::uno::Reference<css::datatransfer::dnd::XDropTarget> xDropTarget;
    if (getEditViewCallbacks())
        xDropTarget = getEditViewCallbacks()->GetDropTarget();
    if (EditViewCallbacks* pCallbacks = getEditViewCallbacks())
        xDropTarget = pCallbacks->GetDropTarget();
    else if (GetWindow())
        xDropTarget = GetWindow()->GetDropTarget();

diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index bf61969..0ecf4c4 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -261,15 +261,15 @@ private:
    // incarnation has to handle that. Used e.g. to represent the edited text
    // in Draw/Impress in an OverlayObject which avoids evtl. expensive full
    // repaints of the EditView(s)
    const EditViewCallbacks* mpEditViewCallbacks;
    EditViewCallbacks* mpEditViewCallbacks;
    bool mbBroadcastLOKViewCursor;

    const EditViewCallbacks* getEditViewCallbacks() const
    EditViewCallbacks* getEditViewCallbacks() const
    {
        return mpEditViewCallbacks;
    }

    void setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks)
    void setEditViewCallbacks(EditViewCallbacks* pEditViewCallbacks)
    {
        mpEditViewCallbacks = pEditViewCallbacks;
    }
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 441dcb9..41d7071 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -55,6 +55,7 @@ class SfxItemSet;
namespace vcl { class Cursor; }
namespace vcl { class Font; }
class FontList;
class InputContext;
class OutputDevice;
enum class TransliterationFlags;
enum class PointerStyle;
@@ -97,18 +98,21 @@ public:
    // call this when text visualization changed in any way. It
    // will also update selection, so no need to call this self
    // additionally (but will also do no harm)
    virtual void EditViewInvalidate(const tools::Rectangle& rRect) const = 0;
    virtual void EditViewInvalidate(const tools::Rectangle& rRect) = 0;

    // call this when only selection is changed. Text change will
    // then *not* be checked and not be reacted on. Still, when
    // only the selection is changed, this is useful and faster
    virtual void EditViewSelectionChange() const = 0;
    virtual void EditViewSelectionChange() = 0;

    // return the OutputDevice that the EditView will draw to
    virtual OutputDevice& EditViewOutputDevice() const = 0;

    // Triggered to update InputEngine context information
    virtual void EditViewInputContext(const InputContext& rInputContext) = 0;

    // implemented if drag and drop support is wanted
    virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> GetDropTarget() const
    virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> GetDropTarget()
    {
        return nullptr;
    }
@@ -140,8 +144,8 @@ public:
                    ~EditView();

    // set EditViewCallbacks for external handling of Repaints/Visualization
    void setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks);
    const EditViewCallbacks* getEditViewCallbacks() const;
    void setEditViewCallbacks(EditViewCallbacks* pEditViewCallbacks);
    EditViewCallbacks* getEditViewCallbacks() const;

    void            SetEditEngine( EditEngine* pEditEngine );
    EditEngine*     GetEditEngine() const;
diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index a78dd5c..feb27e3 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -65,9 +65,10 @@ class SVXCORE_DLLPUBLIC SdrObjEditView : public SdrGlueEditView, public EditView

    // Now derived from EditViewCallbacks and overriding these callbacks to
    // allow own EditText visualization
    virtual void EditViewInvalidate(const tools::Rectangle& rRect) const override;
    virtual void EditViewSelectionChange() const override;
    virtual void EditViewInvalidate(const tools::Rectangle& rRect) override;
    virtual void EditViewSelectionChange() override;
    virtual OutputDevice& EditViewOutputDevice() const override;
    virtual void EditViewInputContext(const InputContext& rInputContext) override;

    // The OverlayObjects used for visualizing active TextEdit (currently
    // using TextEditOverlayObject, but not limited to it
@@ -161,7 +162,7 @@ public:

    // used to call the old ImpPaintOutlinerView. Will be replaced when the
    // outliner will be displayed on the overlay in edit mode.
    void TextEditDrawing(SdrPaintWindow& rPaintWindow) const;
    void TextEditDrawing(SdrPaintWindow& rPaintWindow);

    // Actionhandling for macromode
    virtual bool IsAction() const override;
diff --git a/include/svx/weldeditview.hxx b/include/svx/weldeditview.hxx
index 071a8f5..3a96014 100644
--- a/include/svx/weldeditview.hxx
+++ b/include/svx/weldeditview.hxx
@@ -58,23 +58,19 @@ protected:

    virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;

    virtual void EditViewInvalidate(const tools::Rectangle& rRect) const override
    {
        weld::DrawingArea* pDrawingArea = GetDrawingArea();
        pDrawingArea->queue_draw_area(rRect.Left(), rRect.Top(), rRect.GetWidth(),
                                      rRect.GetHeight());
    }
    virtual void EditViewInvalidate(const tools::Rectangle& rRect) override { Invalidate(rRect); }

    virtual void EditViewSelectionChange() const override
    {
        weld::DrawingArea* pDrawingArea = GetDrawingArea();
        pDrawingArea->queue_draw();
    }
    virtual void EditViewSelectionChange() override { Invalidate(); }

    virtual OutputDevice& EditViewOutputDevice() const override
    {
        return GetDrawingArea()->get_ref_device();
    }

    virtual void EditViewInputContext(const InputContext& rInputContext) override
    {
        SetInputContext(rInputContext);
    }
};

#endif // INCLUDED_SVX_WELDEDITVIEW_HXX
diff --git a/include/vcl/customweld.hxx b/include/vcl/customweld.hxx
index 85829f3..0c3bd0a 100644
--- a/include/vcl/customweld.hxx
+++ b/include/vcl/customweld.hxx
@@ -12,6 +12,8 @@

#include <vcl/weld.hxx>

class InputContext;

namespace weld
{
class VCL_DLLPUBLIC CustomWidgetController
@@ -82,6 +84,10 @@ public:
    void SetPointer(PointerStyle ePointerStyle) { m_pDrawingArea->set_cursor(ePointerStyle); }
    void SetHelpId(const OString& rHelpId) { m_pDrawingArea->set_help_id(rHelpId); }
    void SetAccessibleName(const OUString& rName) { m_pDrawingArea->set_accessible_name(rName); }
    void SetInputContext(const InputContext& rInputContext)
    {
        m_pDrawingArea->set_input_context(rInputContext);
    }
    void SetDragDataTransferrable(rtl::Reference<TransferDataContainer>& rTransferrable,
                                  sal_uInt8 eDNDConstants)
    {
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 33138aa..458eb13 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -63,6 +63,7 @@ typedef css::uno::Reference<css::accessibility::XAccessibleRelationSet> a11yrela

enum class PointerStyle;
class CommandEvent;
class InputContext;
class KeyEvent;
class MouseEvent;
class SvNumberFormatter;
@@ -2056,6 +2057,8 @@ public:

    virtual void set_cursor(PointerStyle ePointerStyle) = 0;

    virtual void set_input_context(const InputContext& rInputContext) = 0;

    // use return here just to generate matching VirtualDevices
    virtual OutputDevice& get_ref_device() = 0;

diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 40aacd3..851a730 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -619,7 +619,7 @@ void TextEditOverlayObject::checkSelectionChange()
// callback from the active EditView, forward to evtl. existing instances of the
// TextEditOverlayObject(s). This will additionally update the selection which
// is an integral part of the text visualization
void SdrObjEditView::EditViewInvalidate(const tools::Rectangle&) const
void SdrObjEditView::EditViewInvalidate(const tools::Rectangle&)
{
    if (IsTextEdit())
    {
@@ -643,7 +643,7 @@ void SdrObjEditView::EditViewInvalidate(const tools::Rectangle&) const
// callback from the active EditView, forward to evtl. existing instances of the
// TextEditOverlayObject(s). This cvall *only* updates the selection visualization
// which is e.g. used when only the selection is changed, but not the text
void SdrObjEditView::EditViewSelectionChange() const
void SdrObjEditView::EditViewSelectionChange()
{
    if (IsTextEdit())
    {
@@ -662,7 +662,14 @@ void SdrObjEditView::EditViewSelectionChange() const

OutputDevice& SdrObjEditView::EditViewOutputDevice() const { return *pTextEditWin; }

void SdrObjEditView::TextEditDrawing(SdrPaintWindow& rPaintWindow) const
void SdrObjEditView::EditViewInputContext(const InputContext& rInputContext)
{
    if (!pTextEditWin)
        return;
    pTextEditWin->SetInputContext(rInputContext);
}

void SdrObjEditView::TextEditDrawing(SdrPaintWindow& rPaintWindow)
{
    if (!comphelper::LibreOfficeKit::isActive())
    {
diff --git a/sw/source/ui/dbui/mmaddressblockpage.cxx b/sw/source/ui/dbui/mmaddressblockpage.cxx
index 11d884e..7c67627 100644
--- a/sw/source/ui/dbui/mmaddressblockpage.cxx
+++ b/sw/source/ui/dbui/mmaddressblockpage.cxx
@@ -1404,7 +1404,7 @@ void AddressMultiLineEdit::UpdateFields()
    m_aSelectionLink.Call(false);
}

void AddressMultiLineEdit::EditViewSelectionChange() const
void AddressMultiLineEdit::EditViewSelectionChange()
{
    WeldEditView::EditViewSelectionChange();
    m_aSelectionLink.Call(true);
@@ -1541,7 +1541,7 @@ namespace
    };
}

css::uno::Reference<css::datatransfer::dnd::XDropTarget> AddressMultiLineEdit::GetDropTarget() const
css::uno::Reference<css::datatransfer::dnd::XDropTarget> AddressMultiLineEdit::GetDropTarget()
{
    if (!m_xDropTarget.is())
    {
@@ -1549,7 +1549,7 @@ css::uno::Reference<css::datatransfer::dnd::XDropTarget> AddressMultiLineEdit::G
        DropTargetListener* pProxy = new DropTargetListener(xRealDropTarget, m_pParentDialog);
        uno::Reference<css::datatransfer::dnd::XDropTargetListener> xListener(pProxy);
        xRealDropTarget->addDropTargetListener(xListener);
        const_cast<AddressMultiLineEdit*>(this)->m_xDropTarget = uno::Reference<css::datatransfer::dnd::XDropTarget>(pProxy);
        m_xDropTarget = uno::Reference<css::datatransfer::dnd::XDropTarget>(pProxy);
    }
    return m_xDropTarget;
}
diff --git a/sw/source/ui/dbui/mmaddressblockpage.hxx b/sw/source/ui/dbui/mmaddressblockpage.hxx
index d55b0cf..c1fc3224 100644
--- a/sw/source/ui/dbui/mmaddressblockpage.hxx
+++ b/sw/source/ui/dbui/mmaddressblockpage.hxx
@@ -141,8 +141,8 @@ class AddressMultiLineEdit : public WeldEditView

    css::uno::Reference<css::datatransfer::dnd::XDropTarget> m_xDropTarget;

    virtual void EditViewSelectionChange() const override;
    virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> GetDropTarget() const override;
    virtual void EditViewSelectionChange() override;
    virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> GetDropTarget() override;

    virtual bool KeyInput(const KeyEvent& rKEvt) override;
    virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index dbdff77..7e80bc2 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -5577,6 +5577,11 @@ public:
        m_xDrawingArea->SetPointer(ePointerStyle);
    }

    virtual void set_input_context(const InputContext& rInputContext) override
    {
        m_xDrawingArea->SetInputContext(rInputContext);
    }

    virtual a11yref get_accessible_parent() override
    {
        vcl::Window* pParent = m_xDrawingArea->GetParent();
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 7023815..77af86f 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -12621,6 +12621,11 @@ public:
        gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(m_pDrawingArea)), pCursor);
    }

    virtual void set_input_context(const InputContext& /*rInputContext*/) override
    {
        // TODO follow up for the gtk case
    }

    virtual void queue_draw() override
    {
        gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea));