weld SvxThesaurusDialog

Change-Id: I09a7b4dcd43af061d0e4be42a7b6a2ebf2331d0d
Reviewed-on: https://gerrit.libreoffice.org/73323
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc
index 6627ad9..70aa638 100644
--- a/cui/inc/strings.hrc
+++ b/cui/inc/strings.hrc
@@ -86,7 +86,6 @@
#define RID_SVXSTR_HYPERDLG_FROM_TEXT               NC_("RID_SVXSTR_HYPERDLG_FROM_TEXT", "Text")
#define RID_SVXSTR_HYPERDLG_QUERYOVERWRITE          NC_("RID_SVXSTR_HYPERDLG_QUERYOVERWRITE", "The file already exists. Overwrite?")

#define RID_SVXSTR_ERR_TEXTNOTFOUND                 NC_("RID_SVXSTR_ERR_TEXTNOTFOUND", "No alternatives found.")
#define RID_SVXSTR_SELECT_FILE_IFRAME               NC_("RID_SVXSTR_SELECT_FILE_IFRAME", "Select File for Floating Frame")
#define RID_SVXSTR_ALLFUNCTIONS                     NC_("RID_SVXSTR_ALLFUNCTIONS", "All commands")
#define RID_SVXSTR_MACROS                           NC_("RID_SVXSTR_MACROS", "Macros")
diff --git a/cui/source/dialogs/thesdlg.cxx b/cui/source/dialogs/thesdlg.cxx
index dd8d638..7d1cd22 100644
--- a/cui/source/dialogs/thesdlg.cxx
+++ b/cui/source/dialogs/thesdlg.cxx
@@ -18,7 +18,6 @@
 */

#include <thesdlg.hxx>
#include "thesdlg_impl.hxx"
#include <strings.hrc>
#include <dialmgr.hxx>

@@ -52,222 +51,28 @@

using namespace ::com::sun::star;

// class LookUpComboBox --------------------------------------------------

LookUpComboBox::LookUpComboBox(vcl::Window *pParent)
    : ComboBox(pParent, WB_LEFT|WB_DROPDOWN|WB_VCENTER|WB_3DLOOK|WB_TABSTOP)
    , m_aModifyIdle("cui LookUpComboBox Modify")
    , m_pDialog(nullptr)
IMPL_LINK_NOARG( SvxThesaurusDialog, ModifyTimer_Hdl, Timer *, void )
{
    EnableAutoSize(true);

    m_aModifyIdle.SetInvokeHandler( LINK( this, LookUpComboBox, ModifyTimer_Hdl ) );
    m_aModifyIdle.SetPriority( TaskPriority::LOWEST );

    EnableAutocomplete( false );
}

LookUpComboBox::~LookUpComboBox()
{
    disposeOnce();
}

void LookUpComboBox::dispose()
{
    m_pDialog.clear();
    ComboBox::dispose();
}

VCL_BUILDER_FACTORY(LookUpComboBox)

void LookUpComboBox::init(SvxThesaurusDialog *pDialog)
{
    m_pDialog = pDialog;
}

void LookUpComboBox::Modify()
{
    m_aModifyIdle.Start();
}

IMPL_LINK_NOARG( LookUpComboBox, ModifyTimer_Hdl, Timer *, void )
{
    m_pDialog->LookUp( GetText() );
    LookUp(m_xWordCB->get_active_text());
    m_aModifyIdle.Stop();
}

// class ReplaceEdit --------------------------------------------------

ReplaceEdit::ReplaceEdit(vcl::Window *pParent)
    : Edit(pParent, WB_BORDER | WB_TABSTOP)
    , m_pBtn(nullptr)
IMPL_LINK_NOARG(SvxThesaurusDialog, ReplaceEditHdl_Impl, weld::Entry&, void)
{
    m_xReplaceBtn->set_sensitive(!m_xReplaceEdit->get_text().isEmpty());
}

ReplaceEdit::~ReplaceEdit()
{
    disposeOnce();
}

void ReplaceEdit::dispose()
{
    m_pBtn.clear();
    Edit::dispose();
}

VCL_BUILDER_FACTORY(ReplaceEdit)

void ReplaceEdit::Modify()
{
    if (m_pBtn)
        m_pBtn->Enable( !GetText().isEmpty() );
}

void ReplaceEdit::SetText( const OUString& rStr )
{
    Edit::SetText( rStr );
    Modify();
}

void ReplaceEdit::SetText( const OUString& rStr, const Selection& rNewSelection )
{
    Edit::SetText( rStr, rNewSelection );
    Modify();
}

// class ThesaurusAlternativesCtrl ----------------------------------

AlternativesString::AlternativesString( ThesaurusAlternativesCtrl &rControl, const OUString& rStr ) :
    SvLBoxString( rStr ),
    m_rControlImpl( rControl )
{
}

void AlternativesString::Paint(const Point& rPos, SvTreeListBox& /*rDev*/, vcl::RenderContext& rRenderContext,
                               const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
{
    AlternativesExtraData* pData = m_rControlImpl.GetExtraData(&rEntry);
    Point aPos(rPos);
    rRenderContext.Push(PushFlags::FONT);
    if (pData && pData->IsHeader())
    {
        vcl::Font aFont(rRenderContext.GetFont());
        aFont.SetWeight(WEIGHT_BOLD);
        rRenderContext.SetFont(aFont);
        aPos.setX( 0 );
    }
    else
        aPos.AdjustX(5 );
    rRenderContext.DrawText(aPos, GetText());
    rRenderContext.Pop();
}

ThesaurusAlternativesCtrl::ThesaurusAlternativesCtrl(vcl::Window* pParent)
    : SvxCheckListBox(pParent)
    , m_pDialog(nullptr)
{
    SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL );
    SetForceMakeVisible(true);
    SetHighlightRange();
}

VCL_BUILDER_FACTORY(ThesaurusAlternativesCtrl)

void ThesaurusAlternativesCtrl::init(SvxThesaurusDialog *pDialog)
{
    m_pDialog = pDialog;
}

ThesaurusAlternativesCtrl::~ThesaurusAlternativesCtrl()
{
    disposeOnce();
}

void ThesaurusAlternativesCtrl::dispose()
{
    ClearExtraData();
    m_pDialog.clear();
    SvxCheckListBox::dispose();
}

void ThesaurusAlternativesCtrl::ClearExtraData()
{
    UserDataMap_t   aEmpty;
    m_aUserData.swap( aEmpty );
}

void ThesaurusAlternativesCtrl::SetExtraData(
    const SvTreeListEntry *pEntry,
    const AlternativesExtraData &rData )
{
    if (!pEntry)
        return;

    UserDataMap_t::iterator aIt( m_aUserData.find( pEntry ) );
    if (aIt != m_aUserData.end())
        aIt->second = rData;
    else
        m_aUserData[ pEntry ] = rData;
}

AlternativesExtraData * ThesaurusAlternativesCtrl::GetExtraData(
    const SvTreeListEntry *pEntry )
{
    AlternativesExtraData *pRes = nullptr;
    UserDataMap_t::iterator aIt( m_aUserData.find( pEntry ) );
    if (aIt != m_aUserData.end())
        pRes = &aIt->second;
    return pRes;
}

SvTreeListEntry * ThesaurusAlternativesCtrl::AddEntry( sal_Int32 nVal, const OUString &rText, bool bIsHeader )
{
    SvTreeListEntry* pEntry = new SvTreeListEntry;
    OUString aText;
    if (bIsHeader && nVal >= 0)
    {
        aText = OUString::number( nVal ) + ". ";
    }
    pEntry->AddItem(std::make_unique<SvLBoxString>(OUString())); // add empty column
    aText += rText;
    pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(Image(), Image(), false)); // otherwise crash
    pEntry->AddItem(std::make_unique<AlternativesString>(*this, aText));

    SetExtraData( pEntry, AlternativesExtraData( rText, bIsHeader ) );
    GetModel()->Insert( pEntry );

    if (bIsHeader)
        GetViewDataEntry( pEntry )->SetSelectable( false );

    return pEntry;
}

void ThesaurusAlternativesCtrl::KeyInput( const KeyEvent& rKEvt )
IMPL_LINK(SvxThesaurusDialog, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    const vcl::KeyCode& rKey = rKEvt.GetKeyCode();

    if (rKey.GetCode() == KEY_RETURN || rKey.GetCode() == KEY_ESCAPE)
        GetParent()->KeyInput( rKEvt ); // parent will close dialog...
    else if (rKey.GetCode() == KEY_SPACE)
        m_pDialog->AlternativesDoubleClickHdl_Impl( this ); // look up current selected entry
    else if (GetEntryCount())
        SvxCheckListBox::KeyInput( rKEvt );
}

void ThesaurusAlternativesCtrl::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect)
{
    if (!m_pDialog->WordFound())
    if (rKey.GetCode() == KEY_RETURN)
    {
        Size aTextSize(rRenderContext.GetTextWidth(m_pDialog->getErrStr()), rRenderContext.GetTextHeight());
        aTextSize  = rRenderContext.LogicToPixel(aTextSize);
        Point aPos;
        aPos.AdjustX(GetSizePixel().Width() / 2  - aTextSize.Width() / 2 );
        aPos.AdjustY(GetSizePixel().Height() / 2 );
        aPos = rRenderContext.PixelToLogic(aPos);
        rRenderContext.DrawText(aPos, m_pDialog->getErrStr());
        m_xDialog->response(RET_OK);
        return true;
    }
    else
        SvxCheckListBox::Paint(rRenderContext, rRect);

    return false;
}

uno::Sequence< uno::Reference< linguistic2::XMeaning > > SvxThesaurusDialog::queryMeanings_Impl(
@@ -302,12 +107,10 @@ bool SvxThesaurusDialog::UpdateAlternativesBox_Impl()
    const sal_Int32 nMeanings = aMeanings.getLength();
    const uno::Reference< linguistic2::XMeaning > *pMeanings = aMeanings.getConstArray();

    m_pAlternativesCT->SetUpdateMode( false );
    m_xAlternativesCT->freeze();

    // clear old user data of control before creating new ones via AddEntry below
    m_pAlternativesCT->ClearExtraData();

    m_pAlternativesCT->Clear();
    m_xAlternativesCT->clear();
    int nRow = 0;
    for (sal_Int32 i = 0;  i < nMeanings;  ++i)
    {
        OUString rMeaningTxt = pMeanings[i]->getMeaning();
@@ -317,37 +120,45 @@ bool SvxThesaurusDialog::UpdateAlternativesBox_Impl()
        DBG_ASSERT( !rMeaningTxt.isEmpty(), "meaning with empty text" );
        DBG_ASSERT( nSynonyms > 0, "meaning without synonym" );

        m_pAlternativesCT->AddEntry( i + 1, rMeaningTxt, true );
        for (sal_Int32 k = 0;  k < nSynonyms;  ++k)
            m_pAlternativesCT->AddEntry( -1, pSynonyms[k], false );
        OUString sHeading = OUString::number(i + 1) + ". " + rMeaningTxt;
        m_xAlternativesCT->append_text(sHeading);
        m_xAlternativesCT->set_text_emphasis(nRow, true, 0);

        ++nRow;
        for (sal_Int32 k = 0;  k < nSynonyms; ++k)
        {
            // GetThesaurusReplaceText will strip the leading spaces
            m_xAlternativesCT->append_text("   " + pSynonyms[k]);
            ++nRow;
        }
    }

    m_pAlternativesCT->SetUpdateMode( true );
    m_xAlternativesCT->thaw();

    return nMeanings > 0;
}

void SvxThesaurusDialog::LookUp( const OUString &rText )
{
    if (rText != m_pWordCB->GetText()) // avoid moving of the cursor if the text is the same
        m_pWordCB->SetText( rText );
    if (rText != m_xWordCB->get_active_text()) // avoid moving of the cursor if the text is the same
        m_xWordCB->set_entry_text(rText);
    LookUp_Impl();
}

IMPL_LINK( SvxThesaurusDialog, LeftBtnHdl_Impl, Button *, pBtn, void )
IMPL_LINK_NOARG(SvxThesaurusDialog, LeftBtnHdl_Impl, weld::Button&, void)
{
    if (pBtn && aLookUpHistory.size() >= 2)
    if (aLookUpHistory.size() >= 2)
    {
        aLookUpHistory.pop();                       // remove current look up word from stack
        m_pWordCB->SetText( aLookUpHistory.top() );    // retrieve previous look up word
        m_xWordCB->set_entry_text(aLookUpHistory.top()); // retrieve previous look up word
        aLookUpHistory.pop();
        LookUp_Impl();
    }
}

IMPL_LINK( SvxThesaurusDialog, LanguageHdl_Impl, ListBox&, rLB, void )
IMPL_LINK( SvxThesaurusDialog, LanguageHdl_Impl, weld::ComboBox&, rLB, void )
{
    OUString aLangText( rLB.GetSelectedEntry() );
    OUString aLangText(rLB.get_active_text());
    LanguageType nLang = SvtLanguageTable::GetLanguageType( aLangText );
    DBG_ASSERT( nLang != LANGUAGE_NONE && nLang != LANGUAGE_DONTKNOW, "failed to get language" );
    if (xThesaurus->hasLocale( LanguageTag::convertToLocale( nLang ) ))
@@ -358,7 +169,7 @@ IMPL_LINK( SvxThesaurusDialog, LanguageHdl_Impl, ListBox&, rLB, void )

void SvxThesaurusDialog::LookUp_Impl()
{
    OUString aText( m_pWordCB->GetText() );
    OUString aText(m_xWordCB->get_active_text());

    aLookUpText = aText;
    if (!aLookUpText.isEmpty() &&
@@ -366,107 +177,105 @@ void SvxThesaurusDialog::LookUp_Impl()
        aLookUpHistory.push( aLookUpText );

    m_bWordFound = UpdateAlternativesBox_Impl();
    m_pAlternativesCT->Enable( m_bWordFound );
    m_xAlternativesCT->set_visible(m_bWordFound);
    m_xNotFound->set_visible(!m_bWordFound);

    if ( m_pWordCB->GetEntryPos( aText ) == LISTBOX_ENTRY_NOTFOUND )
        m_pWordCB->InsertEntry( aText );
    if (m_bWordFound)
        Application::PostUserEvent(LINK(this, SvxThesaurusDialog, SelectFirstHdl_Impl));

    m_pReplaceEdit->SetText( OUString() );
    m_pLeftBtn->Enable( aLookUpHistory.size() > 1 );
    if (m_xWordCB->find_text(aText) == -1)
        m_xWordCB->append_text(aText);

    m_xReplaceEdit->set_text( OUString() );
    ReplaceEditHdl_Impl(*m_xReplaceEdit);
    m_xLeftBtn->set_sensitive( aLookUpHistory.size() > 1 );
}

IMPL_LINK( SvxThesaurusDialog, WordSelectHdl_Impl, ComboBox&, rBox, void )
IMPL_LINK_NOARG(SvxThesaurusDialog, WordSelectHdl_Impl, weld::ComboBox&, void)
{
    if (!m_pWordCB->IsTravelSelect())  // act only upon return key and not when traveling with cursor keys
    m_aModifyIdle.Start();
}

IMPL_LINK( SvxThesaurusDialog, AlternativesSelectHdl_Impl, weld::TreeView&, rBox, void )
{
    int nEntry = rBox.get_selected_index();
    if (nEntry != -1)
    {
        const sal_Int32 nPos = rBox.GetSelectedEntryPos();
        OUString aStr( rBox.GetEntry( nPos ) );
        aStr = linguistic::GetThesaurusReplaceText( aStr );
        m_pWordCB->SetText( aStr );
        LookUp_Impl();
        bool bIsHeader = rBox.get_text_emphasis(nEntry, 0);
        if (bIsHeader)
        {
            ++nEntry;
            rBox.select(nEntry);
        }
        OUString aStr = linguistic::GetThesaurusReplaceText(rBox.get_text(nEntry));
        m_xReplaceEdit->set_text(aStr);
        ReplaceEditHdl_Impl(*m_xReplaceEdit);
    }
}

IMPL_LINK( SvxThesaurusDialog, AlternativesSelectHdl_Impl, SvTreeListBox *, pBox, void )
IMPL_LINK( SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl, weld::TreeView&, rBox, void )
{
    SvTreeListEntry *pEntry = pBox ? pBox->GetCurEntry() : nullptr;
    if (pEntry)
    int nEntry = rBox.get_selected_index();
    if (nEntry != -1)
    {
        AlternativesExtraData * pData = m_pAlternativesCT->GetExtraData( pEntry );
        OUString aStr;
        if (pData && !pData->IsHeader())
        bool bIsHeader = rBox.get_text_emphasis(nEntry, 0);
        if (bIsHeader)
        {
            aStr = pData->GetText();
            aStr = linguistic::GetThesaurusReplaceText( aStr );
            ++nEntry;
            rBox.select(nEntry);
        }
        m_pReplaceEdit->SetText( aStr );
    }
}

IMPL_LINK( SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl, SvTreeListBox*, pBox, bool )
{
    SvTreeListEntry *pEntry = pBox ? pBox->GetCurEntry() : nullptr;
    if (pEntry)
    {
        AlternativesExtraData * pData = m_pAlternativesCT->GetExtraData( pEntry );
        OUString aStr;
        if (pData && !pData->IsHeader())
        {
            aStr = pData->GetText();
            aStr = linguistic::GetThesaurusReplaceText( aStr );
        }

        m_pWordCB->SetText( aStr );
        OUString aStr = linguistic::GetThesaurusReplaceText(rBox.get_text(nEntry));
        m_xWordCB->set_entry_text(aStr);
        if (!aStr.isEmpty())
            LookUp_Impl();
    }

    //! workaround to set the selection since calling SelectEntryPos within
    //! the double click handler does not work
    Application::PostUserEvent( LINK( this, SvxThesaurusDialog, SelectFirstHdl_Impl ), pBox, true );
    return false;
    Application::PostUserEvent(LINK(this, SvxThesaurusDialog, SelectFirstHdl_Impl));
}

IMPL_STATIC_LINK( SvxThesaurusDialog, SelectFirstHdl_Impl, void *, p, void )
IMPL_LINK_NOARG(SvxThesaurusDialog, SelectFirstHdl_Impl, void *, void)
{
    SvxCheckListBox* pBox = static_cast<SvxCheckListBox*>(p);
    if (pBox && pBox->GetEntryCount() >= 2)
        pBox->SelectEntryPos( 1 );  // pos 0 is a 'header' that is not selectable
    if (m_xAlternativesCT->n_children() >= 2)
    {
        m_xAlternativesCT->select(1);  // pos 0 is a 'header' that is not selectable
        AlternativesSelectHdl_Impl(*m_xAlternativesCT);
    }
}

// class SvxThesaurusDialog ----------------------------------------------

SvxThesaurusDialog::SvxThesaurusDialog(
    vcl::Window* pParent,
    weld::Window* pParent,
    uno::Reference< linguistic2::XThesaurus > const & xThes,
    const OUString &rWord,
    LanguageType nLanguage)
    : SvxStandardDialog(pParent, "ThesaurusDialog", "cui/ui/thesaurus.ui")
    , m_aErrStr(CuiResId(RID_SVXSTR_ERR_TEXTNOTFOUND))
    : SfxDialogController(pParent, "cui/ui/thesaurus.ui", "ThesaurusDialog")
    , m_aModifyIdle("cui SvxThesaurusDialog LookUp Modify")
    , aLookUpText()
    , nLookUpLanguage(LANGUAGE_NONE)
    , m_bWordFound(false)
    , m_xLeftBtn(m_xBuilder->weld_button("left"))
    , m_xWordCB(m_xBuilder->weld_combo_box("wordcb"))
    , m_xAlternativesCT(m_xBuilder->weld_tree_view("alternatives"))
    , m_xNotFound(m_xBuilder->weld_label("notfound"))
    , m_xReplaceEdit(m_xBuilder->weld_entry("replaceed"))
    , m_xLangLB(m_xBuilder->weld_combo_box("langcb"))
    , m_xReplaceBtn(m_xBuilder->weld_button("ok"))
{
    get(m_pLeftBtn, "left");
    m_aModifyIdle.SetInvokeHandler( LINK( this, SvxThesaurusDialog, ModifyTimer_Hdl ) );
    m_aModifyIdle.SetPriority( TaskPriority::LOWEST );

    get(m_pWordCB, "wordcb");
    m_pWordCB->init(this);

    get(m_pAlternativesCT, "alternatives");
    m_pAlternativesCT->init(this);

    get(m_pReplaceEdit, "replaceed");
    PushButton *pReplaceBtn = get<PushButton>("replace");
    m_pReplaceEdit->init(pReplaceBtn);

    get(m_pLangLB, "langcb");

    pReplaceBtn->SetClickHdl( LINK( this, SvxThesaurusDialog, ReplaceBtnHdl_Impl ) );
    m_pLeftBtn->SetClickHdl( LINK( this, SvxThesaurusDialog, LeftBtnHdl_Impl ) );
    m_pWordCB->SetSelectHdl( LINK( this, SvxThesaurusDialog, WordSelectHdl_Impl ) );
    m_pLangLB->SetSelectHdl( LINK( this, SvxThesaurusDialog, LanguageHdl_Impl ) );
    m_pAlternativesCT->SetSelectHdl( LINK( this, SvxThesaurusDialog, AlternativesSelectHdl_Impl ));
    m_pAlternativesCT->SetDoubleClickHdl( LINK( this, SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl ));
    m_xReplaceEdit->connect_changed( LINK( this, SvxThesaurusDialog, ReplaceEditHdl_Impl ) );
    m_xReplaceBtn->connect_clicked( LINK( this, SvxThesaurusDialog, ReplaceBtnHdl_Impl ) );
    m_xLeftBtn->connect_clicked( LINK( this, SvxThesaurusDialog, LeftBtnHdl_Impl ) );
    m_xWordCB->set_entry_completion(false);
    m_xWordCB->connect_changed( LINK( this, SvxThesaurusDialog, WordSelectHdl_Impl ) );
    m_xLangLB->connect_changed( LINK( this, SvxThesaurusDialog, LanguageHdl_Impl ) );
    m_xAlternativesCT->connect_changed( LINK( this, SvxThesaurusDialog, AlternativesSelectHdl_Impl ));
    m_xAlternativesCT->connect_row_activated( LINK( this, SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl ));
    m_xAlternativesCT->connect_key_press(LINK(this, SvxThesaurusDialog, KeyInputHdl));

    xThesaurus = xThes;
    aLookUpText = rWord;
@@ -477,12 +286,13 @@ SvxThesaurusDialog::SvxThesaurusDialog(
    OUString aTmp( rWord );
    (void)linguistic::RemoveHyphens( aTmp );
    (void)linguistic::ReplaceControlChars( aTmp );
    m_pReplaceEdit->SetText( aTmp );
    m_pWordCB->InsertEntry( aTmp );
    m_xReplaceEdit->set_text( aTmp );
    ReplaceEditHdl_Impl(*m_xReplaceEdit);
    m_xWordCB->append_text( aTmp );

    LookUp( aTmp );
    m_pAlternativesCT->GrabFocus();
    m_pLeftBtn->Enable( false );
    m_xAlternativesCT->grab_focus();
    m_xLeftBtn->set_sensitive(false);

    // fill language menu button list
    uno::Sequence< lang::Locale > aLocales;
@@ -490,7 +300,7 @@ SvxThesaurusDialog::SvxThesaurusDialog(
        aLocales = xThesaurus->getLocales();
    const sal_Int32 nLocales = aLocales.getLength();
    const lang::Locale *pLocales = aLocales.getConstArray();
    m_pLangLB->Clear();
    m_xLangLB->clear();
    std::vector< OUString > aLangVec;
    for (sal_Int32 i = 0;  i < nLocales; ++i)
    {
@@ -499,62 +309,48 @@ SvxThesaurusDialog::SvxThesaurusDialog(
        aLangVec.push_back( SvtLanguageTable::GetLanguageString( nLang ) );
    }
    std::sort( aLangVec.begin(), aLangVec.end() );
    m_xLangLB->freeze();
    for (OUString & i : aLangVec)
        m_pLangLB->InsertEntry( i );
        m_xLangLB->append_text(i);
    m_xLangLB->thaw();

    std::vector< OUString >::iterator aI = std::find(aLangVec.begin(), aLangVec.end(),
            SvtLanguageTable::GetLanguageString(nLanguage));
    if (aI != aLangVec.end())
    {
        m_pLangLB->SelectEntry(*aI);
        m_xLangLB->set_active_text(*aI);
    }

    SetWindowTitle(nLanguage);

    // disable controls if service is missing
    if (!xThesaurus.is())
        Enable( false );
        m_xDialog->set_sensitive(false);
}

SvxThesaurusDialog::~SvxThesaurusDialog()
{
    disposeOnce();
}

void SvxThesaurusDialog::dispose()
IMPL_LINK_NOARG(SvxThesaurusDialog, ReplaceBtnHdl_Impl, weld::Button&, void)
{
    m_pLeftBtn.clear();
    m_pWordCB.clear();
    m_pAlternativesCT.clear();
    m_pReplaceEdit.clear();
    m_pLangLB.clear();
    SvxStandardDialog::dispose();
}

IMPL_LINK_NOARG( SvxThesaurusDialog, ReplaceBtnHdl_Impl, Button *, void )
{
    EndDialog(RET_OK);
    m_xDialog->response(RET_OK);
}

void SvxThesaurusDialog::SetWindowTitle( LanguageType nLanguage )
{
    // adjust language
    OUString aStr( GetText() );
    OUString aStr(m_xDialog->get_title());
    sal_Int32 nIndex = aStr.indexOf( '(' );
    if( nIndex != -1 )
        aStr = aStr.copy( 0, nIndex - 1 );
    aStr += " (" + SvtLanguageTable::GetLanguageString( nLanguage ) + ")";
    SetText( aStr );    // set window title
    m_xDialog->set_title(aStr);    // set window title
}

OUString SvxThesaurusDialog::GetWord()
{
    return m_pReplaceEdit->GetText();
}


void SvxThesaurusDialog::Apply()
{
    return m_xReplaceEdit->get_text();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/thesdlg_impl.hxx b/cui/source/dialogs/thesdlg_impl.hxx
deleted file mode 100644
index 5047132..0000000
--- a/cui/source/dialogs/thesdlg_impl.hxx
+++ /dev/null
@@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_CUI_SOURCE_DIALOGS_THESDLG_IMPL_HXX
#define INCLUDED_CUI_SOURCE_DIALOGS_THESDLG_IMPL_HXX

#include <thesdlg.hxx>

#include <svtools/ehdl.hxx>
#include <vcl/svlbitm.hxx>
#include <svx/checklbx.hxx>
#include <vcl/button.hxx>
#include <vcl/combobox.hxx>
#include <vcl/edit.hxx>
#include <vcl/image.hxx>
#include <vcl/menubtn.hxx>
#include <vcl/svapp.hxx>
#include <vcl/timer.hxx>
#include <vcl/wrkwin.hxx>

#include <stack>
#include <map>
#include <algorithm>

class SvTreeListEntry;
class ThesaurusAlternativesCtrl;

class AlternativesString : public SvLBoxString
{
    ThesaurusAlternativesCtrl&    m_rControlImpl;
public:

    AlternativesString( ThesaurusAlternativesCtrl &rControl, const OUString& rStr );

    virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext,
                       const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
index d9d8183..17f8c13 100644
--- a/cui/source/factory/dlgfact.cxx
+++ b/cui/source/factory/dlgfact.cxx
@@ -133,7 +133,15 @@ short AbstractHyphenWordDialog_Impl::Execute()
    return m_xDlg->run();
}

IMPL_ABSTDLG_BASE(AbstractThesaurusDialog_Impl)
short AbstractThesaurusDialog_Impl::Execute()
{
    return m_xDlg->run();
}

bool AbstractThesaurusDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
{
    return SfxDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
}

short AbstractSvxZoomDialog_Impl::Execute()
{
@@ -463,7 +471,7 @@ OUString AbstractHangulHanjaConversionDialog_Impl::GetCurrentSuggestion( ) const

OUString AbstractThesaurusDialog_Impl::GetWord()
{
    return pDlg->GetWord();
    return m_xDlg->GetWord();
};

Reference < css::embed::XEmbeddedObject > AbstractInsertObjectDialog_Impl::GetObject()
@@ -1016,12 +1024,11 @@ VclPtr<AbstractHangulHanjaConversionDialog> AbstractDialogFactory_Impl::CreateHa
    return VclPtr<AbstractHangulHanjaConversionDialog_Impl>::Create(std::make_unique<HangulHanjaConversionDialog>(pParent));
}

VclPtr<AbstractThesaurusDialog> AbstractDialogFactory_Impl::CreateThesaurusDialog( vcl::Window* pParent,
                                css::uno::Reference< css::linguistic2::XThesaurus >  xThesaurus,
                                const OUString &rWord, LanguageType nLanguage )
VclPtr<AbstractThesaurusDialog> AbstractDialogFactory_Impl::CreateThesaurusDialog(weld::Window* pParent,
                                css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
                                const OUString &rWord, LanguageType nLanguage)
{
    VclPtrInstance<SvxThesaurusDialog> pDlg( pParent, xThesaurus, rWord, nLanguage );
    return VclPtr<AbstractThesaurusDialog_Impl>::Create( pDlg );
    return VclPtr<AbstractThesaurusDialog_Impl>::Create(std::make_unique<SvxThesaurusDialog>(pParent, xThesaurus, rWord, nLanguage));
}

VclPtr<AbstractHyphenWordDialog> AbstractDialogFactory_Impl::CreateHyphenWordDialog(weld::Window* pParent,
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
index 1a64bc9..6623de4 100644
--- a/cui/source/factory/dlgfact.hxx
+++ b/cui/source/factory/dlgfact.hxx
@@ -183,7 +183,14 @@ public:

class AbstractThesaurusDialog_Impl : public AbstractThesaurusDialog
{
    DECL_ABSTDLG_BASE(AbstractThesaurusDialog_Impl,SvxThesaurusDialog)
    std::shared_ptr<SvxThesaurusDialog> m_xDlg;
public:
    explicit AbstractThesaurusDialog_Impl(std::unique_ptr<SvxThesaurusDialog> p)
        : m_xDlg(std::move(p))
    {
    }
    virtual short Execute() override;
    virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
    virtual OUString    GetWord() override;
};

@@ -715,8 +722,9 @@ public:
    virtual VclPtr<SfxAbstractLinksDialog> CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML = false, sfx2::SvBaseLink* p=nullptr) override;

    virtual VclPtr<AbstractHangulHanjaConversionDialog> CreateHangulHanjaConversionDialog(weld::Window* pParent) override;
    virtual VclPtr<AbstractThesaurusDialog>  CreateThesaurusDialog( vcl::Window*, css::uno::Reference< css::linguistic2::XThesaurus >  xThesaurus,
                                                const OUString &rWord, LanguageType nLanguage ) override;
    virtual VclPtr<AbstractThesaurusDialog>  CreateThesaurusDialog(weld::Window*,
                                                css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
                                                const OUString &rWord, LanguageType nLanguage) override;

    virtual VclPtr<AbstractHyphenWordDialog> CreateHyphenWordDialog(weld::Window*,
                                                const OUString &rWord, LanguageType nLang,
diff --git a/cui/source/inc/thesdlg.hxx b/cui/source/inc/thesdlg.hxx
index 97a78c6..a00d9ae 100644
--- a/cui/source/inc/thesdlg.hxx
+++ b/cui/source/inc/thesdlg.hxx
@@ -26,108 +26,14 @@
#include <vcl/combobox.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/idle.hxx>
#include <svx/stddlg.hxx>
#include <sfx2/basedlgs.hxx>

#include <memory>
#include <stack>

class SvxThesaurusDialog;

class LookUpComboBox : public ComboBox
class SvxThesaurusDialog : public SfxDialogController
{
    Idle                        m_aModifyIdle;
    VclPtr<SvxThesaurusDialog>         m_pDialog;

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

public:
    LookUpComboBox(vcl::Window *pParent);
    virtual ~LookUpComboBox() override;
    virtual void dispose() override;

    DECL_LINK( ModifyTimer_Hdl, Timer *, void );

    void init(SvxThesaurusDialog *pDialog);

    // ComboBox
    virtual void        Modify() override;
};

class AlternativesExtraData
{
    OUString  sText;
    bool      bHeader;

public:
    AlternativesExtraData() : bHeader( false ) {}
    AlternativesExtraData( const OUString &rText, bool bIsHeader ) :
        sText(rText),
        bHeader(bIsHeader)
        {
        }

    bool  IsHeader() const          { return bHeader; }
    const OUString& GetText() const   { return sText; }
};

class ThesaurusAlternativesCtrl
    : public SvxCheckListBox
{
    VclPtr<SvxThesaurusDialog>     m_pDialog;

    typedef std::map< const SvTreeListEntry *, AlternativesExtraData >  UserDataMap_t;
    UserDataMap_t           m_aUserData;

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

public:
    ThesaurusAlternativesCtrl(vcl::Window* pParent);

    void init(SvxThesaurusDialog *pDialog);
    virtual ~ThesaurusAlternativesCtrl() override;
    virtual void dispose() override;

    SvTreeListEntry *   AddEntry( sal_Int32 nVal, const OUString &rText, bool bIsHeader );

    void            ClearExtraData();
    void            SetExtraData( const SvTreeListEntry *pEntry, const AlternativesExtraData &rData );
    AlternativesExtraData * GetExtraData( const SvTreeListEntry *pEntry );

    virtual void    KeyInput( const KeyEvent& rKEvt ) override;
    virtual void    Paint( vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect ) override;
};

class ReplaceEdit : public Edit
{
    VclPtr<Button>       m_pBtn;

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

public:
    ReplaceEdit(vcl::Window *pParent);
    virtual ~ReplaceEdit() override;
    virtual void dispose() override;

    void init(Button *pBtn)  { m_pBtn = pBtn; }

    // Edit
    virtual void        Modify() override;
    virtual void        SetText( const OUString& rStr ) override;
    virtual void        SetText( const OUString& rStr, const Selection& rNewSelection ) override;
};

class SvxThesaurusDialog : public SvxStandardDialog
{
    VclPtr<PushButton>             m_pLeftBtn;
    VclPtr<LookUpComboBox>         m_pWordCB;
    VclPtr<ThesaurusAlternativesCtrl> m_pAlternativesCT;
    VclPtr<ReplaceEdit>            m_pReplaceEdit;
    VclPtr<ListBox>                m_pLangLB;

    OUString                m_aErrStr;
    Idle                    m_aModifyIdle;

    css::uno::Reference< css::linguistic2::XThesaurus >   xThesaurus;
    OUString                aLookUpText;
@@ -135,22 +41,30 @@ class SvxThesaurusDialog : public SvxStandardDialog
    std::stack< OUString >  aLookUpHistory;
    bool                    m_bWordFound;

    std::unique_ptr<weld::Button> m_xLeftBtn;
    std::unique_ptr<weld::ComboBox> m_xWordCB;
    std::unique_ptr<weld::TreeView> m_xAlternativesCT;
    std::unique_ptr<weld::Label> m_xNotFound;
    std::unique_ptr<weld::Entry> m_xReplaceEdit;
    std::unique_ptr<weld::ComboBox> m_xLangLB;
    std::unique_ptr<weld::Button> m_xReplaceBtn;

public:
    virtual ~SvxThesaurusDialog() override;
    virtual void dispose() override;

    bool                    WordFound() const { return m_bWordFound; }
    const OUString&         getErrStr() const { return m_aErrStr; }

    // Handler
    DECL_LINK( ReplaceBtnHdl_Impl, Button *, void );
    DECL_LINK( LeftBtnHdl_Impl, Button *, void );
    DECL_LINK( LanguageHdl_Impl, ListBox&, void );
    DECL_LINK( WordSelectHdl_Impl, ComboBox&, void );
    DECL_LINK( AlternativesSelectHdl_Impl, SvTreeListBox*, void );
    DECL_LINK( AlternativesDoubleClickHdl_Impl, SvTreeListBox*, bool );

    DECL_STATIC_LINK( SvxThesaurusDialog, SelectFirstHdl_Impl, void*, void );
    DECL_LINK( ReplaceBtnHdl_Impl, weld::Button&, void );
    DECL_LINK( LeftBtnHdl_Impl, weld::Button&, void );
    DECL_LINK( LanguageHdl_Impl, weld::ComboBox&, void );
    DECL_LINK( WordSelectHdl_Impl, weld::ComboBox&, void );
    DECL_LINK( AlternativesSelectHdl_Impl, weld::TreeView&, void );
    DECL_LINK( AlternativesDoubleClickHdl_Impl, weld::TreeView&, void );
    DECL_LINK( SelectFirstHdl_Impl, void*, void );
    DECL_LINK( ReplaceEditHdl_Impl, weld::Entry&, void );
    DECL_LINK( ModifyTimer_Hdl, Timer *, void );
    DECL_LINK( KeyInputHdl, const KeyEvent&, bool );

    /// @throws css::lang::IllegalArgumentException
    /// @throws css::uno::RuntimeException
@@ -160,13 +74,11 @@ public:
    bool    UpdateAlternativesBox_Impl();
    void    LookUp( const OUString &rText );
    void    LookUp_Impl();
    virtual void     Apply() override;

public:
    SvxThesaurusDialog( vcl::Window* pParent,
                        css::uno::Reference< css::linguistic2::XThesaurus > const & xThesaurus,
                        const OUString &rWord, LanguageType nLanguage );

    SvxThesaurusDialog(weld::Window* pParent,
                       css::uno::Reference< css::linguistic2::XThesaurus > const & xThesaurus,
                       const OUString &rWord, LanguageType nLanguage);
    void            SetWindowTitle( LanguageType nLanguage );
    OUString        GetWord();
};
diff --git a/cui/uiconfig/ui/accelconfigpage.ui b/cui/uiconfig/ui/accelconfigpage.ui
index 8d058c6..61f01d0 100644
--- a/cui/uiconfig/ui/accelconfigpage.ui
+++ b/cui/uiconfig/ui/accelconfigpage.ui
@@ -28,7 +28,7 @@
      <column type="gchararray"/>
      <!-- column-name weight1 -->
      <column type="gint"/>
      <!-- column-name weight1 -->
      <!-- column-name weight2 -->
      <column type="gint"/>
      <!-- column-name sensitive1 -->
      <column type="gboolean"/>
diff --git a/cui/uiconfig/ui/thesaurus.ui b/cui/uiconfig/ui/thesaurus.ui
index 3906c80..00df61a 100644
--- a/cui/uiconfig/ui/thesaurus.ui
+++ b/cui/uiconfig/ui/thesaurus.ui
@@ -1,19 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkImage" id="image1">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="stock">gtk-go-back</property>
  </object>
  <object class="GtkTreeStore" id="liststore3">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
      <!-- column-name weight1 -->
      <column type="gint"/>
    </columns>
  </object>
  <object class="GtkDialog" id="ThesaurusDialog">
    <property name="can_focus">False</property>
    <property name="border_width">6</property>
    <property name="title" translatable="yes" context="thesaurus|ThesaurusDialog">Thesaurus</property>
    <property name="resizable">False</property>
    <property name="modal">True</property>
    <property name="default_width">0</property>
    <property name="default_height">0</property>
    <property name="type_hint">dialog</property>
    <child>
      <placeholder/>
    </child>
    <child internal-child="vbox">
      <object class="GtkBox" id="dialog-vbox1">
        <property name="can_focus">False</property>
@@ -39,10 +54,11 @@
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="replace">
              <object class="GtkButton" id="ok">
                <property name="label" translatable="yes" context="thesaurus|replace">_Replace</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="can_default">True</property>
                <property name="has_default">True</property>
                <property name="receives_default">True</property>
                <property name="use_underline">True</property>
@@ -58,6 +74,7 @@
                <property name="label">gtk-cancel</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="can_default">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </object>
@@ -85,10 +102,10 @@
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="xalign">0</property>
                <property name="label" translatable="yes" context="thesaurus|label1">Current word:</property>
                <property name="use_underline">True</property>
                <property name="mnemonic_widget">wordcb</property>
                <property name="xalign">0</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
@@ -100,10 +117,10 @@
              <object class="GtkLabel" id="label2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="xalign">0</property>
                <property name="label" translatable="yes" context="thesaurus|label2">Alternatives:</property>
                <property name="use_underline">True</property>
                <property name="mnemonic_widget">alternatives</property>
                <property name="xalign">0</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -115,10 +132,10 @@
              <object class="GtkLabel" id="label3">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="xalign">0</property>
                <property name="label" translatable="yes" context="thesaurus|label3">Replace with:</property>
                <property name="use_underline">True</property>
                <property name="mnemonic_widget">replaceed</property>
                <property name="xalign">0</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -127,9 +144,10 @@
              </packing>
            </child>
            <child>
              <object class="cuilo-ReplaceEdit" id="replaceed">
              <object class="GtkEntry" id="replaceed">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="activates_default">True</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -138,18 +156,6 @@
              </packing>
            </child>
            <child>
              <object class="cuilo-LookUpComboBox" id="wordcb">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="valign">center</property>
                <property name="hexpand">True</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
                <property name="top_attach">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="left">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
@@ -175,11 +181,91 @@
              </packing>
            </child>
            <child>
              <object class="cuilo-ThesaurusAlternativesCtrl" id="alternatives">
              <object class="GtkComboBoxText" id="wordcb">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="valign">center</property>
                <property name="hexpand">True</property>
                <property name="has_entry">True</property>
                <child internal-child="entry">
                  <object class="GtkEntry">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="activates_default">True</property>
                  </object>
                </child>
              </object>
              <packing>
                <property name="left_attach">1</property>
                <property name="top_attach">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkBox">
                <property name="width_request">450</property>
                <property name="height_request">250</property>
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <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="alternatives">
                        <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="model">liststore3</property>
                        <property name="headers_visible">False</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
                        </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>
                                <attribute name="weight">2</attribute>
                              </attributes>
                            </child>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkLabel" id="notfound">
                    <property name="can_focus">False</property>
                    <property name="no_show_all">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="label" translatable="yes" context="thesaurus|RID_SVXSTR_ERR_TEXTNOTFOUND">No alternatives found.</property>
                    <property name="xalign">0.5</property>
                    <property name="yalign">0.5</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -201,7 +287,7 @@
    </child>
    <action-widgets>
      <action-widget response="-11">help</action-widget>
      <action-widget response="101">replace</action-widget>
      <action-widget response="-5">ok</action-widget>
      <action-widget response="-6">cancel</action-widget>
    </action-widgets>
  </object>
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index 79ac6ac..d3f23c6 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -2429,7 +2429,8 @@ EESpellState ImpEditEngine::StartThesaurus( EditView* pEditView )
        return EESpellState::ErrorFound;

    EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
    ScopedVclPtr<AbstractThesaurusDialog> xDlg(pFact->CreateThesaurusDialog( pEditView->GetWindow(), xThes, aWord, GetLanguage( aCurSel.Max() ) ));
    ScopedVclPtr<AbstractThesaurusDialog> xDlg(pFact->CreateThesaurusDialog(pEditView->GetWindow()->GetFrameWeld(), xThes,
                                               aWord, GetLanguage( aCurSel.Max() ) ));
    if (xDlg->Execute() == RET_OK)
    {
        // Replace Word...
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index e2304ab..290635d 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -27,15 +27,9 @@
    <glade-widget-class title="Search Results Box" name="sfxlo-SearchResultsBox"
                        generic-name="SearchResultsBox" parent="GtkComboBoxText"
                        icon-name="widget-gtk-comboboxtext"/>
    <glade-widget-class title="Thesaurus View" name="cuilo-ThesaurusAlternativesCtrl"
                        generic-name="ThesaurusAlternativesCtrl" parent="GtkTextView"
                        icon-name="widget-gtk-textview"/>
    <glade-widget-class title="Spelling View" name="cuilo-SentenceEditWindow"
                        generic-name="SentenceEditWindow" parent="GtkTextView"
                        icon-name="widget-gtk-textview"/>
    <glade-widget-class title="Thesaurus Edit" name="cuilo-ReplaceEdit"
                        generic-name="ReplaceEdit" parent="GtkEntry"
                        icon-name="widget-gtk-textentry"/>
    <glade-widget-class title="Condition Edit" name="rptuilo-ConditionField"
                        generic-name="ConditionEdit" parent="GtkEntry"
                        icon-name="widget-gtk-comboboxtext"/>
diff --git a/include/editeng/edtdlg.hxx b/include/editeng/edtdlg.hxx
index 76b36de..7aeff99 100644
--- a/include/editeng/edtdlg.hxx
+++ b/include/editeng/edtdlg.hxx
@@ -93,8 +93,9 @@ class EDITENG_DLLPUBLIC EditAbstractDialogFactory : virtual public VclAbstractDi
public:
                                        virtual ~EditAbstractDialogFactory() override;   // needed for export of vtable
    static EditAbstractDialogFactory*   Create();
    virtual VclPtr<AbstractThesaurusDialog>  CreateThesaurusDialog( vcl::Window*, css::uno::Reference< css::linguistic2::XThesaurus >  xThesaurus,
                                                const OUString &rWord, LanguageType nLanguage ) = 0;
    virtual VclPtr<AbstractThesaurusDialog>  CreateThesaurusDialog(weld::Window*,
                                                css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
                                                const OUString &rWord, LanguageType nLanguage) = 0;

    virtual VclPtr<AbstractHyphenWordDialog> CreateHyphenWordDialog(weld::Window*,
                                                const OUString &rWord, LanguageType nLang,
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index a033287..19c808b 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -681,6 +681,8 @@ public:
    virtual void set_image(int row, const css::uno::Reference<css::graphic::XGraphic>& rImage,
                           int col = -1)
        = 0;
    virtual void set_text_emphasis(int row, bool bOn, int col) = 0;
    virtual bool get_text_emphasis(int row, int col) const = 0;
    virtual void set_top_entry(int pos) = 0;
    virtual void swap(int pos1, int pos2) = 0;
    virtual std::vector<int> get_selected_rows() const = 0;
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index be5f753..9160dec 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -459,7 +459,6 @@ custom_widgets = [
    'IndexBox',
    'IndexBox',
    'LightButton',
    'LookUpComboBox',
    'ManagedMenuButton',
    'MultiLineEditSyntaxHighlight',
    'OFileURLControl',
@@ -470,7 +469,6 @@ custom_widgets = [
    'PriorityMergedHBox',
    'PropertyControl',
    'RecentDocsView',
    'ReplaceEdit',
    'RowEdit',
    'SameContentListBox',
    'ScCsvTableBox',
@@ -512,7 +510,6 @@ custom_widgets = [
    'SwNavHelpToolBox',
    'TableValueSet',
    'TemplateDefaultView',
    'ThesaurusAlternativesCtrl',
    'ValueSet',
    ]

diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist
index a48a9b1..164cf6c 100644
--- a/solenv/clang-format/blacklist
+++ b/solenv/clang-format/blacklist
@@ -2739,7 +2739,6 @@ cui/source/dialogs/showcols.cxx
cui/source/dialogs/splitcelldlg.cxx
cui/source/dialogs/srchxtra.cxx
cui/source/dialogs/thesdlg.cxx
cui/source/dialogs/thesdlg_impl.hxx
cui/source/dialogs/zoom.cxx
cui/source/factory/cuiexp.cxx
cui/source/factory/cuiresmgr.cxx
diff --git a/solenv/sanitizers/ui/cui.suppr b/solenv/sanitizers/ui/cui.suppr
index 512621d..d5edb8a 100644
--- a/solenv/sanitizers/ui/cui.suppr
+++ b/solenv/sanitizers/ui/cui.suppr
@@ -439,6 +439,7 @@ cui/uiconfig/ui/textanimtabpage.ui://GtkLabel[@id='FT_DELAY'] orphan-label
cui/uiconfig/ui/textflowpage.ui://GtkLabel[@id='labelOrphan'] orphan-label
cui/uiconfig/ui/textflowpage.ui://GtkLabel[@id='labelWidow'] orphan-label
cui/uiconfig/ui/thesaurus.ui://GtkButton[@id='left'] button-no-label
cui/uiconfig/ui/thesaurus.ui://GtkLabel[@id='notfound'] orphan-label
cui/uiconfig/ui/tsaurldialog.ui://GtkLabel[@id='label2'] orphan-label
cui/uiconfig/ui/tsaurldialog.ui://GtkTreeView[@id='urls:border'] no-labelled-by
cui/uiconfig/ui/tsaurldialog.ui://GtkLabel[@id='enteraurl'] orphan-label
diff --git a/sw/source/uibase/uiview/viewling.cxx b/sw/source/uibase/uiview/viewling.cxx
index 28618e6..28fad56 100644
--- a/sw/source/uibase/uiview/viewling.cxx
+++ b/sw/source/uibase/uiview/viewling.cxx
@@ -578,7 +578,7 @@ void SwView::StartThesaurus()
            SwWait aWait( *GetDocShell(), true );
            // load library with dialog only on demand ...
            SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
            pDlg.reset(pFact->CreateThesaurusDialog(&GetEditWin(), xThes, aTmp, eLang));
            pDlg.reset(pFact->CreateThesaurusDialog(GetEditWin().GetFrameWeld(), xThes, aTmp, eLang));
        }

        if (pDlg)
@@ -590,6 +590,7 @@ void SwView::StartThesaurus()
                    InsertThesaurusSynonym(pDlg->GetWord(), aTmp, bSelection);

                pVOpt->SetIdle(bOldIdle);
                pDlg->disposeOnce();
            });
        }
    }
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index ac664d8..82ca26b 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3141,12 +3141,24 @@ public:
        set_text_emphasis(rVclIter.iter, bOn, col);
    }

    virtual void set_text_emphasis(int pos, bool bOn, int col) override
    {
        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
        set_text_emphasis(pEntry, bOn, col);
    }

    virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        return ::get_text_emphasis(rVclIter.iter, col);
    }

    virtual bool get_text_emphasis(int pos, int col) const override
    {
        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
        return ::get_text_emphasis(pEntry, col);
    }

    void set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
    {
        if (col == -1)
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 9e9887e..bd1f8a6f 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -6361,6 +6361,17 @@ private:
        return nRet;
    }

    gint get_int(int pos, int col) const
    {
        gint nRet(-1);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter iter;
        if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
            nRet = get_int(iter, col);
        gtk_tree_model_get(pModel, &iter, col, &nRet, -1);
        return nRet;
    }

    bool get_bool(const GtkTreeIter& iter, int col) const
    {
        gboolean bRet(false);
@@ -6411,6 +6422,14 @@ private:
        gtk_tree_store_set(m_pTreeStore, const_cast<GtkTreeIter*>(&iter), col, bInt, -1);
    }

    void set(int pos, int col, gint bInt)
    {
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter iter;
        if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
            set(iter, col, bInt);
    }

    static gboolean signalTestExpandRow(GtkTreeView*, GtkTreeIter* iter, GtkTreePath*, gpointer widget)
    {
        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
@@ -7118,6 +7137,12 @@ public:
        set(rGtkIter.iter, m_aWeightMap[col], bOn ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
    }

    virtual void set_text_emphasis(int pos, bool bOn, int col) override
    {
        col = get_model_col(col);
        set(pos, m_aWeightMap[col], bOn ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
    }

    virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
@@ -7125,6 +7150,12 @@ public:
        return get_int(rGtkIter.iter, m_aWeightMap.find(col)->second) == PANGO_WEIGHT_BOLD;
    }

    virtual bool get_text_emphasis(int pos, int col) const override
    {
        col = get_model_col(col);
        return get_int(pos, m_aWeightMap.find(col)->second) == PANGO_WEIGHT_BOLD;
    }

    using GtkInstanceWidget::set_sensitive;

    virtual void set_sensitive(int pos, bool bSensitive, int col) override