weld SmEditTextWindow

reuse the WeldEditAccessible a11y impl and remove the then unused
starmath equivalent.

Change-Id: I2dc1e0436ffcd0b295e204c21bfcd365dae08bff
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114044
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svx/weldeditview.hxx b/include/svx/weldeditview.hxx
index d3697ad..1f388cb 100644
--- a/include/svx/weldeditview.hxx
+++ b/include/svx/weldeditview.hxx
@@ -40,6 +40,7 @@ public:

    bool HasSelection() const;

    void Delete();
    void Cut();
    void Copy();
    void Paste();
@@ -47,6 +48,7 @@ public:
    virtual ~WeldEditView() override;

protected:
    bool m_bAcceptsTab;
    std::unique_ptr<EditEngine> m_xEditEngine;
    std::unique_ptr<EditView> m_xEditView;
    rtl::Reference<WeldEditAccessible> m_xAccessible;
@@ -67,6 +69,11 @@ protected:
    virtual void LoseFocus() override;
    virtual void Resize() override;

    // Whether Tab will result in entering a tab or not
    bool GetAcceptsTab() const { return m_bAcceptsTab; }

    void SetAcceptsTab(bool bAcceptsTab) { m_bAcceptsTab = bAcceptsTab; }

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

    virtual void EditViewInvalidate(const tools::Rectangle& rRect) override { Invalidate(rRect); }
diff --git a/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java b/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java
index 7b7a2c2..b32e7f4 100644
--- a/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java
+++ b/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java
@@ -86,7 +86,7 @@ public class SmEditAccessible extends TestCase {
        XAccessible xRoot = AccessibilityTools.getAccessibleObject(xWindow);

        oObj = AccessibilityTools.getAccessibleObjectForRole
            (xRoot, AccessibleRole.TEXT_FRAME, "", "SmEditAccessible");
            (xRoot, AccessibleRole.TEXT_FRAME, "", "WeldEditAccessible");

        log.println("ImplementationName " + utils.getImplName(oObj));
        AccessibilityTools.printAccessibleTree(log, xRoot, Param.getBool(util.PropertyName.DEBUG_IS_ACTIVE));
diff --git a/starmath/UIConfig_smath.mk b/starmath/UIConfig_smath.mk
index 5aa6e4c..c243742 100644
--- a/starmath/UIConfig_smath.mk
+++ b/starmath/UIConfig_smath.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/smath,\
	starmath/uiconfig/smath/ui/alignmentdialog \
	starmath/uiconfig/smath/ui/catalogdialog \
	starmath/uiconfig/smath/ui/dockingelements \
	starmath/uiconfig/smath/ui/editwindow \
	starmath/uiconfig/smath/ui/fontdialog \
	starmath/uiconfig/smath/ui/fontsizedialog \
	starmath/uiconfig/smath/ui/fonttypedialog \
diff --git a/starmath/inc/edit.hxx b/starmath/inc/edit.hxx
index 279c068..3a77af0 100644
--- a/starmath/inc/edit.hxx
+++ b/starmath/inc/edit.hxx
@@ -19,7 +19,8 @@

#pragma once

#include <vcl/window.hxx>
#include <svx/weldeditview.hxx>
#include <vcl/InterimItemWindow.hxx>
#include <vcl/idle.hxx>
#include <vcl/transfer.hxx>

@@ -28,11 +29,8 @@ class SmViewShell;
class EditView;
class EditEngine;
class EditStatus;
class ScrollBar;
class ScrollBarBox;
class DataChangedEvent;
class SmCmdBoxWindow;
class SmEditAccessible;
class CommandEvent;
class Timer;

@@ -43,50 +41,64 @@ class ColorConfig;

void SmGetLeftSelectionPart(const ESelection& rSelection, sal_Int32& nPara, sal_uInt16& nPos);

class SmEditWindow final : public vcl::Window, public DropTargetHelper
{
    rtl::Reference<SmEditAccessible> mxAccessible;
class SmEditWindow;

    SmCmdBoxWindow& rCmdBox;
    std::unique_ptr<EditView> pEditView;
    VclPtr<ScrollBar> pHScrollBar;
    VclPtr<ScrollBar> pVScrollBar;
    VclPtr<ScrollBarBox> pScrollBox;
class SmEditTextWindow : public WeldEditView
{
private:
    SmEditWindow& mrEditWindow;

    Idle aModifyIdle;
    Idle aCursorMoveIdle;
    ESelection aOldSelection;

    virtual void KeyInput(const KeyEvent& rKEvt) override;
    virtual void Command(const CommandEvent& rCEvt) override;
    ESelection aOldSelection;

    DECL_LINK(ModifyTimerHdl, Timer*, void);
    DECL_LINK(CursorMoveTimerHdl, Timer*, void);
    DECL_LINK(EditStatusHdl, EditStatus&, void);

public:
    SmEditTextWindow(SmEditWindow& rEditWindow);
    virtual ~SmEditTextWindow() override;

    virtual EditEngine* GetEditEngine() const override;

    virtual void EditViewScrollStateChange() override;

    virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;

    virtual bool KeyInput(const KeyEvent& rKeyEvt) override;
    virtual bool MouseButtonUp(const MouseEvent& rEvt) override;
    virtual bool Command(const CommandEvent& rCEvt) override;
    virtual void GetFocus() override;
    virtual void LoseFocus() override;

    void SetText(const OUString& rText);
    void InsertText(const OUString& rText);
    void SelNextMark();
    ESelection GetSelection() const;
    void UserPossiblyChangedText();
    void Flush();
    void UpdateStatus(bool bSetDocModified);
    void StartCursorMove();
};

class SmEditWindow final : public InterimItemWindow, public DropTargetHelper
{
    SmCmdBoxWindow& rCmdBox;
    std::unique_ptr<weld::ScrolledWindow> mxScrolledWindow;
    std::unique_ptr<SmEditTextWindow> mxTextControl;
    std::unique_ptr<weld::CustomWeld> mxTextControlWin;

    virtual void ApplySettings(vcl::RenderContext&) override;
    virtual void DataChanged(const DataChangedEvent&) override;
    virtual void Resize() override;
    virtual void MouseMove(const MouseEvent& rEvt) override;
    virtual void MouseButtonUp(const MouseEvent& rEvt) override;
    virtual void MouseButtonDown(const MouseEvent& rEvt) override;

    virtual OUString GetSurroundingText() const override;
    virtual Selection GetSurroundingTextSelection() const override;
    virtual bool DeleteSurroundingText(const Selection& rSelection) override;

    virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override;
    virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override;
    virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;

    DECL_LINK(EditStatusHdl, EditStatus&, void);
    DECL_LINK(ScrollHdl, ScrollBar*, void);
    DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);

    void CreateEditView();
    tools::Rectangle AdjustScrollBars();
    void SetScrollBarRanges();
    void InitScrollBars();
    void InvalidateSlots();
    void UpdateStatus(bool bSetDocModified);
    void UserPossiblyChangedText();

public:
    explicit SmEditWindow(SmCmdBoxWindow& rMyCmdBoxWin);
@@ -95,14 +107,14 @@ public:

    SmDocShell* GetDoc();
    SmViewShell* GetView();
    EditView* GetEditView();
    EditView* GetEditView() const;
    EditEngine* GetEditEngine();

    // Window
    virtual void SetText(const OUString& rText) override;
    virtual OUString GetText() const override;
    virtual void GetFocus() override;
    virtual void LoseFocus() override;
    virtual void Resize() override;
    virtual void Command(const CommandEvent& rCEvt) override;

    ESelection GetSelection() const;
    void SetSelection(const ESelection& rSel);
@@ -110,6 +122,9 @@ public:
    bool IsEmpty() const;
    bool IsSelected() const;
    bool IsAllSelected() const;
    void SetScrollBarRanges();
    tools::Rectangle AdjustScrollBars();
    void InvalidateSlots();
    void Cut();
    void Copy();
    void Paste();
@@ -119,19 +134,11 @@ public:
    void MarkError(const Point& rPos);
    void SelNextMark();
    void SelPrevMark();
    static bool HasMark(const OUString& rText);

    void Flush() override;
    void DeleteEditView();

    bool HandleWheelCommands(const CommandEvent& rCEvt);
    static bool IsInlineEditEnabled();
    void StartCursorMove();

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

    using Window::GetAccessible;
    void HideScrollbars();
    void ShowScrollbars();
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/accessibility.cxx b/starmath/source/accessibility.cxx
index d6e5988..bab8d77 100644
--- a/starmath/source/accessibility.cxx
+++ b/starmath/source/accessibility.cxx
@@ -737,1046 +737,4 @@ Sequence< OUString > SAL_CALL SmGraphicAccessible::getSupportedServiceNames()
    };
}


SmEditSource::SmEditSource( SmEditAccessible &rAcc ) :
    aViewFwd    (rAcc),
    aTextFwd    (rAcc, *this),
    aEditViewFwd(rAcc),
    rEditAcc (rAcc)
{
}

SmEditSource::SmEditSource( const SmEditSource &rSrc ) :
    SvxEditSource(),
    aViewFwd    (rSrc.rEditAcc),
    aTextFwd    (rSrc.rEditAcc, *this),
    aEditViewFwd(rSrc.rEditAcc),
    rEditAcc    (rSrc.rEditAcc)
{
}

SmEditSource::~SmEditSource()
{
}

std::unique_ptr<SvxEditSource> SmEditSource::Clone() const
{
    return std::unique_ptr<SvxEditSource>(new SmEditSource( *this ));
}

SvxTextForwarder* SmEditSource::GetTextForwarder()
{
    return &aTextFwd;
}

SvxViewForwarder* SmEditSource::GetViewForwarder()
{
    return &aViewFwd;
}

SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( bool /*bCreate*/ )
{
    return &aEditViewFwd;
}

void SmEditSource::UpdateData()
{
    // would possibly only by needed if the XText interface is implemented
    // and its text needs to be updated.
}

SfxBroadcaster & SmEditSource::GetBroadcaster() const
{
    return const_cast<SmEditSource*>(this)->aBroadCaster;
}

SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) :
    rEditAcc(rAcc)
{
}

SmViewForwarder::~SmViewForwarder()
{
}

bool SmViewForwarder::IsValid() const
{
    return rEditAcc.GetEditView() != nullptr;
}

Point SmViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
{
    EditView *pEditView = rEditAcc.GetEditView();
    OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;

    if( pOutDev )
    {
        MapMode aMapMode(pOutDev->GetMapMode());
        Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
                                                  MapMode(aMapMode.GetMapUnit())) );
        aMapMode.SetOrigin(Point());
        return pOutDev->LogicToPixel( aPoint, aMapMode );
    }

    return Point();
}

Point SmViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
{
    EditView *pEditView = rEditAcc.GetEditView();
    OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;

    if( pOutDev )
    {
        MapMode aMapMode(pOutDev->GetMapMode());
        aMapMode.SetOrigin(Point());
        Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
        return OutputDevice::LogicToLogic( aPoint,
                                           MapMode(aMapMode.GetMapUnit()),
                                           rMapMode );
    }

    return Point();
}


SmTextForwarder::SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource) :
    rEditAcc ( rAcc ),
    rEditSource (rSource)
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetNotifyHdl( LINK(this, SmTextForwarder, NotifyHdl) );
}

SmTextForwarder::~SmTextForwarder()
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetNotifyHdl( Link<EENotify&,void>() );
}

IMPL_LINK(SmTextForwarder, NotifyHdl, EENotify&, rNotify, void)
{
    ::std::unique_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( &rNotify );
    if (aHint)
        rEditSource.GetBroadcaster().Broadcast(*aHint);
}

sal_Int32 SmTextForwarder::GetParagraphCount() const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
}

sal_Int32 SmTextForwarder::GetTextLen( sal_Int32 nParagraph ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0;
}

OUString SmTextForwarder::GetText( const ESelection& rSel ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    OUString aRet;
    if (pEditEngine)
        aRet = pEditEngine->GetText( rSel );
    return convertLineEnd(aRet, GetSystemLineEnd());
}

SfxItemSet SmTextForwarder::GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    assert(pEditEngine && "EditEngine missing");
    if( rSel.nStartPara == rSel.nEndPara )
    {
        GetAttribsFlags nFlags = GetAttribsFlags::NONE;
        switch( nOnlyHardAttrib )
        {
        case EditEngineAttribs::All:
            nFlags = GetAttribsFlags::ALL;
            break;
        case EditEngineAttribs::OnlyHard:
            nFlags = GetAttribsFlags::CHARATTRIBS;
            break;
        default:
            SAL_WARN("starmath", "unknown flags for SmTextForwarder::GetAttribs");
        }

        return pEditEngine->GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
    }
    else
    {
        return pEditEngine->GetAttribs( rSel, nOnlyHardAttrib );
    }
}

SfxItemSet SmTextForwarder::GetParaAttribs( sal_Int32 nPara ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    assert(pEditEngine && "EditEngine missing");

    SfxItemSet aSet( pEditEngine->GetParaAttribs( nPara ) );

    sal_uInt16 nWhich = EE_PARA_START;
    while( nWhich <= EE_PARA_END )
    {
        if( aSet.GetItemState( nWhich ) != SfxItemState::SET )
        {
            if( pEditEngine->HasParaAttrib( nPara, nWhich ) )
                aSet.Put( pEditEngine->GetParaAttrib( nPara, nWhich ) );
        }
        nWhich++;
    }

    return aSet;
}

void SmTextForwarder::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetParaAttribs( nPara, rSet );
}

SfxItemPool* SmTextForwarder::GetPool() const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : nullptr;
}

void SmTextForwarder::RemoveAttribs( const ESelection& rSelection )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->RemoveAttribs( rSelection, false/*bRemoveParaAttribs*/, 0 );
}

void SmTextForwarder::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->GetPortions( nPara, rList );
}

void SmTextForwarder::QuickInsertText( const OUString& rText, const ESelection& rSel )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->QuickInsertText( rText, rSel );
}

void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->QuickInsertLineBreak( rSel );
}

void SmTextForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->QuickInsertField( rFld, rSel );
}

void SmTextForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->QuickSetAttribs( rSet, rSel );
}

bool SmTextForwarder::IsValid() const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    // cannot reliably query EditEngine state
    // while in the middle of an update
    return pEditEngine && pEditEngine->GetUpdateMode();
}

OUString SmTextForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor )
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->CalcFieldValue(rField, nPara, nPos, rpTxtColor, rpFldColor) : OUString();
}

void SmTextForwarder::FieldClicked(const SvxFieldItem&)
{
}

static SfxItemState GetSvxEditEngineItemState( EditEngine const & rEditEngine, const ESelection& rSel, sal_uInt16 nWhich )
{
    std::vector<EECharAttrib> aAttribs;

    const SfxPoolItem*  pLastItem = nullptr;

    SfxItemState eState = SfxItemState::DEFAULT;

    // check all paragraphs inside the selection
    for( sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
    {
        SfxItemState eParaState = SfxItemState::DEFAULT;

        // calculate start and endpos for this paragraph
        sal_Int32 nPos = 0;
        if( rSel.nStartPara == nPara )
            nPos = rSel.nStartPos;

        sal_Int32 nEndPos = rSel.nEndPos;
        if( rSel.nEndPara != nPara )
            nEndPos = rEditEngine.GetTextLen( nPara );


        // get list of char attribs
        rEditEngine.GetCharAttribs( nPara, aAttribs );

        bool bEmpty = true;     // we found no item inside the selection of this paragraph
        bool bGaps  = false;    // we found items but there are gaps between them
        sal_Int32 nLastEnd = nPos;

        const SfxPoolItem* pParaItem = nullptr;

        for(const auto& rAttrib : aAttribs)
        {
            OSL_ENSURE( rAttrib.pAttr, "GetCharAttribs gives corrupt data" );

            const bool bEmptyPortion = (rAttrib.nStart == rAttrib.nEnd);
            if( (!bEmptyPortion && (rAttrib.nStart >= nEndPos)) || (bEmptyPortion && (rAttrib.nStart > nEndPos)) )
                break;  // break if we are already behind our selection

            if( (!bEmptyPortion && (rAttrib.nEnd <= nPos)) || (bEmptyPortion && (rAttrib.nEnd < nPos)) )
                continue;   // or if the attribute ends before our selection

            if( rAttrib.pAttr->Which() != nWhich )
                continue; // skip if is not the searched item

            // if we already found an item
            if( pParaItem )
            {
                // ... and its different to this one than the state is don't care
                if( *pParaItem != *(rAttrib.pAttr) )
                    return SfxItemState::DONTCARE;
            }
            else
            {
                pParaItem = rAttrib.pAttr;
            }

            if( bEmpty )
                bEmpty = false;

            if( !bGaps && rAttrib.nStart > nLastEnd )
                bGaps = true;

            nLastEnd = rAttrib.nEnd;
        }

        if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
            bGaps = true;
        if( bEmpty )
            eParaState = SfxItemState::DEFAULT;
        else if( bGaps )
            eParaState = SfxItemState::DONTCARE;
        else
            eParaState = SfxItemState::SET;

        // if we already found an item check if we found the same
        if( pLastItem )
        {
            if( (pParaItem == nullptr) || (*pLastItem != *pParaItem) )
                return SfxItemState::DONTCARE;
        }
        else
        {
            pLastItem = pParaItem;
            eState = eParaState;
        }
    }

    return eState;
}

SfxItemState SmTextForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
{
    SfxItemState nState = SfxItemState::DISABLED;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        nState = GetSvxEditEngineItemState( *pEditEngine, rSel, nWhich );
    return nState;
}

SfxItemState SmTextForwarder::GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const
{
    SfxItemState nState = SfxItemState::DISABLED;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        const SfxItemSet& rSet = pEditEngine->GetParaAttribs( nPara );
        nState = rSet.GetItemState( nWhich );
    }
    return nState;
}

LanguageType SmTextForwarder::GetLanguage( sal_Int32 nPara, sal_Int32 nIndex ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
}

sal_Int32 SmTextForwarder::GetFieldCount( sal_Int32 nPara ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
}

EFieldInfo SmTextForwarder::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetFieldInfo( nPara, nField ) : EFieldInfo();
}

EBulletInfo SmTextForwarder::GetBulletInfo( sal_Int32 /*nPara*/ ) const
{
    return EBulletInfo();
}

tools::Rectangle SmTextForwarder::GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const
{
    tools::Rectangle aRect(0,0,0,0);
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();

    if (pEditEngine)
    {
        // Handle virtual position one-past-the end of the string
        if( nIndex >= pEditEngine->GetTextLen(nPara) )
        {
            if( nIndex )
                aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex-1) );

            aRect.Move( aRect.Right() - aRect.Left(), 0 );
            aRect.SetSize( Size(1, pEditEngine->GetTextHeight()) );
        }
        else
        {
            aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex) );
        }
    }
    return aRect;
}

tools::Rectangle SmTextForwarder::GetParaBounds( sal_Int32 nPara ) const
{
    tools::Rectangle aRect(0,0,0,0);
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();

    if (pEditEngine)
    {
        const Point aPnt = pEditEngine->GetDocPosTopLeft( nPara );
        const sal_uLong nWidth = pEditEngine->CalcTextWidth();
        const sal_uLong nHeight = pEditEngine->GetTextHeight( nPara );
        aRect = tools::Rectangle( aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight );
    }

    return aRect;
}

MapMode SmTextForwarder::GetMapMode() const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MapUnit::Map100thMM );
}

OutputDevice* SmTextForwarder::GetRefDevice() const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetRefDevice() : nullptr;
}

bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_Int32& nPara, sal_Int32& nIndex ) const
{
    bool bRes = false;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        EPosition aDocPos = pEditEngine->FindDocPosition( rPos );
        nPara   = aDocPos.nPara;
        nIndex  = aDocPos.nIndex;
        bRes = true;
    }
    return bRes;
}

bool SmTextForwarder::GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const
{
    bool bRes = false;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        ESelection aRes = pEditEngine->GetWord( ESelection(nPara, nIndex, nPara, nIndex), css::i18n::WordType::DICTIONARY_WORD );

        if( aRes.nStartPara == nPara &&
            aRes.nStartPara == aRes.nEndPara )
        {
            nStart = aRes.nStartPos;
            nEnd = aRes.nEndPos;

            bRes = true;
        }
    }

    return bRes;
}

bool SmTextForwarder::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (!pEditEngine)
        return false;
    SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex, bInCell );
    return true;
}

sal_Int32 SmTextForwarder::GetLineCount( sal_Int32 nPara ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
}

sal_Int32 SmTextForwarder::GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
}

void SmTextForwarder::GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nPara, sal_Int32 nLine ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
        pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
    else
        rStart = rEnd = 0;
}

sal_Int32 SmTextForwarder::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const
{
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
}

bool SmTextForwarder::QuickFormatDoc( bool /*bFull*/ )
{
    bool bRes = false;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        pEditEngine->QuickFormatDoc();
        bRes = true;
    }
    return bRes;
}

sal_Int16 SmTextForwarder::GetDepth( sal_Int32 /*nPara*/ ) const
{
    // math has no outliner...
    return -1;
}

bool SmTextForwarder::SetDepth( sal_Int32 /*nPara*/, sal_Int16 nNewDepth )
{
    // math has no outliner...
    return -1 == nNewDepth;  // is it the value from 'GetDepth' ?
}

bool SmTextForwarder::Delete( const ESelection& rSelection )
{
    bool bRes = false;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        pEditEngine->QuickDelete( rSelection );
        pEditEngine->QuickFormatDoc();
        bRes = true;
    }
    return bRes;
}

bool SmTextForwarder::InsertText( const OUString& rStr, const ESelection& rSelection )
{
    bool bRes = false;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        pEditEngine->QuickInsertText( rStr, rSelection );
        pEditEngine->QuickFormatDoc();
        bRes = true;
    }
    return bRes;
}

const SfxItemSet*   SmTextForwarder::GetEmptyItemSetPtr()
{
    const SfxItemSet *pItemSet = nullptr;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        pItemSet = &pEditEngine->GetEmptyItemSet();
    }
    return pItemSet;
}

void SmTextForwarder::AppendParagraph()
{
    // append an empty paragraph
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine)
    {
        sal_Int32 nParaCount = pEditEngine->GetParagraphCount();
        pEditEngine->InsertParagraph( nParaCount, OUString() );
    }
}

sal_Int32 SmTextForwarder::AppendTextPortion( sal_Int32 nPara, const OUString &rText, const SfxItemSet &rSet )
{
    sal_uInt16 nRes = 0;
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
    {
        // append text
        ESelection aSel( nPara, pEditEngine->GetTextLen( nPara ) );
        pEditEngine->QuickInsertText( rText, aSel );

        // set attributes for new appended text
        nRes = aSel.nEndPos = pEditEngine->GetTextLen( nPara );
        pEditEngine->QuickSetAttribs( rSet, aSel );
    }
    return nRes;
}

void SmTextForwarder::CopyText(const SvxTextForwarder& rSource)
{

    const SmTextForwarder* pSourceForwarder = dynamic_cast< const SmTextForwarder* >( &rSource );
    if( !pSourceForwarder )
        return;
    EditEngine* pSourceEditEngine = pSourceForwarder->rEditAcc.GetEditEngine();
    EditEngine *pEditEngine = rEditAcc.GetEditEngine();
    if (pEditEngine && pSourceEditEngine )
    {
        std::unique_ptr<EditTextObject> pNewTextObject = pSourceEditEngine->CreateTextObject();
        pEditEngine->SetText( *pNewTextObject );
    }
}


SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) :
    rEditAcc( rAcc )
{
}

SmEditViewForwarder::~SmEditViewForwarder()
{
}

bool SmEditViewForwarder::IsValid() const
{
    return rEditAcc.GetEditView() != nullptr;
}


Point SmEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
{
    EditView *pEditView = rEditAcc.GetEditView();
    OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;

    if( pOutDev )
    {
        MapMode aMapMode(pOutDev->GetMapMode());
        Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
                                                  MapMode(aMapMode.GetMapUnit())));
        aMapMode.SetOrigin(Point());
        return pOutDev->LogicToPixel( aPoint, aMapMode );
    }

    return Point();
}

Point SmEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
{
    EditView *pEditView = rEditAcc.GetEditView();
    OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;

    if( pOutDev )
    {
        MapMode aMapMode(pOutDev->GetMapMode());
        aMapMode.SetOrigin(Point());
        Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
        return OutputDevice::LogicToLogic( aPoint,
                                           MapMode(aMapMode.GetMapUnit()),
                                           rMapMode );
    }

    return Point();
}

bool SmEditViewForwarder::GetSelection( ESelection& rSelection ) const
{
    bool bRes = false;
    EditView *pEditView = rEditAcc.GetEditView();
    if (pEditView)
    {
        rSelection = pEditView->GetSelection();
        bRes = true;
    }
    return bRes;
}

bool SmEditViewForwarder::SetSelection( const ESelection& rSelection )
{
    bool bRes = false;
    EditView *pEditView = rEditAcc.GetEditView();
    if (pEditView)
    {
        pEditView->SetSelection( rSelection );
        bRes = true;
    }
    return bRes;
}

bool SmEditViewForwarder::Copy()
{
    bool bRes = false;
    EditView *pEditView = rEditAcc.GetEditView();
    if (pEditView)
    {
        pEditView->Copy();
        bRes = true;
    }
    return bRes;
}

bool SmEditViewForwarder::Cut()
{
    bool bRes = false;
    EditView *pEditView = rEditAcc.GetEditView();
    if (pEditView)
    {
        pEditView->Cut();
        bRes = true;
    }
    return bRes;
}

bool SmEditViewForwarder::Paste()
{
    bool bRes = false;
    EditView *pEditView = rEditAcc.GetEditView();
    if (pEditView)
    {
        pEditView->Paste();
        bRes = true;
    }
    return bRes;
}


SmEditAccessible::SmEditAccessible( SmEditWindow *pEditWin ) :
    aAccName            (SmResId(STR_CMDBOXWINDOW)),
    pTextHelper         (),
    pWin                (pEditWin)
{
    OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
}

SmEditAccessible::~SmEditAccessible()
{
}

::accessibility::AccessibleTextHelper *SmEditAccessible::GetTextHelper()
{
    return pTextHelper.get();
}

void SmEditAccessible::Init()
{
    OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
    if (pWin)
    {
        EditEngine *pEditEngine = pWin->GetEditEngine();
        EditView   *pEditView   = pWin->GetEditView();
        if (pEditEngine && pEditView)
        {
            assert(!pTextHelper);
            pTextHelper.reset(new ::accessibility::AccessibleTextHelper( std::make_unique<SmEditSource>( *this ) ));
            pTextHelper->SetEventSource( this );
        }
    }
}

void SmEditAccessible::ClearWin()
{
    // remove handler before current object gets destroyed
    // (avoid handler being called for already dead object)
    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetNotifyHdl( Link<EENotify&,void>() );

    pWin = nullptr;   // implicitly results in AccessibleStateType::DEFUNC set

    //! make TextHelper implicitly release C++ references to some core objects
    pTextHelper->SetEditSource( ::std::unique_ptr<SvxEditSource>() );
    //! make TextHelper release references
    //! (e.g. the one set by the 'SetEventSource' call)
    pTextHelper->Dispose();
    pTextHelper.reset();
}

// XAccessible
uno::Reference< XAccessibleContext > SAL_CALL SmEditAccessible::getAccessibleContext(  )
{
    return this;
}

// XAccessibleComponent
sal_Bool SAL_CALL SmEditAccessible::containsPoint( const awt::Point& aPoint )
{
    //! the arguments coordinates are relative to the current window !
    //! Thus the top left-point is (0, 0)

    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();

    Size aSz( pWin->GetSizePixel() );
    return  aPoint.X >= 0  &&  aPoint.Y >= 0  &&
            aPoint.X < aSz.Width()  &&  aPoint.Y < aSz.Height();
}

uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleAtPoint( const awt::Point& aPoint )
{
    SolarMutexGuard aGuard;
    if (!pTextHelper)
        throw RuntimeException();
    return pTextHelper->GetAt( aPoint );
}

awt::Rectangle SAL_CALL SmEditAccessible::getBounds(  )
{
    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();
    OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
            "mismatch of window parent and accessible parent" );
    return lcl_GetBounds( pWin );
}

awt::Point SAL_CALL SmEditAccessible::getLocation(  )
{
    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();
    OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
            "mismatch of window parent and accessible parent" );
    awt::Rectangle aRect( lcl_GetBounds( pWin ) );
    return awt::Point( aRect.X, aRect.Y );
}

awt::Point SAL_CALL SmEditAccessible::getLocationOnScreen(  )
{
    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();
    OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
            "mismatch of window parent and accessible parent" );
    return lcl_GetLocationOnScreen( pWin );
}

awt::Size SAL_CALL SmEditAccessible::getSize(  )
{
    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();
    OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
            "mismatch of window parent and accessible parent" );

    Size aSz( pWin->GetSizePixel() );
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
    awt::Rectangle aRect( lcl_GetBounds( pWin ) );
    Size aSz2( aRect.Width, aRect.Height );
    assert(aSz == aSz2 && "mismatch in width");
#endif
    return awt::Size( aSz.Width(), aSz.Height() );
}

void SAL_CALL SmEditAccessible::grabFocus(  )
{
    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();

    pWin->GrabFocus();
}

sal_Int32 SAL_CALL SmEditAccessible::getForeground()
{
    SolarMutexGuard aGuard;

    if (!pWin)
        throw RuntimeException();
    return static_cast<sal_Int32>(pWin->GetTextColor());
}

sal_Int32 SAL_CALL SmEditAccessible::getBackground()
{
    SolarMutexGuard aGuard;

    if (!pWin)
        throw RuntimeException();
    Wallpaper aWall( pWin->GetDisplayBackground() );
    Color nCol;
    if (aWall.IsBitmap() || aWall.IsGradient())
        nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor();
    else
        nCol = aWall.GetColor();
    return static_cast<sal_Int32>(nCol);
}

// XAccessibleContext
sal_Int32 SAL_CALL SmEditAccessible::getAccessibleChildCount(  )
{
    SolarMutexGuard aGuard;
    if (!pTextHelper)
        return 0;
    return pTextHelper->GetChildCount();
}

uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleChild( sal_Int32 i )
{
    SolarMutexGuard aGuard;
    if (!pTextHelper)
        throw RuntimeException();
    return pTextHelper->GetChild( i );
}

uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleParent(  )
{
    SolarMutexGuard aGuard;
    if (!pWin)
        throw RuntimeException();

    vcl::Window *pAccParent = pWin->GetAccessibleParentWindow();
    OSL_ENSURE( pAccParent, "accessible parent missing" );
    return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
}

sal_Int32 SAL_CALL SmEditAccessible::getAccessibleIndexInParent(  )
{
    SolarMutexGuard aGuard;
    sal_Int32 nIdx = -1;
    vcl::Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : nullptr;
    if (pAccParent)
    {
        sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
        for (sal_uInt16 i = 0;  i < nCnt  &&  nIdx == -1;  ++i)
            if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
                nIdx = i;
    }
    return nIdx;
}

sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole(  )
{
    return AccessibleRole::TEXT_FRAME;
}

OUString SAL_CALL SmEditAccessible::getAccessibleDescription(  )
{
    return OUString();  // empty as agreed with product-management
}

OUString SAL_CALL SmEditAccessible::getAccessibleName(  )
{
    SolarMutexGuard aGuard;
    // same name as displayed by the window when not docked
    return aAccName;
}

uno::Reference< XAccessibleRelationSet > SAL_CALL SmEditAccessible::getAccessibleRelationSet(  )
{
    Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
    return xRelSet;   // empty relation set
}

uno::Reference< XAccessibleStateSet > SAL_CALL SmEditAccessible::getAccessibleStateSet(  )
{
    SolarMutexGuard aGuard;
    rtl::Reference<::utl::AccessibleStateSetHelper> pStateSet =
            new ::utl::AccessibleStateSetHelper;

    if (!pWin || !pTextHelper)
        pStateSet->AddState( AccessibleStateType::DEFUNC );
    else
    {
        pStateSet->AddState( AccessibleStateType::MULTI_LINE );
        pStateSet->AddState( AccessibleStateType::ENABLED );
        pStateSet->AddState( AccessibleStateType::EDITABLE );
        pStateSet->AddState( AccessibleStateType::FOCUSABLE );
        if (pWin->HasFocus())
            pStateSet->AddState( AccessibleStateType::FOCUSED );
        if (pWin->IsActive())
            pStateSet->AddState( AccessibleStateType::ACTIVE );
        if (pWin->IsVisible())
            pStateSet->AddState( AccessibleStateType::SHOWING );
        if (pWin->IsReallyVisible())
            pStateSet->AddState( AccessibleStateType::VISIBLE );
        if (COL_TRANSPARENT != pWin->GetBackground().GetColor())
            pStateSet->AddState( AccessibleStateType::OPAQUE );
    }

    return pStateSet;
}

Locale SAL_CALL SmEditAccessible::getLocale(  )
{
    SolarMutexGuard aGuard;
    // should be the document language...
    // We use the language of the localized symbol names here.
    return Application::GetSettings().GetUILanguageTag().getLocale();
}


// XAccessibleEventBroadcaster
void SAL_CALL SmEditAccessible::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
{
    if (pTextHelper)   // not disposing (about to destroy view shell)
        pTextHelper->AddEventListener( xListener );
}

void SAL_CALL SmEditAccessible::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
{
   if (pTextHelper)   // not disposing (about to destroy view shell)
        pTextHelper->RemoveEventListener( xListener );
}

OUString SAL_CALL SmEditAccessible::getImplementationName()
{
    return "SmEditAccessible";
}

sal_Bool SAL_CALL SmEditAccessible::supportsService(
        const OUString& rServiceName )
{
    return  cppu::supportsService(this, rServiceName);
}

Sequence< OUString > SAL_CALL SmEditAccessible::getSupportedServiceNames()
{
    return {
        "css::accessibility::Accessible",
        "css::accessibility::AccessibleComponent",
        "css::accessibility::AccessibleContext"
    };
}


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/accessibility.hxx b/starmath/source/accessibility.hxx
index d93159b..817c4ca 100644
--- a/starmath/source/accessibility.hxx
+++ b/starmath/source/accessibility.hxx
@@ -135,223 +135,4 @@ public:
    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) override;
};


// classes and helper-classes used for accessibility in the command-window


class SmEditAccessible;
class SmEditSource;
class EditView;
class SvxFieldItem;


class SmViewForwarder :
    public SvxViewForwarder
{
    SmEditAccessible &          rEditAcc;

    SmViewForwarder( const SmViewForwarder & ) = delete;
    SmViewForwarder & operator = ( const SmViewForwarder & ) = delete;

public:
    explicit SmViewForwarder( SmEditAccessible &rAcc );
    virtual             ~SmViewForwarder() override;

    virtual bool        IsValid() const override;
    virtual Point       LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
    virtual Point       PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
};


class SmTextForwarder :     /* analog to SvxEditEngineForwarder */
    public SvxTextForwarder
{
    SmEditAccessible &  rEditAcc;
    SmEditSource &      rEditSource;

    DECL_LINK( NotifyHdl, EENotify&, void );

    SmTextForwarder( const SmTextForwarder & ) = delete;
    SmTextForwarder & operator = ( const SmTextForwarder & ) = delete;

public:
    SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource );
    virtual ~SmTextForwarder() override;

    virtual sal_Int32   GetParagraphCount() const override;
    virtual sal_Int32   GetTextLen( sal_Int32 nParagraph ) const override;
    virtual OUString    GetText( const ESelection& rSel ) const override;
    virtual SfxItemSet  GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib = EditEngineAttribs::All ) const override;
    virtual SfxItemSet  GetParaAttribs( sal_Int32 nPara ) const override;
    virtual void        SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet ) override;
    virtual void        RemoveAttribs( const ESelection& rSelection ) override;
    virtual void        GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const override;

    virtual SfxItemState  GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const override;
    virtual SfxItemState  GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const override;

    virtual void        QuickInsertText( const OUString& rText, const ESelection& rSel ) override;
    virtual void        QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel ) override;
    virtual void        QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel ) override;
    virtual void        QuickInsertLineBreak( const ESelection& rSel ) override;

    virtual SfxItemPool* GetPool() const override;

    virtual OUString        CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor ) override;
    virtual void            FieldClicked(const SvxFieldItem&) override;
    virtual bool            IsValid() const override;

    virtual LanguageType    GetLanguage( sal_Int32, sal_Int32 ) const override;
    virtual sal_Int32       GetFieldCount( sal_Int32 nPara ) const override;
    virtual EFieldInfo      GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const override;
    virtual EBulletInfo     GetBulletInfo( sal_Int32 nPara ) const override;
    virtual tools::Rectangle       GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const override;
    virtual tools::Rectangle       GetParaBounds( sal_Int32 nPara ) const override;
    virtual MapMode         GetMapMode() const override;
    virtual OutputDevice*   GetRefDevice() const override;
    virtual bool            GetIndexAtPoint( const Point&, sal_Int32& nPara, sal_Int32& nIndex ) const override;
    virtual bool            GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const override;
    virtual bool            GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell = false ) const override;
    virtual sal_Int32       GetLineCount( sal_Int32 nPara ) const override;
    virtual sal_Int32       GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const override;
    virtual void            GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const override;
    virtual sal_Int32       GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nLine ) const override;
    virtual bool            Delete( const ESelection& ) override;
    virtual bool            InsertText( const OUString&, const ESelection& ) override;
    virtual bool            QuickFormatDoc( bool bFull = false ) override;

    virtual sal_Int16       GetDepth( sal_Int32 nPara ) const override;
    virtual bool            SetDepth( sal_Int32 nPara, sal_Int16 nNewDepth ) override;

    virtual const SfxItemSet*   GetEmptyItemSetPtr() override;
    // implementation functions for XParagraphAppend and XTextPortionAppend
    virtual void        AppendParagraph() override;
    virtual sal_Int32   AppendTextPortion( sal_Int32 nPara, const OUString &rText, const SfxItemSet &rSet ) override;

    virtual void        CopyText(const SvxTextForwarder& rSource) override;
};


class SmEditViewForwarder :     /* analog to SvxEditEngineViewForwarder */
    public SvxEditViewForwarder
{
    SmEditAccessible&       rEditAcc;

    SmEditViewForwarder( const SmEditViewForwarder & ) = delete;
    SmEditViewForwarder & operator = ( const SmEditViewForwarder & ) = delete;

public:
    explicit SmEditViewForwarder( SmEditAccessible& rAcc );
    virtual             ~SmEditViewForwarder() override;

    virtual bool        IsValid() const override;

    virtual Point       LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
    virtual Point       PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;

    virtual bool        GetSelection( ESelection& rSelection ) const override;
    virtual bool        SetSelection( const ESelection& rSelection ) override;
    virtual bool        Copy() override;
    virtual bool        Cut() override;
    virtual bool        Paste() override;
};


class SmEditSource :
    public SvxEditSource
{
    SfxBroadcaster          aBroadCaster;
    SmViewForwarder         aViewFwd;
    SmTextForwarder         aTextFwd;
    SmEditViewForwarder     aEditViewFwd;

    SmEditAccessible&       rEditAcc;

    SmEditSource( const SmEditSource &rSrc );
    SmEditSource & operator = ( const SmEditSource & ) = delete;

public:
            SmEditSource( SmEditAccessible &rAcc );
    virtual ~SmEditSource() override;

    virtual std::unique_ptr<SvxEditSource> Clone() const override;
    virtual SvxTextForwarder*   GetTextForwarder() override;
    virtual SvxViewForwarder*  GetViewForwarder() override;
    virtual SvxEditViewForwarder*  GetEditViewForwarder( bool bCreate = false ) override;
    virtual void                UpdateData() override;
    virtual SfxBroadcaster&     GetBroadcaster() const override;
};


typedef
cppu::WeakImplHelper
    <
        css::lang::XServiceInfo,
        css::accessibility::XAccessible,
        css::accessibility::XAccessibleComponent,
        css::accessibility::XAccessibleContext,
        css::accessibility::XAccessibleEventBroadcaster
    >
SmEditAccessibleBaseClass;

class SmEditAccessible :
    public SmEditAccessibleBaseClass
{
    OUString                                aAccName;
    std::unique_ptr<::accessibility::AccessibleTextHelper> pTextHelper;
    VclPtr<SmEditWindow>                    pWin;

    SmEditAccessible( const SmEditAccessible & ) = delete;
    SmEditAccessible & operator = ( const SmEditAccessible & ) = delete;

public:
    explicit SmEditAccessible( SmEditWindow *pEditWin );
    virtual ~SmEditAccessible() override;

    ::accessibility::AccessibleTextHelper *   GetTextHelper();

    void                Init();
    void                ClearWin();     // to be called when view is destroyed

    //! access EditEngine and EditView via the functions in the respective window
    //! pointers may be 0 (e.g. during reload)
    EditEngine * GetEditEngine()    { return pWin ? pWin->GetEditEngine() : nullptr; }
    EditView   * GetEditView()      { return pWin ? pWin->GetEditView() : nullptr; }

    // XAccessible
    virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) override;

    // XAccessibleComponent
    virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
    virtual css::awt::Rectangle SAL_CALL getBounds(  ) override;
    virtual css::awt::Point SAL_CALL getLocation(  ) override;
    virtual css::awt::Point SAL_CALL getLocationOnScreen(  ) override;
    virtual css::awt::Size SAL_CALL getSize(  ) override;
    virtual void SAL_CALL grabFocus(  ) override;
    virtual sal_Int32 SAL_CALL getForeground(  ) override;
    virtual sal_Int32 SAL_CALL getBackground(  ) override;

    // XAccessibleContext
    virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) override;
    virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) override;
    virtual sal_Int16 SAL_CALL getAccessibleRole(  ) override;
    virtual OUString SAL_CALL getAccessibleDescription(  ) override;
    virtual OUString SAL_CALL getAccessibleName(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) override;
    virtual css::lang::Locale SAL_CALL getLocale(  ) override;

    // XAccessibleEventBroadcaster
    virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override;
    virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override;

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName(  ) override;
    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) override;
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/edit.cxx b/starmath/source/edit.cxx
index d06c1db..555e4d8 100644
--- a/starmath/source/edit.cxx
+++ b/starmath/source/edit.cxx
@@ -22,7 +22,7 @@

#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/settings.hxx>

#include <editeng/editview.hxx>
@@ -64,18 +64,68 @@ void SmGetLeftSelectionPart(const ESelection &rSel,
    }
}

bool SmEditWindow::IsInlineEditEnabled()
SmEditTextWindow::SmEditTextWindow(SmEditWindow& rEditWindow)
    : mrEditWindow(rEditWindow)
    , aModifyIdle("SmEditWindow ModifyIdle")
    , aCursorMoveIdle("SmEditWindow CursorMoveIdle")
{
    return SmViewShell::IsInlineEditEnabled();
    SetAcceptsTab(true);

    aModifyIdle.SetInvokeHandler(LINK(this, SmEditTextWindow, ModifyTimerHdl));
    aModifyIdle.SetPriority(TaskPriority::LOWEST);

    if (!SmViewShell::IsInlineEditEnabled())
    {
        aCursorMoveIdle.SetInvokeHandler(LINK(this, SmEditTextWindow, CursorMoveTimerHdl));
        aCursorMoveIdle.SetPriority(TaskPriority::LOWEST);
    }
}

SmEditTextWindow::~SmEditTextWindow()
{
    aModifyIdle.Stop();
    StartCursorMove();
}

SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) :
    Window              (&rMyCmdBoxWin, WB_BORDER),
    DropTargetHelper    ( this ),
    rCmdBox             (rMyCmdBoxWin),
    aModifyIdle         ("SmEditWindow ModifyIdle"),
    aCursorMoveIdle     ("SmEditWindow CursorMoveIdle")
EditEngine* SmEditTextWindow::GetEditEngine() const
{
    SmDocShell *pDoc = mrEditWindow.GetDoc();
    assert(pDoc);
    return &pDoc->GetEditEngine();
}

void SmEditTextWindow::EditViewScrollStateChange()
{
    mrEditWindow.SetScrollBarRanges();
}

void SmEditTextWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
{
    weld::CustomWidgetController::SetDrawingArea(pDrawingArea);

    EnableRTL(false);

    EditEngine* pEditEngine = GetEditEngine();

    m_xEditView.reset(new EditView(pEditEngine, nullptr));
    m_xEditView->setEditViewCallbacks(this);

    pEditEngine->InsertView(m_xEditView.get());

    m_xEditView->SetOutputArea(mrEditWindow.AdjustScrollBars());

    pDrawingArea->set_cursor(PointerStyle::Text);

    pEditEngine->SetStatusEventHdl(LINK(this, SmEditTextWindow, EditStatusHdl));

    InitAccessible();
}

SmEditWindow::SmEditWindow(SmCmdBoxWindow &rMyCmdBoxWin)
    : InterimItemWindow(&rMyCmdBoxWin, "modules/smath/ui/editwindow.ui", "EditWindow")
    , DropTargetHelper(this)
    , rCmdBox(rMyCmdBoxWin)
    , mxScrolledWindow(m_xBuilder->weld_scrolled_window("scrolledwindow", true))
{
    set_id("math_edit");
    SetHelpId(HID_SMA_COMMAND_WIN_EDIT);
@@ -87,21 +137,16 @@ SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) :
    // compare DataChanged
    SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );

    aModifyIdle.SetInvokeHandler(LINK(this, SmEditWindow, ModifyTimerHdl));
    aModifyIdle.SetPriority(TaskPriority::LOWEST);
    mxScrolledWindow->connect_hadjustment_changed(LINK(this, SmEditWindow, ScrollHdl));
    mxScrolledWindow->connect_vadjustment_changed(LINK(this, SmEditWindow, ScrollHdl));

    if (!IsInlineEditEnabled())
    {
        aCursorMoveIdle.SetInvokeHandler(LINK(this, SmEditWindow, CursorMoveTimerHdl));
        aCursorMoveIdle.SetPriority(TaskPriority::LOWEST);
    }
    CreateEditView();

    // if not called explicitly the this edit window within the
    // command window will just show an empty gray panel.
    Show();
}


SmEditWindow::~SmEditWindow()
{
    disposeOnce();
@@ -109,62 +154,17 @@ SmEditWindow::~SmEditWindow()

void SmEditWindow::dispose()
{
    aModifyIdle.Stop();
    DeleteEditView();

    StartCursorMove();

    // clean up of classes used for accessibility
    // must be done before EditView (and thus EditEngine) is no longer
    // available for those classes.
    if (mxAccessible.is())
    {
        mxAccessible->ClearWin();    // make Accessible nonfunctional
        mxAccessible.clear();
    }

    if (pEditView)
    {
        EditEngine *pEditEngine = pEditView->GetEditEngine();
        if (pEditEngine)
        {
            pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
            pEditEngine->RemoveView( pEditView.get() );
        }
        pEditView.reset();
    }

    pHScrollBar.disposeAndClear();
    pVScrollBar.disposeAndClear();
    pScrollBox.disposeAndClear();
    mxScrolledWindow.reset();

    DropTargetHelper::dispose();
    vcl::Window::dispose();
    InterimItemWindow::dispose();
}

OUString SmEditWindow::GetSurroundingText() const
void SmEditTextWindow::StartCursorMove()
{
    if (pEditView)
        return pEditView->GetSurroundingText();
    return OUString();
}

Selection SmEditWindow::GetSurroundingTextSelection() const
{
    if (pEditView)
        return pEditView->GetSurroundingTextSelection();
    return Selection(0, 0);
}

bool SmEditWindow::DeleteSurroundingText(const Selection& rSelection)
{
    if (pEditView)
        return pEditView->DeleteSurroundingText(rSelection);
    return false;
}

void SmEditWindow::StartCursorMove()
{
    if (!IsInlineEditEnabled())
    if (!SmViewShell::IsInlineEditEnabled())
        aCursorMoveIdle.Stop();
}

@@ -181,30 +181,22 @@ SmViewShell * SmEditWindow::GetView()
    return rCmdBox.GetView();
}


SmDocShell * SmEditWindow::GetDoc()
{
    SmViewShell *pView = rCmdBox.GetView();
    return pView ? pView->GetDoc() : nullptr;
}

EditView * SmEditWindow::GetEditView()
EditView * SmEditWindow::GetEditView() const
{
    return pEditView.get();
    return mxTextControl ? mxTextControl->GetEditView() : nullptr;
}

EditEngine * SmEditWindow::GetEditEngine()
{
    EditEngine *pEditEng = nullptr;
    if (pEditView)
        pEditEng = pEditView->GetEditEngine();
    else
    {
        SmDocShell *pDoc = GetDoc();
        if (pDoc)
            pEditEng = &pDoc->GetEditEngine();
    }
    return pEditEng;
    if (SmDocShell *pDoc = GetDoc())
        return &pDoc->GetEditEngine();
    return nullptr;
}

void SmEditWindow::ApplySettings(vcl::RenderContext& rRenderContext)
@@ -215,7 +207,7 @@ void SmEditWindow::ApplySettings(vcl::RenderContext& rRenderContext)

void SmEditWindow::DataChanged( const DataChangedEvent& rDCEvt )
{
    Window::DataChanged( rDCEvt );
    InterimItemWindow::DataChanged( rDCEvt );

    if (!((rDCEvt.GetType() == DataChangedEventType::FONTS) ||
          (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
@@ -247,36 +239,33 @@ void SmEditWindow::DataChanged( const DataChangedEvent& rDCEvt )
        AdjustScrollBars();
        Resize();
    }

    Invalidate();
}

IMPL_LINK_NOARG( SmEditWindow, ModifyTimerHdl, Timer *, void )
IMPL_LINK_NOARG(SmEditTextWindow, ModifyTimerHdl, Timer *, void)
{
    UpdateStatus(false);
    aModifyIdle.Stop();
}

IMPL_LINK_NOARG(SmEditWindow, CursorMoveTimerHdl, Timer *, void)
IMPL_LINK_NOARG(SmEditTextWindow, CursorMoveTimerHdl, Timer *, void)
    // every once in a while check cursor position (selection) of edit
    // window and if it has changed (try to) set the formula-cursor
    // according to that.
{
    if (IsInlineEditEnabled())
    if (SmViewShell::IsInlineEditEnabled())
        return;

    ESelection aNewSelection(GetSelection());

    if (aNewSelection != aOldSelection)
    {
        SmViewShell *pView = rCmdBox.GetView();
        if (pView)
        if (SmViewShell *pViewSh = mrEditWindow.GetView())
        {
            // get row and column to look for
            sal_Int32  nRow;
            sal_uInt16 nCol;
            SmGetLeftSelectionPart(aNewSelection, nRow, nCol);
            pView->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
            pViewSh->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
            aOldSelection = aNewSelection;
        }
    }
@@ -285,10 +274,9 @@ IMPL_LINK_NOARG(SmEditWindow, CursorMoveTimerHdl, Timer *, void)

void SmEditWindow::Resize()
{
    if (!pEditView)
        CreateEditView();
    InterimItemWindow::Resize();

    if (pEditView)
    if (EditView* pEditView = GetEditView())
    {
        // Resizes the edit engine to adjust to the size of the output area
        const Size aSize( pEditView->GetOutputArea().GetSize() );
@@ -308,336 +296,271 @@ void SmEditWindow::Resize()
            pEditView->SetVisArea(aVisArea);
            pEditView->ShowCursor();
        }
        InitScrollBars();
        SetScrollBarRanges();
    }
    Invalidate();
}

void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt)
bool SmEditTextWindow::MouseButtonUp(const MouseEvent &rEvt)
{
    if (pEditView)
        pEditView->MouseButtonUp(rEvt);
    else
        Window::MouseButtonUp (rEvt);

    if (!IsInlineEditEnabled())
    bool bRet = WeldEditView::MouseButtonUp(rEvt);
    if (!SmViewShell::IsInlineEditEnabled())
        CursorMoveTimerHdl(&aCursorMoveIdle);
    InvalidateSlots();
}

void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt)
{
    if (pEditView)
        pEditView->MouseButtonDown(rEvt);
    else
        Window::MouseButtonDown (rEvt);

    GrabFocus();
    mrEditWindow.InvalidateSlots();
    return bRet;
}

void SmEditWindow::Command(const CommandEvent& rCEvt)
{
    //pass alt press/release to parent impl
    if (rCEvt.GetCommand() == CommandEventId::ModKeyChange)
    {
        Window::Command(rCEvt);
        return;
    }

    bool bForwardEvt = true;
    if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
    {
        GetParent()->ToTop();

        Point aPoint = rCEvt.GetMousePosPixel();
        SmViewShell* pViewSh = rCmdBox.GetView();
        SmViewShell *pViewSh = GetView();
        if (pViewSh)
            pViewSh->GetViewFrame()->GetDispatcher()->ExecutePopup("edit", this, &aPoint);
        bForwardEvt = false;
        return;
    }
    else if (rCEvt.GetCommand() == CommandEventId::Wheel)
        bForwardEvt = !HandleWheelCommands( rCEvt );

    if (bForwardEvt)
    {
        if (pEditView)
        {
            if (pEditView->Command(rCEvt))
                UserPossiblyChangedText();
        }
        else
            Window::Command (rCEvt);
    }
    InterimItemWindow::Command(rCEvt);
}

bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt )
bool SmEditTextWindow::Command(const CommandEvent& rCEvt)
{
    bool bCommandHandled = false;    // true if the CommandEvent needs not
                                    // to be passed on (because it has fully
                                    // been taken care of).

    // no zooming in Command window
    const CommandWheelData* pWData = rCEvt.GetWheelData();
    if (pWData)
    if (pWData && CommandWheelMode::ZOOM == pWData->GetMode())
        return true;

    //pass alt press/release to parent impl
    if (rCEvt.GetCommand() == CommandEventId::ModKeyChange)
        return false;

    if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
    {
        if (CommandWheelMode::ZOOM == pWData->GetMode())
            bCommandHandled = true;     // no zooming in Command window
        else
            bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar.get(), pVScrollBar.get());
        // purely for "ExecutePopup" taking a vcl::Window and
        // we assume SmEditTextWindow 0,0 is at SmEditWindow 0,0
        mrEditWindow.Command(rCEvt);
        return false;
    }

    return bCommandHandled;
    bool bConsumed = WeldEditView::Command(rCEvt);
    if (bConsumed)
        UserPossiblyChangedText();
    return bConsumed;
}

void SmEditWindow::KeyInput(const KeyEvent& rKEvt)
bool SmEditTextWindow::KeyInput(const KeyEvent& rKEvt)
{
    if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
    {
        bool bCallBase = true;
        SfxViewShell* pViewShell = GetView();
        SfxViewShell* pViewShell = mrEditWindow.GetView();
        if ( dynamic_cast<const SmViewShell *>(pViewShell) )
        {
            // Terminate possible InPlace mode
            bCallBase = !pViewShell->Escape();
        }
        if ( bCallBase )
            Window::KeyInput( rKEvt );
        return !bCallBase;
    }
    else

    StartCursorMove();

    bool autoClose = false;
    EditView* pEditView = GetEditView();
    ESelection aSelection = pEditView->GetSelection();
    // as we don't support RTL in Math, we need to swap values from selection when they were done
    // in RTL form
    aSelection.Adjust();
    OUString selected = pEditView->GetEditEngine()->GetText(aSelection);

    // Check is auto close brackets/braces is disabled
    SmModule *pMod = SM_MOD();
    if (pMod && !pMod->GetConfig()->IsAutoCloseBrackets())
        autoClose = false;
    else if (selected.trim() == "<?>")
        autoClose = true;
    else if (selected.isEmpty() && !aSelection.HasRange())
    {
        StartCursorMove();

        bool autoClose = false;
        if (!pEditView)
            CreateEditView();
        ESelection aSelection = pEditView->GetSelection();
        // as we don't support RTL in Math, we need to swap values from selection when they were done
        // in RTL form
        aSelection.Adjust();
        OUString selected = pEditView->GetEditEngine()->GetText(aSelection);

        // Check is auto close brackets/braces is disabled
        SmModule *pMod = SM_MOD();
        if (pMod && !pMod->GetConfig()->IsAutoCloseBrackets())
            autoClose = false;
        else if (selected.trim() == "<?>")
            autoClose = true;
        else if (selected.isEmpty() && !aSelection.HasRange())
        selected = pEditView->GetEditEngine()->GetText(aSelection.nEndPara);
        if (!selected.isEmpty())
        {
            selected = pEditView->GetEditEngine()->GetText(aSelection.nEndPara);
            if (!selected.isEmpty())
            sal_Int32 index = selected.indexOf("\n", aSelection.nEndPos);
            if (index != -1)
            {
                sal_Int32 index = selected.indexOf("\n", aSelection.nEndPos);
                if (index != -1)
                {
                    selected = selected.copy(index, sal_Int32(aSelection.nEndPos-index));
                    if (selected.trim().isEmpty())
                        autoClose = true;
                }
                selected = selected.copy(index, sal_Int32(aSelection.nEndPos-index));
                if (selected.trim().isEmpty())
                    autoClose = true;
            }
            else
            {
                sal_Int32 length = selected.getLength();
                if (aSelection.nEndPos == length)
                    autoClose = true;
                else
                {
                    sal_Int32 length = selected.getLength();
                    if (aSelection.nEndPos == length)
                    selected = selected.copy(aSelection.nEndPos);
                    if (selected.trim().isEmpty())
                        autoClose = true;
                    else
                    {
                        selected = selected.copy(aSelection.nEndPos);
                        if (selected.trim().isEmpty())
                            autoClose = true;
                    }
                }
            }
            else
                autoClose = true;
        }

        if ( !pEditView->PostKeyEvent(rKEvt) )
        {
            SmViewShell *pView = GetView();
            if ( pView && !pView->KeyInput(rKEvt) )
            {
                // F1 (help) leads to the destruction of this
                Flush();
                if ( aModifyIdle.IsActive() )
                    aModifyIdle.Stop();
                Window::KeyInput(rKEvt);
            }
            else
            {
                // SFX has maybe called a slot of the view and thus (because of a hack in SFX)
                // set the focus to the view
                SmViewShell* pVShell = GetView();
                if ( pVShell && pVShell->GetGraphicWindow().HasFocus() )
                {
                    GrabFocus();
                }
            }
        }
        else
        {
            UserPossiblyChangedText();
        }

        // get the current char of the key event
        sal_Unicode cCharCode = rKEvt.GetCharCode();
        OUString sClose;

        if (cCharCode == '{')
            sClose = "  }";
        else if (cCharCode == '[')
            sClose = "  ]";
        else if (cCharCode == '(')
            sClose = "  )";

        // auto close the current character only when needed
        if (!sClose.isEmpty() && autoClose)
        {
            pEditView->InsertText(sClose);
            // position it at center of brackets
            aSelection.nStartPos += 2;
            aSelection.nEndPos = aSelection.nStartPos;
            pEditView->SetSelection(aSelection);
        }

        InvalidateSlots();
            autoClose = true;
    }

    bool bConsumed = WeldEditView::KeyInput(rKEvt);
    if (!bConsumed)
    {
        SmViewShell *pView = mrEditWindow.GetView();
        if ( pView && !pView->KeyInput(rKEvt) )
        {
            // F1 (help) leads to the destruction of this
            Flush();
            if ( aModifyIdle.IsActive() )
                aModifyIdle.Stop();
        }
        else
        {
            // SFX has maybe called a slot of the view and thus (because of a hack in SFX)
            // set the focus to the view
            SmViewShell* pVShell = mrEditWindow.GetView();
            if ( pVShell && pVShell->GetGraphicWindow().HasFocus() )
            {
                GrabFocus();
            }
        }
    }
    else
    {
        UserPossiblyChangedText();
    }

    // get the current char of the key event
    sal_Unicode cCharCode = rKEvt.GetCharCode();
    OUString sClose;

    if (cCharCode == '{')
        sClose = "  }";
    else if (cCharCode == '[')
        sClose = "  ]";
    else if (cCharCode == '(')
        sClose = "  )";

    // auto close the current character only when needed
    if (!sClose.isEmpty() && autoClose)
    {
        pEditView->InsertText(sClose);
        // position it at center of brackets
        aSelection.nStartPos += 2;
        aSelection.nEndPos = aSelection.nStartPos;
        pEditView->SetSelection(aSelection);
    }

    mrEditWindow.InvalidateSlots();
    return bConsumed;
}

void SmEditWindow::UserPossiblyChangedText()
void SmEditTextWindow::UserPossiblyChangedText()
{
    // have doc-shell modified only for formula input/change and not
    // cursor travelling and such things...
    SmDocShell *pDocShell = GetDoc();
    SmDocShell *pDocShell = mrEditWindow.GetDoc();
    EditEngine *pEditEngine = GetEditEngine();
    if (pDocShell && pEditEngine)
        pDocShell->SetModified(pEditEngine->IsModified());
    aModifyIdle.Start();
}

void SmEditWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
    if (!pEditView)
        CreateEditView();
    pEditView->Paint(rRect, &rRenderContext);
}

void SmEditWindow::CreateEditView()
{
    EditEngine *pEditEngine = GetEditEngine();
    assert(!mxTextControl);

    //! pEditEngine and pEditView may be 0.
    EditEngine *pEditEngine = GetEditEngine();
    //! pEditEngine may be 0.
    //! For example when the program is used by the document-converter
    if (pEditView || !pEditEngine)
    if (!pEditEngine)
        return;

    pEditView.reset(new EditView(pEditEngine, this));
    pEditEngine->InsertView( pEditView.get() );

    if (!pVScrollBar)
        pVScrollBar = VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL));
    if (!pHScrollBar)
        pHScrollBar = VclPtr<ScrollBar>::Create(this, WinBits(WB_HSCROLL));
    if (!pScrollBox)
        pScrollBox  = VclPtr<ScrollBarBox>::Create(this);
    pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
    pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
    pVScrollBar->EnableDrag();
    pHScrollBar->EnableDrag();

    pEditView->SetOutputArea(AdjustScrollBars());

    ESelection eSelection;

    pEditView->SetSelection(eSelection);
    PaintImmediately();
    pEditView->ShowCursor();

    pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
    SetPointer(pEditView->GetPointer());
    mxTextControl.reset(new SmEditTextWindow(*this));
    mxTextControlWin.reset(new weld::CustomWeld(*m_xBuilder, "editview", *mxTextControl));
    InitControlBase(mxTextControl->GetDrawingArea());

    SetScrollBarRanges();
}


IMPL_LINK_NOARG( SmEditWindow, EditStatusHdl, EditStatus&, void )
IMPL_LINK_NOARG(SmEditTextWindow, EditStatusHdl, EditStatus&, void)
{
    if (pEditView)
        Resize();
    if (GetEditView())
        mrEditWindow.Resize();
}

IMPL_LINK( SmEditWindow, ScrollHdl, ScrollBar *, /*pScrollBar*/, void )
IMPL_LINK(SmEditWindow, ScrollHdl, weld::ScrolledWindow&, rScrolledWindow, void)
{
    OSL_ENSURE(pEditView, "EditView missing");
    if (pEditView)
    if (EditView* pEditView = GetEditView())
    {
        pEditView->SetVisArea(tools::Rectangle(Point(pHScrollBar->GetThumbPos(),
                                            pVScrollBar->GetThumbPos()),
                                        pEditView->GetVisArea().GetSize()));
        pEditView->SetVisArea(tools::Rectangle(
                    Point(rScrolledWindow.hadjustment_get_value(),
                          rScrolledWindow.vadjustment_get_value()),
                    pEditView->GetVisArea().GetSize()));
        pEditView->Invalidate();
    }
}

tools::Rectangle SmEditWindow::AdjustScrollBars()
{
    const Size aOut( GetOutputSizePixel() );
    tools::Rectangle aRect( Point(), aOut );
    tools::Rectangle aRect(Point(), GetOutputSizePixel());

    if (pVScrollBar && pHScrollBar && pScrollBox)
    if (mxScrolledWindow)
    {
        const tools::Long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
        Point aPt( aRect.TopRight() ); aPt.AdjustX( -(nTmp -1) );
        pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp));

        aPt = aRect.BottomLeft(); aPt.AdjustY( -(nTmp - 1) );
        pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp));

        aPt.setX( pHScrollBar->GetSizePixel().Width() );
        aPt.setY( pVScrollBar->GetSizePixel().Height() );
        pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp ));

        aRect.SetRight( aPt.X() - 2 );
        aRect.SetBottom( aPt.Y() - 2 );
        const auto nScrollSize = mxScrolledWindow->get_scroll_thickness();
        const auto nMargin = nScrollSize + 2;
        aRect.AdjustRight(-nMargin);
        aRect.AdjustBottom(-nMargin);
    }

    return aRect;
}

void SmEditWindow::SetScrollBarRanges()
{
    // Extra method, not InitScrollBars, since it's also being used for EditEngine events
    EditEngine *pEditEngine = GetEditEngine();
    if (pVScrollBar && pHScrollBar && pEditEngine && pEditView)
    {
        tools::Long nTmp = pEditEngine->GetTextHeight();
        pVScrollBar->SetRange(Range(0, nTmp));
        pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top());

        nTmp = pEditEngine->GetPaperSize().Width();
        pHScrollBar->SetRange(Range(0,nTmp));
        pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left());
    }
}

void SmEditWindow::InitScrollBars()
{
    if (!(pVScrollBar && pHScrollBar && pScrollBox && pEditView))
    if (!pEditEngine)
        return;
    if (!mxScrolledWindow)
        return;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    const Size aOut( pEditView->GetOutputArea().GetSize() );
    pVScrollBar->SetVisibleSize(aOut.Height());
    pVScrollBar->SetPageSize(aOut.Height() * 8 / 10);
    pVScrollBar->SetLineSize(aOut.Height() * 2 / 10);
    int nVUpper = pEditEngine->GetTextHeight();
    int nHUpper = pEditEngine->GetPaperSize().Width();
    int nVCurrentDocPos = pEditView->GetVisArea().Top();
    int nHCurrentDocPos = pEditView->GetVisArea().Left();
    const Size aOut(pEditView->GetOutputArea().GetSize());
    int nVStepIncrement = aOut.Height() * 2 / 10;
    int nHStepIncrement = SCROLL_LINE;
    int nVPageIncrement = aOut.Height() * 8 / 10;
    int nHPageIncrement = aOut.Width() * 8 / 10;
    int nVPageSize = aOut.Height();
    int nHPageSize = aOut.Width();

    pHScrollBar->SetVisibleSize(aOut.Width());
    pHScrollBar->SetPageSize(aOut.Width() * 8 / 10);
    pHScrollBar->SetLineSize(SCROLL_LINE );
    /* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has
       effectively...

    SetScrollBarRanges();
       lower = gtk_adjustment_get_lower
       upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size

    pVScrollBar->Show();
    pHScrollBar->Show();
    pScrollBox->Show();
       and requires that upper > lower or the deceleration animation never ends
    */
    nVPageSize = std::min(nVPageSize, nVUpper);
    nHPageSize = std::min(nHPageSize, nHUpper);

    mxScrolledWindow->vadjustment_configure(nVCurrentDocPos, 0, nVUpper,
                                            nVStepIncrement, nVPageIncrement, nVPageSize);
    mxScrolledWindow->hadjustment_configure(nHCurrentDocPos, 0, nHUpper,
                                            nHStepIncrement, nHPageIncrement, nHPageSize);
}


OUString SmEditWindow::GetText() const
{
    OUString aText;
@@ -648,17 +571,21 @@ OUString SmEditWindow::GetText() const
    return aText;
}


void SmEditWindow::SetText(const OUString& rText)
{
    if (!mxTextControl)
        return;
    mxTextControl->SetText(rText);
}

void SmEditTextWindow::SetText(const OUString& rText)
{
    EditEngine *pEditEngine = GetEditEngine();
    OSL_ENSURE( pEditEngine, "EditEngine missing" );
    if (!pEditEngine || pEditEngine->IsModified())
        return;

    if (!pEditView)
        CreateEditView();

    EditView* pEditView = GetEditView();
    ESelection eSelection = pEditView->GetSelection();

    pEditEngine->SetText(rText);
@@ -671,76 +598,54 @@ void SmEditWindow::SetText(const OUString& rText)
    pEditView->SetSelection(eSelection);
}


void SmEditWindow::GetFocus()
void SmEditTextWindow::GetFocus()
{
    Window::GetFocus();
    WeldEditView::GetFocus();

    if (mxAccessible.is())
    {
        // Note: will implicitly send the AccessibleStateType::FOCUSED event
        ::accessibility::AccessibleTextHelper *pHelper = mxAccessible->GetTextHelper();
        if (pHelper)
            pHelper->SetFocus();
    }

    if (!pEditView)
         CreateEditView();
    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
        pEditEngine->SetStatusEventHdl(LINK(this, SmEditTextWindow, EditStatusHdl));

    //Let SmViewShell know we got focus
    if(GetView() && IsInlineEditEnabled())
        GetView()->SetInsertIntoEditWindow(true);
    if (mrEditWindow.GetView() && SmViewShell::IsInlineEditEnabled())
        mrEditWindow.GetView()->SetInsertIntoEditWindow(true);
}


void SmEditWindow::LoseFocus()
void SmEditTextWindow::LoseFocus()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );

    Window::LoseFocus();

    if (mxAccessible.is())
    {
        // Note: will implicitly send the AccessibleStateType::FOCUSED event
        ::accessibility::AccessibleTextHelper *pHelper = mxAccessible->GetTextHelper();
        if (pHelper)
            pHelper->SetFocus(false);
    }
    WeldEditView::LoseFocus();
}


bool SmEditWindow::IsAllSelected() const
{
    bool bRes = false;
    EditEngine *pEditEngine = const_cast<SmEditWindow *>(this)->GetEditEngine();
    OSL_ENSURE( pEditView, "NULL pointer" );
    OSL_ENSURE( pEditEngine, "NULL pointer" );
    if (pEditEngine  &&  pEditView)
    if (!pEditEngine)
        return false;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return false;
    bool bRes = false;
    ESelection eSelection( pEditView->GetSelection() );
    sal_Int32 nParaCnt = pEditEngine->GetParagraphCount();
    if (!(nParaCnt - 1))
    {
        ESelection eSelection( pEditView->GetSelection() );
        sal_Int32 nParaCnt = pEditEngine->GetParagraphCount();
        if (!(nParaCnt - 1))
        {
            sal_Int32 nTextLen = pEditEngine->GetText().getLength();
            bRes = !eSelection.nStartPos && (eSelection.nEndPos == nTextLen - 1);
        }
        else
        {
            bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1);
        }
        sal_Int32 nTextLen = pEditEngine->GetText().getLength();
        bRes = !eSelection.nStartPos && (eSelection.nEndPos == nTextLen - 1);
    }
    else
    {
        bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1);
    }
    return bRes;
}

void SmEditWindow::SelectAll()
{
    OSL_ENSURE( pEditView, "NULL pointer" );
    if (pEditView)
    if (EditView* pEditView = GetEditView())
    {
        // ALL as last two parameters refers to the end of the text
        pEditView->SetSelection( ESelection( 0, 0, EE_PARA_ALL, EE_TEXTPOS_ALL ) );
@@ -749,8 +654,7 @@ void SmEditWindow::SelectAll()

void SmEditWindow::MarkError(const Point &rPos)
{
    OSL_ENSURE( pEditView, "EditView missing" );
    if (pEditView)
    if (EditView* pEditView = GetEditView())
    {
        const sal_uInt16        nCol = sal::static_int_cast< sal_uInt16 >(rPos.X());
        const sal_uInt16        nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1);
@@ -760,13 +664,21 @@ void SmEditWindow::MarkError(const Point &rPos)
    }
}

// Makes selection to next <?> symbol
void SmEditWindow::SelNextMark()
{
    if (!mxTextControl)
        return;
    mxTextControl->SelNextMark();
}

// Makes selection to next <?> symbol
void SmEditTextWindow::SelNextMark()
{
    EditEngine *pEditEngine = GetEditEngine();
    OSL_ENSURE( pEditView, "NULL pointer" );
    OSL_ENSURE( pEditEngine, "NULL pointer" );
    if (!pEditEngine || !pEditView)
    if (!pEditEngine)
        return;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    ESelection eSelection = pEditView->GetSelection();
@@ -792,9 +704,10 @@ void SmEditWindow::SelNextMark()
void SmEditWindow::SelPrevMark()
{
    EditEngine *pEditEngine = GetEditEngine();
    OSL_ENSURE( pEditEngine, "NULL pointer" );
    OSL_ENSURE( pEditView, "NULL pointer" );
    if (!(pEditEngine  &&  pEditView))
    if (!pEditEngine)
        return;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    ESelection eSelection = pEditView->GetSelection();
@@ -814,18 +727,12 @@ void SmEditWindow::SelPrevMark()
    pEditView->SetSelection(ESelection(nPara, nPos, nPara, nPos + 3));
}

bool SmEditWindow::HasMark(const OUString& rText)
    // returns true iff 'rText' contains a mark
// returns true iff 'rText' contains a mark
static bool HasMark(const OUString& rText)
{
    return rText.indexOf("<?>") != -1;
}

void SmEditWindow::MouseMove(const MouseEvent &rEvt)
{
    if (pEditView)
        pEditView->MouseMove(rEvt);
}

sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
{
    return DND_ACTION_NONE;
@@ -838,19 +745,23 @@ sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )

ESelection SmEditWindow::GetSelection() const
{
    if (mxTextControl)
        return mxTextControl->GetSelection();
    return ESelection();
}

ESelection SmEditTextWindow::GetSelection() const
{
    // pointer may be 0 when reloading a document and the old view
    // was already destroyed
    //(OSL_ENSURE( pEditView, "NULL pointer" );
    ESelection eSel;
    if (pEditView)
        eSel = pEditView->GetSelection();
    return eSel;
    if (EditView* pEditView = GetEditView())
        return pEditView->GetSelection();
    return ESelection();
}

void SmEditWindow::SetSelection(const ESelection &rSel)
{
    OSL_ENSURE( pEditView, "NULL pointer" );
    if (pEditView)
    if (EditView* pEditView = GetEditView())
        pEditView->SetSelection(rSel);
    InvalidateSlots();
}
@@ -864,59 +775,74 @@ bool SmEditWindow::IsEmpty() const

bool SmEditWindow::IsSelected() const
{
    EditView* pEditView = GetEditView();
    return pEditView && pEditView->HasSelection();
}


void SmEditWindow::UpdateStatus( bool bSetDocModified )
void SmEditTextWindow::UpdateStatus(bool bSetDocModified)
{
    SmModule *pMod = SM_MOD();
    if (pMod && pMod->GetConfig()->IsAutoRedraw())
        Flush();
    if ( bSetDocModified )
        GetDoc()->SetModified();
        mrEditWindow.GetDoc()->SetModified();
}

void SmEditWindow::Cut()
{
    OSL_ENSURE( pEditView, "EditView missing" );
    if (pEditView)
    if (mxTextControl)
    {
        pEditView->Cut();
        UpdateStatus(true);
        mxTextControl->Cut();
        mxTextControl->UpdateStatus(true);
    }
}

void SmEditWindow::Copy()
{
    OSL_ENSURE( pEditView, "EditView missing" );
    if (pEditView)
        pEditView->Copy();
    if (mxTextControl)
        mxTextControl->Copy();
}

void SmEditWindow::Paste()
{
    OSL_ENSURE( pEditView, "EditView missing" );
    if (pEditView)
    if (mxTextControl)
    {
        pEditView->Paste();
        UpdateStatus(true);
        mxTextControl->Paste();
        mxTextControl->UpdateStatus(true);
    }
}

void SmEditWindow::Delete()
{
    OSL_ENSURE( pEditView, "EditView missing" );
    if (pEditView)
    if (mxTextControl)
    {
        pEditView->DeleteSelected();
        UpdateStatus(true);
        mxTextControl->Delete();
        mxTextControl->UpdateStatus(true);
    }
}

void SmEditWindow::InsertText(const OUString& rText)
{
    OSL_ENSURE( pEditView, "EditView missing" );
    if (!mxTextControl)
        return;
    mxTextControl->InsertText(rText);
}

void SmEditWindow::HideScrollbars()
{
    mxScrolledWindow->set_vpolicy(VclPolicyType::NEVER);
    mxScrolledWindow->set_hpolicy(VclPolicyType::NEVER);
}

void SmEditWindow::ShowScrollbars()
{
    mxScrolledWindow->set_vpolicy(VclPolicyType::ALWAYS);
    mxScrolledWindow->set_hpolicy(VclPolicyType::ALWAYS);
}

void SmEditTextWindow::InsertText(const OUString& rText)
{
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

@@ -950,12 +876,10 @@ void SmEditWindow::InsertText(const OUString& rText)
      This change "solves" the visual problem. But I don't think so
      this is the best solution.
    */
    pVScrollBar->Hide();
    pHScrollBar->Hide();
    mrEditWindow.HideScrollbars();
    pEditView->InsertText(string);
    AdjustScrollBars();
    pVScrollBar->Show();
    pHScrollBar->Show();
    mrEditWindow.AdjustScrollBars();
    mrEditWindow.ShowScrollbars();

    // Remember start of the selection and move the cursor there afterwards.
    aSelection.nEndPara = aSelection.nStartPara;
@@ -974,17 +898,17 @@ void SmEditWindow::InsertText(const OUString& rText)

    aModifyIdle.Start();
    StartCursorMove();

    GrabFocus();
}

void SmEditWindow::Flush()
void SmEditTextWindow::Flush()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine  &&  pEditEngine->IsModified())
    {
        pEditEngine->ClearModifyFlag();
        SmViewShell *pViewSh = rCmdBox.GetView();
        if (pViewSh)
        if (SmViewShell *pViewSh = mrEditWindow.GetView())
        {
            std::unique_ptr<SfxStringItem> pTextToFlush = std::make_unique<SfxStringItem>(SID_TEXT, GetText());
            pViewSh->GetViewFrame()->GetDispatcher()->ExecuteList(
@@ -1001,26 +925,17 @@ void SmEditWindow::Flush()

void SmEditWindow::DeleteEditView()
{
    if (pEditView)
    if (EditView* pEditView = GetEditView())
    {
        std::unique_ptr<EditEngine> xEditEngine(pEditView->GetEditEngine());
        if (xEditEngine)
        if (EditEngine* pEditEngine = pEditView->GetEditEngine())
        {
            xEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
            xEditEngine->RemoveView( pEditView.get() );
            pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
            pEditEngine->RemoveView(pEditView);
        }
        pEditView.reset();
        InitControlBase(nullptr);
        mxTextControlWin.reset();
        mxTextControl.reset();
    }
}

uno::Reference< XAccessible > SmEditWindow::CreateAccessible()
{
    if (!mxAccessible.is())
    {
        mxAccessible.set(new SmEditAccessible( this ));
        mxAccessible->Init();
    }
    return mxAccessible;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/uiconfig/smath/ui/editwindow.ui b/starmath/uiconfig/smath/ui/editwindow.ui
new file mode 100644
index 0000000..ca7794f
--- /dev/null
+++ b/starmath/uiconfig/smath/ui/editwindow.ui
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface domain="sm">
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkBox" id="EditWindow">
    <property name="visible">True</property>
    <property name="can-focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="spacing">6</property>
    <child>
      <object class="GtkScrolledWindow" id="scrolledwindow">
        <property name="visible">True</property>
        <property name="can-focus">True</property>
        <property name="border-width">0</property>
        <property name="hscrollbar-policy">always</property>
        <property name="vscrollbar-policy">always</property>
        <property name="shadow-type">etched-out</property>
        <child>
          <object class="GtkViewport">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkDrawingArea" id="editview">
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK</property>
                <child internal-child="accessible">
                  <object class="AtkObject" id="editview-atkobject">
                    <property name="AtkObject::accessible-description" translatable="yes" context="headerfootercontent|extended_tip|textviewWND_LEFT">Enter the text to be displayed at the left side of the header or footer.</property>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="expand">True</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/svx/source/dialog/weldeditview.cxx b/svx/source/dialog/weldeditview.cxx
index f08abb3..b558d9f3 100644
--- a/svx/source/dialog/weldeditview.cxx
+++ b/svx/source/dialog/weldeditview.cxx
@@ -67,6 +67,12 @@ bool WeldEditView::HasSelection() const
    return pEditView && pEditView->HasSelection();
}

void WeldEditView::Delete()
{
    if (EditView* pEditView = GetEditView())
        pEditView->DeleteSelected();
}

void WeldEditView::Cut()
{
    if (EditView* pEditView = GetEditView())
@@ -85,7 +91,10 @@ void WeldEditView::Paste()
        pEditView->Paste();
}

WeldEditView::WeldEditView() {}
WeldEditView::WeldEditView()
    : m_bAcceptsTab(false)
{
}

// tdf#127033 want to use UI font so override makeEditEngine to enable that
void WeldEditView::makeEditEngine()
@@ -203,7 +212,7 @@ bool WeldEditView::KeyInput(const KeyEvent& rKEvt)

    sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();

    if (nKey == KEY_TAB)
    if (nKey == KEY_TAB && !GetAcceptsTab())
    {
        return false;
    }