weld OfaAutocorrReplacePage

Change-Id: I143792cfe123942d44b2e39cb1910a5127b2f592
Reviewed-on: https://gerrit.libreoffice.org/64254
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/source/inc/autocdlg.hxx b/cui/source/inc/autocdlg.hxx
index 55e1fed..bc8739a 100644
--- a/cui/source/inc/autocdlg.hxx
+++ b/cui/source/inc/autocdlg.hxx
@@ -233,49 +233,51 @@ typedef std::map<LanguageType, StringChangeList> StringChangeTable;

class OfaAutocorrReplacePage : public SfxTabPage
{
        using TabPage::ActivatePage;
        using TabPage::DeactivatePage;
    using TabPage::ActivatePage;
    using TabPage::DeactivatePage;

private:

        StringChangeTable aChangesTable;
    StringChangeTable aChangesTable;

        VclPtr<CheckBox>       m_pTextOnlyCB;
        VclPtr<AutoCorrEdit>   m_pShortED;
        VclPtr<AutoCorrEdit>   m_pReplaceED;
        VclPtr<SvTabListBox>   m_pReplaceTLB;
        VclPtr<PushButton>     m_pNewReplacePB;
        VclPtr<PushButton>     m_pDeleteReplacePB;
    OUString        sModify;
    OUString        sNew;

        OUString        sModify;
        OUString        sNew;
    std::set<OUString>      aFormatText;
    std::map<LanguageType, DoubleStringArray>
                            aDoubleStringTable;
    std::unique_ptr<CollatorWrapper>  pCompareClass;
    std::unique_ptr<CharClass>        pCharClass;
    LanguageType            eLang;

        std::set<OUString>      aFormatText;
        std::map<LanguageType, DoubleStringArray>
                                aDoubleStringTable;
        std::unique_ptr<CollatorWrapper>  pCompareClass;
        std::unique_ptr<CharClass>        pCharClass;
        LanguageType            eLang;
    bool bHasSelectionText;
    bool bFirstSelect:1;
    bool bReplaceEditChanged:1;
    bool bSWriter:1;

        bool bHasSelectionText;
        bool bFirstSelect:1;
        bool bReplaceEditChanged:1;
        bool bSWriter:1;
    std::unique_ptr<weld::CheckButton> m_xTextOnlyCB;
    std::unique_ptr<weld::Entry> m_xShortED;
    std::unique_ptr<weld::Entry> m_xReplaceED;
    std::unique_ptr<weld::TreeView> m_xReplaceTLB;
    std::unique_ptr<weld::Button> m_xNewReplacePB;
    std::unique_ptr<weld::Button> m_xReplacePB;
    std::unique_ptr<weld::Button> m_xDeleteReplacePB;

        DECL_LINK(SelectHdl, SvTreeListBox*, void);
        DECL_LINK(NewDelButtonHdl, Button*, void);
        DECL_LINK(NewDelActionHdl, AutoCorrEdit&, bool);
        DECL_LINK(ModifyHdl, Edit&, void);
        bool NewDelHdl(void const *);
    DECL_LINK(SelectHdl, weld::TreeView&, void);
    DECL_LINK(NewDelButtonHdl, weld::Button&, void);
    DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
    DECL_LINK(EntrySizeAllocHdl, const Size&, void);
    DECL_LINK(ModifyHdl, weld::Entry&, void);
    bool NewDelHdl(const weld::Widget*);

        void RefillReplaceBox(  bool bFromReset,
                                LanguageType eOldLanguage,
                                LanguageType eNewLanguage);
    void RefillReplaceBox(  bool bFromReset,
                            LanguageType eOldLanguage,
                            LanguageType eNewLanguage);

public:
                        OfaAutocorrReplacePage( vcl::Window* pParent, const SfxItemSet& rSet );
                        virtual ~OfaAutocorrReplacePage() override;
    virtual void        dispose() override;
    OfaAutocorrReplacePage(TabPageParent pParent, const SfxItemSet& rSet);
    virtual ~OfaAutocorrReplacePage() override;
    virtual void dispose() override;

    static VclPtr<SfxTabPage>  Create( TabPageParent pParent, const SfxItemSet* rAttrSet);

diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
index c491d26..b143f27 100644
--- a/cui/source/tabpages/autocdlg.cxx
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -857,24 +857,25 @@ void    OfaACorrCheckListBox::KeyInput( const KeyEvent& rKEvt )
        SvSimpleTable::KeyInput(rKEvt);
}

OfaAutocorrReplacePage::OfaAutocorrReplacePage( vcl::Window* pParent,
                                                const SfxItemSet& rSet )
    : SfxTabPage(pParent, "AcorReplacePage", "cui/ui/acorreplacepage.ui", &rSet)
OfaAutocorrReplacePage::OfaAutocorrReplacePage(TabPageParent pParent,
                                               const SfxItemSet& rSet)
    : SfxTabPage(pParent, "cui/ui/acorreplacepage.ui", "AcorReplacePage", &rSet)
    , eLang(eLastDialogLanguage)
    , bHasSelectionText(false)
    , bFirstSelect(true)
    , bReplaceEditChanged(false)
    , bSWriter(true)
    , m_xTextOnlyCB(m_xBuilder->weld_check_button("textonly"))
    , m_xShortED(m_xBuilder->weld_entry("origtext"))
    , m_xReplaceED(m_xBuilder->weld_entry("newtext"))
    , m_xReplaceTLB(m_xBuilder->weld_tree_view("tabview"))
    , m_xNewReplacePB(m_xBuilder->weld_button("new"))
    , m_xReplacePB(m_xBuilder->weld_button("replace"))
    , m_xDeleteReplacePB(m_xBuilder->weld_button("delete"))
{
    get(m_pTextOnlyCB, "textonly");
    get(m_pDeleteReplacePB, "delete");
    get(m_pNewReplacePB, "new");
    sNew = m_pNewReplacePB->GetText();
    sModify = get<PushButton>("replace")->GetText();
    get(m_pShortED, "origtext");
    get(m_pReplaceED, "newtext");
    get(m_pReplaceTLB, "tabview");
    m_pReplaceTLB->set_height_request(16 * GetTextHeight());
    sNew = m_xNewReplacePB->get_label();
    sModify = m_xReplacePB->get_label();
    m_xReplaceTLB->set_size_request(-1, m_xReplaceTLB->get_height_rows(16));

    SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
    bSWriter = pMod == SfxModule::GetActiveModule();
@@ -884,23 +885,19 @@ OfaAutocorrReplacePage::OfaAutocorrReplacePage( vcl::Window* pParent,
    pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
    pCharClass.reset( new CharClass( aLanguageTag ) );

    static long const aTabs[] = { 1, 61 };
    m_pReplaceTLB->SetTabs( SAL_N_ELEMENTS(aTabs), aTabs );
    std::vector<int> aWidths;
    aWidths.push_back(m_xReplaceTLB->get_approximate_digit_width() * 32);
    m_xReplaceTLB->set_column_fixed_widths(aWidths);

    m_pReplaceTLB->SetStyle( m_pReplaceTLB->GetStyle()|WB_HSCROLL|WB_CLIPCHILDREN );
    m_pReplaceTLB->SetSelectHdl( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
    m_pNewReplacePB->SetClickHdl( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
    m_pDeleteReplacePB->SetClickHdl( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
    m_pShortED->SetModifyHdl( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
    m_pReplaceED->SetModifyHdl( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
    m_pShortED->SetActionHdl( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
    m_pReplaceED->SetActionHdl( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );

    m_pReplaceED->SetSpaces(true);
    m_pShortED->SetSpaces(true);

    m_pShortED->ConnectColumn(m_pReplaceTLB, 0);
    m_pReplaceED->ConnectColumn(m_pReplaceTLB, 1);
    m_xReplaceTLB->connect_changed( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
    m_xNewReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
    m_xDeleteReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
    m_xShortED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
    m_xReplaceED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
    m_xShortED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
    m_xReplaceED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
    m_xShortED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
    m_xReplaceED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
}

OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
@@ -916,18 +913,12 @@ void OfaAutocorrReplacePage::dispose()
    pCompareClass.reset();
    pCharClass.reset();

    m_pTextOnlyCB.clear();
    m_pShortED.clear();
    m_pReplaceED.clear();
    m_pReplaceTLB.clear();
    m_pNewReplacePB.clear();
    m_pDeleteReplacePB.clear();
    SfxTabPage::dispose();
}

VclPtr<SfxTabPage> OfaAutocorrReplacePage::Create( TabPageParent pParent, const SfxItemSet* rSet)
VclPtr<SfxTabPage> OfaAutocorrReplacePage::Create(TabPageParent pParent, const SfxItemSet* rSet)
{
    return VclPtr<OfaAutocorrReplacePage>::Create(pParent.pParent, *rSet);
    return VclPtr<OfaAutocorrReplacePage>::Create(pParent, *rSet);
}

void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
@@ -1003,23 +994,24 @@ void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
            pArray = &aDoubleStringTable[eOldLanguage]; // create new array
        }

        sal_uInt32 nListBoxCount = static_cast<sal_uInt32>(m_pReplaceTLB->GetEntryCount());
        sal_uInt32 nListBoxCount = m_xReplaceTLB->n_children();
        sal_uInt32 i;
        for(i = 0; i < nListBoxCount; i++)
        {
            pArray->push_back(DoubleString());
            DoubleString& rDouble = (*pArray)[pArray->size() - 1];
            SvTreeListEntry*  pEntry = m_pReplaceTLB->GetEntry( i );
            rDouble.sShort = SvTabListBox::GetEntryText(pEntry, 0);
            rDouble.sLong = SvTabListBox::GetEntryText(pEntry, 1);
            rDouble.pUserData = pEntry->GetUserData();
            rDouble.sShort = m_xReplaceTLB->get_text(i, 0);
            rDouble.sLong = m_xReplaceTLB->get_text(i, 1);
            rDouble.pUserData = reinterpret_cast<void*>(m_xReplaceTLB->get_id(i).toInt64());
        }
    }

    m_pReplaceTLB->Clear();
    m_xReplaceTLB->clear();
    if( !bSWriter )
        aFormatText.clear();

    m_xReplaceTLB->freeze();

    if( aDoubleStringTable.find(eLang) != aDoubleStringTable.end() )
    {
        DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
@@ -1027,13 +1019,17 @@ void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
        {
            bool bTextOnly = nullptr == rDouble.pUserData;
            // formatted text is only in Writer
            if(bSWriter || bTextOnly)
            if (bSWriter || bTextOnly)
            {
                OUString sEntry = rDouble.sShort + "\t" + rDouble.sLong;
                SvTreeListEntry* pEntry = m_pReplaceTLB->InsertEntry(sEntry);
                m_pTextOnlyCB->Check(bTextOnly);
                if(!bTextOnly)
                    pEntry->SetUserData(rDouble.pUserData); // that means: with format info or even with selection text
                m_xTextOnlyCB->set_active(bTextOnly);
                OUString sId;
                if (!bTextOnly)
                {
                    // that means: with format info or even with selection text
                    sId = OUString::number(reinterpret_cast<sal_Int64>(rDouble.pUserData));
                }
                m_xReplaceTLB->append(sId, rDouble.sShort);
                m_xReplaceTLB->set_text(m_xReplaceTLB->n_children() - 1, rDouble.sLong, 1);
            }
            else
            {
@@ -1045,49 +1041,53 @@ void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
    {
        SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
        SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
        m_pReplaceTLB->SetUpdateMode(false);
        SvxAutocorrWordList::Content aContent = pWordList->getSortedContent();
        for (auto const& elem : aContent)
        {
            bool bTextOnly = elem->IsTextOnly();
            // formatted text is only in Writer
            if(bSWriter || bTextOnly)
            if (bSWriter || bTextOnly)
            {
                OUString sEntry = elem->GetShort() + "\t" + elem->GetLong();
                SvTreeListEntry* pEntry = m_pReplaceTLB->InsertEntry(sEntry);
                m_pTextOnlyCB->Check(elem->IsTextOnly());
                if(!bTextOnly)
                    pEntry->SetUserData(m_pTextOnlyCB); // that means: with format info
                m_xTextOnlyCB->set_active(elem->IsTextOnly());
                OUString sId;
                if (!bTextOnly)
                {
                    // that means: with format info or even with selection text
                    sId = OUString::number(reinterpret_cast<sal_Int64>(m_xTextOnlyCB.get()));
                }
                m_xReplaceTLB->append(sId, elem->GetShort());
                m_xReplaceTLB->set_text(m_xReplaceTLB->n_children() - 1, elem->GetLong(), 1);
            }
            else
            {
                aFormatText.insert(elem->GetShort());
            }
        }
        m_pNewReplacePB->Enable(false);
        m_pDeleteReplacePB->Enable(false);
        m_pReplaceTLB->SetUpdateMode(true);
        m_xNewReplacePB->set_sensitive(false);
        m_xDeleteReplacePB->set_sensitive(false);
    }

    m_xReplaceTLB->thaw();

    SfxViewShell* pViewShell = SfxViewShell::Current();
    if( pViewShell && pViewShell->HasSelection() )
    if (pViewShell && pViewShell->HasSelection())
    {
        bHasSelectionText = true;
        const OUString sSelection( pViewShell->GetSelectionText() );
        m_pReplaceED->SetText( sSelection );
        m_pTextOnlyCB->Check( !bSWriter );
        m_pTextOnlyCB->Enable( bSWriter && !sSelection.isEmpty() );
        m_xReplaceED->set_text(sSelection);
        m_xTextOnlyCB->set_active(!bSWriter);
        m_xTextOnlyCB->set_sensitive(bSWriter && !sSelection.isEmpty());
    }
    else
    {
        m_pTextOnlyCB->Enable( false );
        m_xTextOnlyCB->set_sensitive(false);
    }
}

void OfaAutocorrReplacePage::Reset( const SfxItemSet* )
{
    RefillReplaceBox(true, eLang, eLang);
    m_pShortED->GrabFocus();
    m_xShortED->grab_focus();
}

void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
@@ -1102,40 +1102,41 @@ void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
        pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
        pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
        pCharClass.reset( new CharClass( aLanguageTag ) );
        ModifyHdl(*m_pShortED);
        ModifyHdl(*m_xShortED);
    }
}

IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, SvTreeListBox*, pBox, void)
IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
{
    if(!bFirstSelect || !bHasSelectionText)
    {
        SvTreeListEntry* pEntry = pBox->FirstSelected();
        OUString sTmpShort(SvTabListBox::GetEntryText(pEntry, 0));
        int nEntry = rBox.get_selected_index();
        OUString sTmpShort(rBox.get_text(nEntry, 0));
        // if the text is set via ModifyHdl, the cursor is always at the beginning
        // of a word, although you're editing here
        bool bSameContent = 0 == pCompareClass->compareString( sTmpShort, m_pShortED->GetText() );
        Selection aSel = m_pShortED->GetSelection();
        if(m_pShortED->GetText() != sTmpShort)
        bool bSameContent = 0 == pCompareClass->compareString(sTmpShort, m_xShortED->get_text());
        int nStartPos, nEndPos;
        m_xShortED->get_selection_bounds(nStartPos, nEndPos);
        if (m_xShortED->get_text() != sTmpShort)
        {
            m_pShortED->SetText(sTmpShort);
            m_xShortED->set_text(sTmpShort);
            // if it was only a different notation, the selection has to be set again
            if(bSameContent)
            if (bSameContent)
            {
                m_pShortED->SetSelection(aSel);
                m_xShortED->select_region(nStartPos, nEndPos);
            }
        }
        m_pReplaceED->SetText( SvTabListBox::GetEntryText(pEntry, 1) );
        m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
        // with UserData there is a Formatinfo
        m_pTextOnlyCB->Check( pEntry->GetUserData() == nullptr);
        m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
    }
    else
    {
        bFirstSelect = false;
    }

    m_pNewReplacePB->Enable(false);
    m_pDeleteReplacePB->Enable();
    m_xNewReplacePB->set_sensitive(false);
    m_xDeleteReplacePB->set_sensitive(true);
};

void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
@@ -1196,72 +1197,84 @@ void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString&
    rDeletedArray.push_back(aDeletedString);
}

IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, Button*, pBtn, void)
IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, weld::Button&, rBtn, void)
{
    NewDelHdl(pBtn);
    NewDelHdl(&rBtn);
}

IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, AutoCorrEdit&, rEdit, bool)
IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
{
    return NewDelHdl(&rEdit);
}
bool OfaAutocorrReplacePage::NewDelHdl(void const * pBtn)

IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
{
    SvTreeListEntry* pEntry = m_pReplaceTLB->FirstSelected();
    if( pBtn == m_pDeleteReplacePB )
    std::vector<int> aWidths;
    int x, y, width, height;
    if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
    {
        DBG_ASSERT( pEntry, "no entry selected" );
        if( pEntry )
        aWidths.push_back(x);
        m_xReplaceTLB->set_column_fixed_widths(aWidths);
    }
}

bool OfaAutocorrReplacePage::NewDelHdl(const weld::Widget* pBtn)
{
    int nEntry = m_xReplaceTLB->get_selected_index();
    if (pBtn == m_xDeleteReplacePB.get())
    {
        DBG_ASSERT( nEntry != -1, "no entry selected" );
        if (nEntry != -1)
        {
            DeleteEntry(SvTabListBox::GetEntryText(pEntry, 0), SvTabListBox::GetEntryText(pEntry, 1));
            m_pReplaceTLB->GetModel()->Remove(pEntry);
            ModifyHdl(*m_pShortED);
            DeleteEntry(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
            m_xReplaceTLB->remove(nEntry);
            ModifyHdl(*m_xShortED);
            return false;
        }
    }
    if(pBtn == m_pNewReplacePB || m_pNewReplacePB->IsEnabled())

    if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
    {
        SvTreeListEntry* _pNewEntry = m_pReplaceTLB->FirstSelected();
        OUString sEntry(m_pShortED->GetText());
        if(!sEntry.isEmpty() && ( !m_pReplaceED->GetText().isEmpty() ||
        OUString sEntry(m_xShortED->get_text());
        if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
                ( bHasSelectionText && bSWriter ) ))
        {
            bool bKeepSourceFormatting = !bReplaceEditChanged && !m_pTextOnlyCB->IsChecked();
            bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();

            NewEntry(m_pShortED->GetText(), m_pReplaceED->GetText(), bKeepSourceFormatting);
            m_pReplaceTLB->SetUpdateMode(false);
            sal_uLong nPos = TREELIST_ENTRY_NOTFOUND;
            sEntry += "\t" + m_pReplaceED->GetText();
            if(_pNewEntry)
            NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
            m_xReplaceTLB->freeze();
            int nPos = -1;
            if (nEntry != -1)
            {
                nPos = m_pReplaceTLB->GetModel()->GetAbsPos(_pNewEntry);
                m_pReplaceTLB->GetModel()->Remove(_pNewEntry);
                nPos = nEntry;
                m_xReplaceTLB->remove(nEntry);
            }
            else
            {
                sal_uLong j;
                for( j = 0; j < m_pReplaceTLB->GetEntryCount(); j++ )
                int j;
                int nCount = m_xReplaceTLB->n_children();
                for (j = 0; j < nCount; ++j)
                {
                    SvTreeListEntry* pReplaceEntry = m_pReplaceTLB->GetEntry(j);
                    if( 0 >=  pCompareClass->compareString(sEntry, SvTabListBox::GetEntryText(pReplaceEntry, 0) ) )
                    if (0 >= pCompareClass->compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
                        break;
                }
                nPos = j;
            }
            SvTreeListEntry* pInsEntry = m_pReplaceTLB->InsertEntry(
                                        sEntry, static_cast< SvTreeListEntry * >(nullptr), false,
                                        nPos == TREELIST_ENTRY_NOTFOUND ? TREELIST_APPEND : nPos);

            OUString sId;
            if (bKeepSourceFormatting)
            {
                pInsEntry->SetUserData(&bHasSelectionText); // new formatted text
                sId = OUString::number(reinterpret_cast<sal_Int64>(&bHasSelectionText)); // new formatted text
            }

            m_pReplaceTLB->MakeVisible( pInsEntry );
            m_pReplaceTLB->SetUpdateMode( true );
            m_xReplaceTLB->insert(nPos, sEntry, &sId, nullptr, nullptr);
            m_xReplaceTLB->set_text(nPos, m_xReplaceED->get_text(), 1);
            m_xReplaceTLB->thaw();
            m_xReplaceTLB->scroll_to_row(nPos);
            // if the request came from the ReplaceEdit, give focus to the ShortEdit
            if(m_pReplaceED->HasFocus())
            if (m_xReplaceED->has_focus())
            {
                m_pShortED->GrabFocus();
                m_xShortED->grab_focus();
            }
        }
    }
@@ -1271,17 +1284,17 @@ bool OfaAutocorrReplacePage::NewDelHdl(void const * pBtn)
        // which means EndDialog() - has to be evaluated in KeyInput
        return false;
    }
    ModifyHdl(*m_pShortED);
    ModifyHdl(*m_xShortED);
    return true;
}

IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, Edit&, rEdt, void)
IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
{
    SvTreeListEntry* pFirstSel = m_pReplaceTLB->FirstSelected();
    bool bShort = &rEdt == m_pShortED;
    const OUString rEntry = rEdt.GetText();
    const OUString rRepString = m_pReplaceED->GetText();
    OUString aWordStr( pCharClass->lowercase( rEntry ));
    int nFirstSel = m_xReplaceTLB->get_selected_index();
    bool bShort = &rEdt == m_xShortED.get();
    const OUString rEntry = rEdt.get_text();
    const OUString rRepString = m_xReplaceED->get_text();
    OUString aWordStr(pCharClass->lowercase(rEntry));

    if(bShort)
    {
@@ -1290,19 +1303,20 @@ IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, Edit&, rEdt, void)
            bool bFound = false;
            bool bTmpSelEntry=false;

            for(sal_uLong i = 0; i < m_pReplaceTLB->GetEntryCount(); i++)
            int nCount = m_xReplaceTLB->n_children();
            for (int i = 0; i < nCount; ++i)
            {
                SvTreeListEntry*  pEntry = m_pReplaceTLB->GetEntry( i );
                OUString aTestStr = SvTabListBox::GetEntryText(pEntry, 0);
                int nEntry = i;
                OUString aTestStr = m_xReplaceTLB->get_text(i, 0);
                if( pCompareClass->compareString(rEntry, aTestStr ) == 0 )
                {
                    if( !rRepString.isEmpty() )
                    {
                        bFirstSelect = true;
                    }
                    m_pReplaceTLB->SetCurEntry(pEntry);
                    pFirstSel = pEntry;
                    m_pNewReplacePB->SetText(sModify);
                    m_xReplaceTLB->set_cursor(nEntry);
                    nFirstSel = i;
                    m_xNewReplacePB->set_label(sModify);
                    bFound = true;
                    break;
                }
@@ -1311,43 +1325,42 @@ IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, Edit&, rEdt, void)
                    aTestStr = pCharClass->lowercase( aTestStr );
                    if( aTestStr.startsWith(aWordStr) && !bTmpSelEntry )
                    {
                        m_pReplaceTLB->MakeVisible( pEntry );
                        m_xReplaceTLB->scroll_to_row(nEntry);
                        bTmpSelEntry = true;
                    }
                }
            }
            if( !bFound )
            {
                m_pReplaceTLB->SelectAll( false );
                pFirstSel = nullptr;
                m_pNewReplacePB->SetText( sNew );
                m_xReplaceTLB->select(-1);
                nFirstSel = -1;
                m_xNewReplacePB->set_label(sNew);
                if( bReplaceEditChanged )
                    m_pTextOnlyCB->Enable(false);
                    m_xTextOnlyCB->set_sensitive(false);
            }
            m_pDeleteReplacePB->Enable( bFound );
            m_xDeleteReplacePB->set_sensitive(bFound);
        }
        else if( m_pReplaceTLB->GetEntryCount() > 0 )
        else if (m_xReplaceTLB->n_children() > 0)
        {
            SvTreeListEntry*  pEntry = m_pReplaceTLB->GetEntry( 0 );
            m_pReplaceTLB->MakeVisible( pEntry );
            m_xReplaceTLB->scroll_to_row(0);
        }

    }
    else if( !bShort )
    {
        bReplaceEditChanged = true;
        if( pFirstSel )
        if (nFirstSel != -1)
        {
            m_pNewReplacePB->SetText( sModify );
            m_xNewReplacePB->set_label(sModify);
        }
    }

    const OUString& rShortTxt = m_pShortED->GetText();
    const OUString& rShortTxt = m_xShortED->get_text();
    bool bEnableNew = !rShortTxt.isEmpty() &&
                        ( !rRepString.isEmpty() ||
                                ( bHasSelectionText && bSWriter )) &&
                        ( !pFirstSel || rRepString !=
                                SvTabListBox::GetEntryText( pFirstSel, 1 ) );
                        ( nFirstSel == -1 || rRepString !=
                                m_xReplaceTLB->get_text(nFirstSel, 1) );
    if( bEnableNew )
    {
        for (auto const& elem : aFormatText)
@@ -1359,7 +1372,7 @@ IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, Edit&, rEdt, void)
            }
        }
    }
    m_pNewReplacePB->Enable( bEnableNew );
    m_xNewReplacePB->set_sensitive(bEnableNew);
}

static bool lcl_FindInArray(std::vector<OUString>& rStrings, const OUString& rString)
diff --git a/cui/uiconfig/ui/acorreplacepage.ui b/cui/uiconfig/ui/acorreplacepage.ui
index 6ab79ee..3d293cc 100644
--- a/cui/uiconfig/ui/acorreplacepage.ui
+++ b/cui/uiconfig/ui/acorreplacepage.ui
@@ -2,7 +2,16 @@
<!-- Generated with glade 3.16.0 on Wed Jan 29 10:50:29 2014 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name text2 -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkGrid" id="AcorReplacePage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -71,12 +80,52 @@
      </packing>
    </child>
    <child>
      <object class="vcllo-SvTabListBox" id="tabview:border">
        <property name="width_request">1</property>
      <object class="GtkScrolledWindow">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
        <property name="vexpand">True</property>
        <property name="shadow_type">in</property>
        <child>
          <object class="GtkTreeView" id="tabview">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="headers_visible">False</property>
            <property name="model">liststore1</property>
            <property name="search_column">0</property>
            <property name="show_expanders">False</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                <property name="resizable">True</property>
                <property name="spacing">6</property>
                <child>
                  <object class="GtkCellRendererText" id="cellrenderer1"/>
                  <attributes>
                    <attribute name="text">0</attribute>
                  </attributes>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="treeviewcolumn2">
                <property name="resizable">True</property>
                <property name="spacing">6</property>
                <child>
                  <object class="GtkCellRendererText" id="cellrenderer2"/>
                  <attributes>
                    <attribute name="text">1</attribute>
                  </attributes>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="left_attach">0</property>
@@ -86,7 +135,7 @@
      </packing>
    </child>
    <child>
      <object class="cuilo-AutoCorrEdit" id="newtext">
      <object class="GtkEntry" id="newtext">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
@@ -100,7 +149,7 @@
      </packing>
    </child>
    <child>
      <object class="cuilo-AutoCorrEdit" id="origtext">
      <object class="GtkEntry" id="origtext">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
diff --git a/include/svtools/inettbc.hxx b/include/svtools/inettbc.hxx
index 96415f3..c62754c 100644
--- a/include/svtools/inettbc.hxx
+++ b/include/svtools/inettbc.hxx
@@ -117,7 +117,7 @@ public:

    void                            SetText(const OUString& rStr) { m_xWidget->set_entry_text(rStr); }
    void                            Clear() { m_xWidget->clear(); }
    void connect_entry_activate(const Link<weld::ComboBox&, void>& rLink) { m_xWidget->connect_entry_activate(rLink); }
    void connect_entry_activate(const Link<weld::ComboBox&, bool>& rLink) { m_xWidget->connect_entry_activate(rLink); }
    void connect_changed(const Link<weld::ComboBox&, void>& rLink) { m_xWidget->connect_changed(rLink); }
    void                            append_text(const OUString& rStr) { m_xWidget->append_text(rStr); }
    OUString                        get_active_text() const { return m_xWidget->get_active_text(); }
diff --git a/include/vcl/combobox.hxx b/include/vcl/combobox.hxx
index 9714acec..9dc1473 100644
--- a/include/vcl/combobox.hxx
+++ b/include/vcl/combobox.hxx
@@ -126,7 +126,7 @@ public:
    const Link<ComboBox&,void>&   GetSelectHdl() const;
    void            SetDoubleClickHdl(const Link<ComboBox&,void>& rLink);
    const Link<ComboBox&,void>&   GetDoubleClickHdl() const;
    void            SetEntryActivateHdl(const Link<Edit&,void>& rLink);
    void            SetEntryActivateHdl(const Link<Edit&,bool>& rLink);

    Size            CalcMinimumSize() const override;
    virtual Size    GetOptimalSize() const override;
diff --git a/include/vcl/edit.hxx b/include/vcl/edit.hxx
index 40d2f44..a44a430 100644
--- a/include/vcl/edit.hxx
+++ b/include/vcl/edit.hxx
@@ -99,7 +99,7 @@ private:
    Link<Edit&,void>    maModifyHdl;
    Link<Edit&,void>    maUpdateDataHdl;
    Link<Edit&,void>    maAutocompleteHdl;
    Link<Edit&,void>    maActivateHdl;
    Link<Edit&,bool>    maActivateHdl;
    std::unique_ptr<VclBuilder> mpUIBuilder;

    css::uno::Reference<css::i18n::XExtendedInputSequenceChecker> mxISC;
@@ -244,7 +244,7 @@ public:
    virtual const Link<Edit&,void>& GetModifyHdl() const { return maModifyHdl; }
    virtual void        SetUpdateDataHdl( const Link<Edit&,void>& rLink ) { maUpdateDataHdl = rLink; }

    void                SetActivateHdl(const Link<Edit&,void>& rLink) { maActivateHdl = rLink; }
    void                SetActivateHdl(const Link<Edit&,bool>& rLink) { maActivateHdl = rLink; }

    void                SetSubEdit( Edit* pEdit );
    Edit*               GetSubEdit() const { return mpSubEdit; }
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index da56503..b682acd 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -41,6 +41,7 @@ class VCL_DLLPUBLIC Widget
protected:
    Link<Widget&, void> m_aFocusInHdl;
    Link<Widget&, void> m_aFocusOutHdl;
    Link<const Size&, void> m_aSizeAllocateHdl;

    void signal_focus_in() { m_aFocusInHdl.Call(*this); }
    void signal_focus_out() { m_aFocusOutHdl.Call(*this); }
@@ -89,6 +90,9 @@ public:
    virtual void set_margin_top(int nMargin) = 0;
    virtual void set_margin_bottom(int nMargin) = 0;

    virtual bool get_extents_relative_to(Widget& rRelative, int& x, int& y, int& width, int& height)
        = 0;

    virtual void set_accessible_name(const OUString& rName) = 0;
    virtual OUString get_accessible_name() const = 0;

@@ -108,6 +112,12 @@ public:
        m_aFocusOutHdl = rLink;
    }

    virtual void connect_size_allocate(const Link<const Size&, void>& rLink)
    {
        assert(!m_aSizeAllocateHdl.IsSet() || !rLink.IsSet());
        m_aSizeAllocateHdl = rLink;
    }

    virtual void grab_add() = 0;
    virtual bool has_grab() const = 0;
    virtual void grab_remove() = 0;
@@ -199,8 +209,6 @@ public:
    virtual void window_move(int x, int y) = 0;
    virtual void set_modal(bool bModal) = 0;
    virtual bool get_modal() const = 0;
    virtual bool get_extents_relative_to(Window& rRelative, int& x, int& y, int& width, int& height)
        = 0;
    virtual bool get_resizable() const = 0;
    virtual Size get_size() const = 0;
    virtual Point get_position() const = 0;
@@ -293,7 +301,7 @@ private:

protected:
    Link<ComboBox&, void> m_aChangeHdl;
    Link<ComboBox&, void> m_aEntryActivateHdl;
    Link<ComboBox&, bool> m_aEntryActivateHdl;

    void signal_changed() { m_aChangeHdl.Call(*this); }

@@ -359,7 +367,8 @@ public:

    virtual bool get_popup_shown() const = 0;

    void connect_entry_activate(const Link<ComboBox&, void>& rLink) { m_aEntryActivateHdl = rLink; }
    // callback returns true to indicated no further processing of activate wanted
    void connect_entry_activate(const Link<ComboBox&, bool>& rLink) { m_aEntryActivateHdl = rLink; }

    void save_value() { m_sSavedValue = get_active_text(); }
    OUString const& get_saved_value() const { return m_sSavedValue; }
@@ -440,6 +449,7 @@ public:
    virtual std::vector<int> get_selected_rows() const = 0;
    virtual void set_font_color(int pos, const Color& rColor) const = 0;
    virtual void scroll_to_row(int pos) = 0;
    virtual void set_cursor(int pos) = 0;

    //by text
    virtual OUString get_text(int row, int col = -1) const = 0;
@@ -653,6 +663,7 @@ protected:
    Link<Entry&, void> m_aChangeHdl;
    Link<OUString&, bool> m_aInsertTextHdl;
    Link<Entry&, void> m_aCursorPositionHdl;
    Link<Entry&, bool> m_aActivateHdl;

    void signal_changed() { m_aChangeHdl.Call(*this); }
    void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); }
@@ -678,6 +689,8 @@ public:

    void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; }
    void connect_insert_text(const Link<OUString&, bool>& rLink) { m_aInsertTextHdl = rLink; }
    // callback returns true to indicated no further processing of activate wanted
    void connect_activate(const Link<Entry&, bool>& rLink) { m_aActivateHdl = rLink; }
    virtual void connect_cursor_position(const Link<Entry&, void>& rLink)
    {
        m_aCursorPositionHdl = rLink;
@@ -1155,7 +1168,6 @@ public:

protected:
    Link<draw_args, void> m_aDrawHdl;
    Link<const Size&, void> m_aSizeAllocateHdl;
    Link<const MouseEvent&, void> m_aMousePressHdl;
    Link<const MouseEvent&, void> m_aMouseMotionHdl;
    Link<const MouseEvent&, void> m_aMouseReleaseHdl;
@@ -1173,7 +1185,6 @@ protected:

public:
    void connect_draw(const Link<draw_args, void>& rLink) { m_aDrawHdl = rLink; }
    void connect_size_allocate(const Link<const Size&, void>& rLink) { m_aSizeAllocateHdl = rLink; }
    void connect_mouse_press(const Link<const MouseEvent&, void>& rLink)
    {
        m_aMousePressHdl = rLink;
diff --git a/sc/source/ui/inc/linkarea.hxx b/sc/source/ui/inc/linkarea.hxx
index 8b2151d..c3ce695 100644
--- a/sc/source/ui/inc/linkarea.hxx
+++ b/sc/source/ui/inc/linkarea.hxx
@@ -44,7 +44,7 @@ private:
    std::unique_ptr<weld::Label> m_xFtSeconds;
    std::unique_ptr<weld::Button> m_xBtnOk;

    DECL_LINK(FileHdl, weld::ComboBox&, void);
    DECL_LINK(FileHdl, weld::ComboBox&, bool);
    DECL_LINK(BrowseHdl, weld::Button&, void);
    DECL_LINK(RangeHdl, weld::TreeView&, void);
    DECL_LINK(ReloadHdl, weld::Button&, void);
diff --git a/sc/source/ui/miscdlgs/linkarea.cxx b/sc/source/ui/miscdlgs/linkarea.cxx
index a55c27f..e5d0fdc 100644
--- a/sc/source/ui/miscdlgs/linkarea.cxx
+++ b/sc/source/ui/miscdlgs/linkarea.cxx
@@ -49,7 +49,7 @@ ScLinkedAreaDlg::ScLinkedAreaDlg(weld::Window* pParent)
{
    m_xLbRanges->set_selection_mode(true);

    m_xCbUrl->connect_entry_activate(LINK( this, ScLinkedAreaDlg, FileHdl));
    m_xCbUrl->connect_entry_activate(LINK(this, ScLinkedAreaDlg, FileHdl));
    m_xBtnBrowse->connect_clicked(LINK( this, ScLinkedAreaDlg, BrowseHdl));
    m_xLbRanges->connect_changed(LINK( this, ScLinkedAreaDlg, RangeHdl));
    m_xLbRanges->set_size_request(m_xLbRanges->get_approximate_digit_width() * 54,
@@ -71,7 +71,7 @@ IMPL_LINK_NOARG(ScLinkedAreaDlg, BrowseHdl, weld::Button&, void)
    m_xDocInserter->StartExecuteModal( LINK( this, ScLinkedAreaDlg, DialogClosedHdl ) );
}

IMPL_LINK_NOARG(ScLinkedAreaDlg, FileHdl, weld::ComboBox&, void)
IMPL_LINK_NOARG(ScLinkedAreaDlg, FileHdl, weld::ComboBox&, bool)
{
    OUString aEntered = m_xCbUrl->GetURL();
    if (m_pSourceShell)
@@ -80,7 +80,7 @@ IMPL_LINK_NOARG(ScLinkedAreaDlg, FileHdl, weld::ComboBox&, void)
        if ( aEntered == pMed->GetName() )
        {
            //  already loaded - nothing to do
            return;
            return true;
        }
    }

@@ -89,7 +89,7 @@ IMPL_LINK_NOARG(ScLinkedAreaDlg, FileHdl, weld::ComboBox&, void)
    //  get filter name by looking at the file content (bWithContent = true)
    // Break operation if any error occurred inside.
    if (!ScDocumentLoader::GetFilterName( aEntered, aFilter, aOptions, true, false ))
        return;
        return true;

    // #i53241# replace HTML filter with DataQuery filter
    if (aFilter == FILTERNAME_HTML)
@@ -99,6 +99,8 @@ IMPL_LINK_NOARG(ScLinkedAreaDlg, FileHdl, weld::ComboBox&, void)

    UpdateSourceRanges();
    UpdateEnable();

    return true;
}

void ScLinkedAreaDlg::LoadDocument( const OUString& rFile, const OUString& rFilter, const OUString& rOptions )
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d95d3de..b740bad 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -212,6 +212,7 @@ private:

    DECL_LINK(FocusInListener, VclWindowEvent&, void);
    DECL_LINK(FocusOutListener, VclWindowEvent&, void);
    DECL_LINK(ResizeListener, VclWindowEvent&, void);

    const bool m_bTakeOwnership;
    int m_nBlockNotify;
@@ -424,6 +425,22 @@ public:
        weld::Widget::connect_focus_out(rLink);
    }

    virtual void connect_size_allocate(const Link<const Size&, void>& rLink) override
    {
        m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, ResizeListener));
        weld::Widget::connect_size_allocate(rLink);
    }

    virtual bool get_extents_relative_to(Widget& rRelative, int& x, int &y, int& width, int &height) override
    {
        tools::Rectangle aRect(m_xWidget->GetWindowExtentsRelative(dynamic_cast<SalInstanceWidget&>(rRelative).getWidget()));
        x = aRect.Left();
        y = aRect.Top();
        width = aRect.GetWidth();
        height = aRect.GetHeight();
        return true;
    }

    virtual void grab_add() override
    {
        m_xWidget->CaptureMouse();
@@ -463,6 +480,8 @@ public:

    virtual ~SalInstanceWidget() override
    {
        if (m_aSizeAllocateHdl.IsSet())
            m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, ResizeListener));
        if (m_aFocusInHdl.IsSet())
            m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, FocusInListener));
        if (m_aFocusOutHdl.IsSet())
@@ -509,6 +528,14 @@ IMPL_LINK(SalInstanceWidget, FocusOutListener, VclWindowEvent&, rEvent, void)
        signal_focus_out();
}

IMPL_LINK(SalInstanceWidget, ResizeListener, VclWindowEvent&, rEvent, void)
{
    if (rEvent.GetId() == VclEventId::WindowResize)
    {
        m_aSizeAllocateHdl.Call(m_xWidget->GetSizePixel());
    }
}

namespace
{
    Image createImage(const OUString& rImage)
@@ -752,21 +779,6 @@ public:
        m_xWindow->SetPosPixel(Point(x, y));
    }

    vcl::Window* getWindow()
    {
        return m_xWindow.get();
    }

    virtual bool get_extents_relative_to(Window& rRelative, int& x, int &y, int& width, int &height) override
    {
        tools::Rectangle aRect(m_xWindow->GetWindowExtentsRelative(dynamic_cast<SalInstanceWindow&>(rRelative).getWindow()));
        x = aRect.Left();
        y = aRect.Top();
        width = aRect.GetWidth();
        height = aRect.GetHeight();
        return true;
    }

    virtual Size get_size() const override
    {
        return m_xWindow->GetSizePixel();
@@ -1592,6 +1604,7 @@ private:

    DECL_LINK(ChangeHdl, Edit&, void);
    DECL_LINK(CursorListener, VclWindowEvent&, void);
    DECL_LINK(ActivateHdl, Edit&, bool);

    class WeldTextFilter : public TextFilter
    {
@@ -1624,6 +1637,7 @@ public:
        , m_aTextFilter(m_aInsertTextHdl)
    {
        m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
        m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
        m_xEntry->SetTextFilter(&m_aTextFilter);
    }

@@ -1744,6 +1758,7 @@ public:
        if (m_aCursorPositionHdl.IsSet())
            m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
        m_xEntry->SetTextFilter(nullptr);
        m_xEntry->SetActivateHdl(Link<Edit&, bool>());
        m_xEntry->SetModifyHdl(Link<Edit&, void>());
    }
};
@@ -1761,6 +1776,11 @@ IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
        signal_cursor_position();
}

IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool)
{
    return m_aActivateHdl.Call(*this);
}

struct SalInstanceTreeIter : public weld::TreeIter
{
    SalInstanceTreeIter(const SalInstanceTreeIter* pOrig)
@@ -1937,6 +1957,17 @@ public:
        enable_notify_events();
    }

    virtual void set_cursor(int pos) override
    {
        if (pos == -1)
            m_xTreeView->SetCurEntry(nullptr);
        else
        {
            SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
            m_xTreeView->SetCurEntry(pEntry);
        }
    }

    virtual void scroll_to_row(int pos) override
    {
        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
@@ -2646,6 +2677,11 @@ public:
        m_xDrawingArea->queue_resize();
    }

    virtual void connect_size_allocate(const Link<const Size&, void>& rLink) override
    {
        weld::Widget::connect_size_allocate(rLink);
    }

    virtual a11yref get_accessible_parent() override
    {
        vcl::Window* pParent = m_xDrawingArea->GetParent();
@@ -2980,7 +3016,7 @@ class SalInstanceComboBoxWithEdit : public SalInstanceComboBox<ComboBox>
{
private:
    DECL_LINK(ChangeHdl, Edit&, void);
    DECL_LINK(EntryActivateHdl, Edit&, void);
    DECL_LINK(EntryActivateHdl, Edit&, bool);
public:
    SalInstanceComboBoxWithEdit(::ComboBox* pComboBox, bool bTakeOwnership)
        : SalInstanceComboBox<::ComboBox>(pComboBox, bTakeOwnership)
@@ -3065,7 +3101,7 @@ public:

    virtual ~SalInstanceComboBoxWithEdit() override
    {
        m_xComboBox->SetEntryActivateHdl(Link<Edit&, void>());
        m_xComboBox->SetEntryActivateHdl(Link<Edit&, bool>());
        m_xComboBox->SetModifyHdl(Link<Edit&, void>());
    }
};
@@ -3075,9 +3111,9 @@ IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, ChangeHdl, Edit&, void)
    signal_changed();
}

IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, EntryActivateHdl, Edit&, void)
IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, EntryActivateHdl, Edit&, bool)
{
    m_aEntryActivateHdl.Call(*this);
    return m_aEntryActivateHdl.Call(*this);
}

class SalInstanceEntryTreeView : public SalInstanceContainer, public virtual weld::EntryTreeView
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index 8dee632..9d34f90 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -999,7 +999,7 @@ void ComboBox::SetDoubleClickHdl(const Link<ComboBox&,void>& rLink) { m_pImpl->m

const Link<ComboBox&,void>& ComboBox::GetDoubleClickHdl() const { return m_pImpl->m_DoubleClickHdl; }

void ComboBox::SetEntryActivateHdl(const Link<Edit&,void>& rLink)
void ComboBox::SetEntryActivateHdl(const Link<Edit&,bool>& rLink)
{
    if (!m_pImpl->m_pSubEdit)
        return;
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index c1337c5..6e26672 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -1672,8 +1672,7 @@ bool Edit::ImplHandleKeyEvent( const KeyEvent& rKEvt )
            case KEY_RETURN:
                if (maActivateHdl.IsSet())
                {
                    maActivateHdl.Call(*this);
                    bDone = true;
                    bDone = maActivateHdl.Call(*this);
                }
            break;

diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index e04c6e6..4af889d 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1190,6 +1190,7 @@ private:
    gulong m_nFocusInSignalId;
    gulong m_nFocusOutSignalId;
    gulong m_nKeyPressSignalId;
    gulong m_nSizeAllocateSignalId;

    static void signalFocusIn(GtkWidget*, GdkEvent*, gpointer widget)
    {
@@ -1205,6 +1206,13 @@ private:
        pThis->signal_focus_out();
    }

    static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget)
    {
        GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
        SolarMutexGuard aGuard;
        pThis->signal_size_allocate(allocation->width, allocation->height);
    }

    static gboolean signalKeyPress(GtkWidget*, GdkEventKey* pEvent, gpointer)
    {
        // #i1820# use locale specific decimal separator
@@ -1223,6 +1231,7 @@ public:
        , m_bFrozen(false)
        , m_nFocusInSignalId(0)
        , m_nFocusOutSignalId(0)
        , m_nSizeAllocateSignalId(0)
    {
        GdkEventMask eEventMask(static_cast<GdkEventMask>(gtk_widget_get_events(pWidget)));
        if (eEventMask & GDK_BUTTON_PRESS_MASK)
@@ -1439,6 +1448,17 @@ public:
        return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
    }

    virtual bool get_extents_relative_to(weld::Widget& rRelative, int& x, int &y, int& width, int &height) override
    {
        //for toplevel windows this is sadly futile under wayland, so we can't tell where a dialog is in order to allow
        //the document underneath to auto-scroll to place content in a visible location
        gboolean ret = gtk_widget_translate_coordinates(dynamic_cast<GtkInstanceWidget&>(rRelative).getWidget(),
                                                        m_pWidget, 0, 0, &x, &y);
        width = gtk_widget_get_allocated_width(m_pWidget);
        height = gtk_widget_get_allocated_height(m_pWidget);
        return ret;
    }

    virtual void set_tooltip_text(const OUString& rTip) override
    {
        gtk_widget_set_tooltip_text(m_pWidget, OUStringToOString(rTip, RTL_TEXTENCODING_UTF8).getStr());
@@ -1487,6 +1507,17 @@ public:
        weld::Widget::connect_focus_out(rLink);
    }

    virtual void connect_size_allocate(const Link<const Size&, void>& rLink) override
    {
        m_nSizeAllocateSignalId = g_signal_connect(m_pWidget, "size_allocate", G_CALLBACK(signalSizeAllocate), this);
        weld::Widget::connect_size_allocate(rLink);
    }

    virtual void signal_size_allocate(guint nWidth, guint nHeight)
    {
        m_aSizeAllocateHdl.Call(Size(nWidth, nHeight));
    }

    virtual void grab_add() override
    {
        gtk_grab_add(m_pWidget);
@@ -1534,6 +1565,8 @@ public:
            g_signal_handler_disconnect(m_pWidget, m_nFocusInSignalId);
        if (m_nFocusOutSignalId)
            g_signal_handler_disconnect(m_pWidget, m_nFocusOutSignalId);
        if (m_nSizeAllocateSignalId)
            g_signal_handler_disconnect(m_pWidget, m_nSizeAllocateSignalId);
        if (m_bTakeOwnership)
            gtk_widget_destroy(m_pWidget);
    }
@@ -1544,10 +1577,14 @@ public:
            g_signal_handler_block(m_pWidget, m_nFocusInSignalId);
        if (m_nFocusOutSignalId)
            g_signal_handler_block(m_pWidget, m_nFocusOutSignalId);
        if (m_nSizeAllocateSignalId)
            g_signal_handler_block(m_pWidget, m_nSizeAllocateSignalId);
    }

    virtual void enable_notify_events()
    {
        if (m_nSizeAllocateSignalId)
            g_signal_handler_unblock(m_pWidget, m_nSizeAllocateSignalId);
        if (m_nFocusOutSignalId)
            g_signal_handler_unblock(m_pWidget, m_nFocusOutSignalId);
        if (m_nFocusInSignalId)
@@ -2095,16 +2132,6 @@ public:
        gtk_window_move(m_pWindow, x, y);
    }

    virtual bool get_extents_relative_to(Window& rRelative, int& x, int &y, int& width, int &height) override
    {
        //this is sadly futile under wayland, so we can't tell where a dialog is in order to allow
        //the document underneath to auto-scroll to place content in a visible location
        gboolean ret = gtk_widget_translate_coordinates(dynamic_cast<GtkInstanceWindow&>(rRelative).getWidget(), m_pWidget, 0, 0, &x, &y);
        width = gtk_widget_get_allocated_width(m_pWidget);
        height = gtk_widget_get_allocated_height(m_pWidget);
        return ret;
    }

    virtual SystemEnvData get_system_data() const override
    {
        assert(false && "nothing should call this impl, yet anyway, if ever");
@@ -3113,7 +3140,7 @@ private:
    // if > 6, but only if the notebook would auto-scroll, then flip tabs
    // to left which allows themes like Ambience under Ubuntu 16.04 to keep
    // tabs on top when they would fit
    void signal_size_allocate()
    void signal_notebook_size_allocate()
    {
        gint nPages = gtk_notebook_get_n_pages(m_pNotebook);
        if (nPages > 6 && gtk_notebook_get_tab_pos(m_pNotebook) == GTK_POS_TOP)
@@ -3133,7 +3160,7 @@ private:
    static void signalSizeAllocate(GtkWidget*, GdkRectangle*, gpointer widget)
    {
        GtkInstanceNotebook* pThis = static_cast<GtkInstanceNotebook*>(widget);
        pThis->signal_size_allocate();
        pThis->signal_notebook_size_allocate();
    }

public:
@@ -4571,6 +4598,13 @@ public:
        enable_notify_events();
    }

    virtual void set_cursor(int pos) override
    {
        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
        gtk_tree_view_set_cursor(m_pTreeView, path, nullptr, false);
        gtk_tree_path_free(path);
    }

    virtual void scroll_to_row(int pos) override
    {
        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when frozen");
@@ -5473,7 +5507,6 @@ private:
    cairo_surface_t* m_pSurface;
    sal_uInt16 m_nLastMouseButton;
    gulong m_nDrawSignalId;
    gulong m_nSizeAllocateSignalId;
    gulong m_nButtonPressSignalId;
    gulong m_nMotionSignalId;
    gulong m_nButtonReleaseSignalId;
@@ -5510,17 +5543,11 @@ private:
                             aFocusRect.Left(), aFocusRect.Top(), aFocusRect.GetWidth(), aFocusRect.GetHeight());
        }
    }
    static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget)
    {
        GtkInstanceDrawingArea* pThis = static_cast<GtkInstanceDrawingArea*>(widget);
        SolarMutexGuard aGuard;
        pThis->signal_size_allocate(allocation->width, allocation->height);
    }
    void signal_size_allocate(guint nWidth, guint nHeight)
    virtual void signal_size_allocate(guint nWidth, guint nHeight) override
    {
        m_xDevice->SetOutputSizePixel(Size(nWidth, nHeight));
        m_pSurface = get_underlying_cairo_surface(*m_xDevice);
        m_aSizeAllocateHdl.Call(Size(nWidth, nHeight));
        GtkInstanceWidget::signal_size_allocate(nWidth, nHeight);
    }
    static void signalStyleUpdated(GtkWidget*, gpointer widget)
    {
@@ -5690,7 +5717,6 @@ public:
        , m_pSurface(nullptr)
        , m_nLastMouseButton(0)
        , m_nDrawSignalId(g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(signalDraw), this))
        , m_nSizeAllocateSignalId(g_signal_connect(m_pDrawingArea, "size_allocate", G_CALLBACK(signalSizeAllocate), this))
        , m_nButtonPressSignalId(g_signal_connect(m_pDrawingArea, "button-press-event", G_CALLBACK(signalButton), this))
        , m_nMotionSignalId(g_signal_connect(m_pDrawingArea, "motion-notify-event", G_CALLBACK(signalMotion), this))
        , m_nButtonReleaseSignalId(g_signal_connect(m_pDrawingArea, "button-release-event", G_CALLBACK(signalButton), this))
@@ -5795,7 +5821,6 @@ public:
        g_signal_handler_disconnect(m_pDrawingArea, m_nButtonPressSignalId);
        g_signal_handler_disconnect(m_pDrawingArea, m_nMotionSignalId);
        g_signal_handler_disconnect(m_pDrawingArea, m_nButtonReleaseSignalId);
        g_signal_handler_disconnect(m_pDrawingArea, m_nSizeAllocateSignalId);
        g_signal_handler_disconnect(m_pDrawingArea, m_nDrawSignalId);
    }

@@ -5858,8 +5883,8 @@ private:
        if (m_aEntryActivateHdl.IsSet())
        {
            SolarMutexGuard aGuard;
            m_aEntryActivateHdl.Call(*this);
            g_signal_stop_emission_by_name(get_entry(), "activate");
            if (m_aEntryActivateHdl.Call(*this))
                g_signal_stop_emission_by_name(get_entry(), "activate");
        }
    }