Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/cui/source/tabpages/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 90 kB image not shown  

Quelle  autocdlg.cxx   Sprache: C

 
/* -*- 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 .
 */


#include <sal/config.h>

#include <i18nutil/unicode.hxx>
#include <o3tl/safeint.hxx>
#include <utility>
#include <vcl/event.hxx>
#include <vcl/keycodes.hxx>
#include <vcl/settings.hxx>
#include <vcl/transfer.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/viewsh.hxx>
#include <unotools/charclass.hxx>
#include <unotools/collatorwrapper.hxx>
#include <comphelper/processfactory.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/module.hxx>
#include <svl/eitem.hxx>
#include <svl/cjkoptions.hxx>
#include <svl/ctloptions.hxx>
#include <svx/SmartTagMgr.hxx>
#include <com/sun/star/smarttags/XSmartTagRecognizer.hpp>
#include <rtl/strbuf.hxx>
#include <o3tl/temporary.hxx>
#include <osl/diagnose.h>
#include <tools/debug.hxx>

#include <autocdlg.hxx>
#include <editeng/acorrcfg.hxx>
#include <editeng/svxacorr.hxx>
#include <svx/cuicharmap.hxx>
#include <strings.hrc>
#include <dialmgr.hxx>
#include <svx/svxids.hrc>

static LanguageType eLastDialogLanguage = LANGUAGE_SYSTEM;

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

OfaAutoCorrDlg::OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet* _pSet )
    : SfxTabDialogController(pParent, u"cui/ui/autocorrectdialog.ui"_ustr, u"AutoCorrectDialog"_ustr, _pSet)
    , m_xLanguageBox(m_xBuilder->weld_widget(u"langbox"_ustr))
    , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"lang"_ustr)))
{
    bool bShowSWOptions = false;
    bool bOpenSmartTagOptions = false;

    if ( _pSet )
    {
        const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_AUTO_CORRECT_DLGfalse);
        if ( pItem && pItem->GetValue() )
            bShowSWOptions = true;

        const SfxBoolItem* pItem2 = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_OPEN_SMARTTAGOPTIONS, false);
        if ( pItem2 && pItem2->GetValue() )
            bOpenSmartTagOptions = true;
    }

    AddTabPage(u"options"_ustr, OfaAutocorrOptionsPage::Create, nullptr);
    AddTabPage(u"applypage"_ustr, OfaSwAutoFmtOptionsPage::Create, nullptr);
    AddTabPage(u"wordcompletion"_ustr, OfaAutoCompleteTabPage::Create, nullptr);
    AddTabPage(u"smarttags"_ustr, OfaSmartTagOptionsTabPage::Create, nullptr);

    if (!bShowSWOptions)
    {
        RemoveTabPage(u"applypage"_ustr);
        RemoveTabPage(u"wordcompletion"_ustr);
        RemoveTabPage(u"smarttags"_ustr);
    }
    else
    {
        // remove smart tag tab page if no extensions are installed
        SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
        SvxSwAutoFormatFlags& rOpt = pAutoCorrect->GetSwFlags();
        if (!rOpt.pSmartTagMgr || 0 == rOpt.pSmartTagMgr->NumberOfRecognizers())
            RemoveTabPage(u"smarttags"_ustr);

        RemoveTabPage(u"options"_ustr);
    }

    AddTabPage(u"replace"_ustr, OfaAutocorrReplacePage::Create, nullptr);
    AddTabPage(u"exceptions"_ustr,  OfaAutocorrExceptPage::Create, nullptr);
    AddTabPage(u"localized"_ustr, OfaQuoteTabPage::Create, nullptr);

    // initialize languages
    //! LANGUAGE_NONE is displayed as '[All]' and the LanguageType
    //! will be set to LANGUAGE_UNDETERMINED
    SvxLanguageListFlags nLangList = SvxLanguageListFlags::WESTERN;

    if( SvtCTLOptions::IsCTLFontEnabled() )
        nLangList |= SvxLanguageListFlags::CTL;
    if( SvtCJKOptions::IsCJKFontEnabled() )
        nLangList |= SvxLanguageListFlags::CJK;
    m_xLanguageLB->SetLanguageList( nLangList, truetrue );
    m_xLanguageLB->set_active_id( LANGUAGE_NONE );
    int nPos = m_xLanguageLB->get_active();
    DBG_ASSERT(nPos != -1, "listbox entry missing" );
    m_xLanguageLB->set_id(nPos, LANGUAGE_UNDETERMINED);

    // Initializing doesn't work for static on linux - therefore here
    if (LANGUAGE_SYSTEM == eLastDialogLanguage)
        eLastDialogLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();

    LanguageType nSelectLang = LANGUAGE_UNDETERMINED;
    nPos = m_xLanguageLB->find_id(eLastDialogLanguage);
    if (nPos != -1)
        nSelectLang = eLastDialogLanguage;
    m_xLanguageLB->set_active_id(nSelectLang);

    m_xLanguageLB->connect_changed(LINK(this, OfaAutoCorrDlg, SelectLanguageHdl));

    if ( bOpenSmartTagOptions )
        SetCurPageId(u"smarttags"_ustr);
}

OfaAutoCorrDlg::~OfaAutoCorrDlg()
{
}

void OfaAutoCorrDlg::EnableLanguage(bool bEnable)
{
    m_xLanguageBox->set_sensitive(bEnable);
}

static bool lcl_FindEntry(weld::TreeView& rLB, const OUString& rEntry,
                          CollatorWrapper const & rCmpClass)
{
    int nCount = rLB.n_children();
    int nSelPos = rLB.get_selected_index();
    for (int i = 0; i < nCount; i++)
    {
        if (0 == rCmpClass.compareString(rEntry, rLB.get_text(i)))
        {
            rLB.select(i);
            return true;
        }
    }
    if (nSelPos != -1)
        rLB.unselect(nSelPos);
    return false;
}

IMPL_LINK_NOARG(OfaAutoCorrDlg, SelectLanguageHdl, weld::ComboBox&, void)
{
    LanguageType eNewLang = m_xLanguageLB->get_active_id();
    // save old settings and fill anew
    if(eNewLang == eLastDialogLanguage)
        return;

    OUString sPageId = GetCurPageId();
    if (sPageId == "replace")
    {
        OfaAutocorrReplacePage* pPage = static_cast<OfaAutocorrReplacePage*>(GetTabPage(sPageId));
        assert(pPage);
        pPage->SetLanguage(eNewLang);
    }
    else if (sPageId == "exceptions")
    {
        OfaAutocorrExceptPage* pPage = static_cast<OfaAutocorrExceptPage*>(GetTabPage(sPageId));
        assert(pPage);
        pPage->SetLanguage(eNewLang);
    }
}

OfaAutocorrOptionsPage::OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
    : SfxTabPage(pPage, pController, u"cui/ui/acoroptionspage.ui"_ustr, u"AutocorrectOptionsPage"_ustr, &rSet)
    , m_sInput(CuiResId(RID_CUISTR_USE_REPLACE))
    , m_sDoubleCaps(CuiResId(RID_CUISTR_CPTL_STT_WORD))
    , m_sStartCap(CuiResId(RID_CUISTR_CPTL_STT_SENT))
    , m_sBoldUnderline(CuiResId(RID_CUISTR_BOLD_UNDER))
    , m_sURL(CuiResId(RID_CUISTR_DETECT_URL))
    , m_sDOI(CuiResId(RID_CUISTR_DETECT_DOI))
    , m_sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
    , m_sDash(CuiResId(RID_CUISTR_DASH))
    , m_sAccidentalCaps(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
    , m_xCheckLB(m_xBuilder->weld_tree_view(u"checklist"_ustr))
{
    m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
    m_xCheckLB->set_size_request(-1, m_xCheckLB->get_height_rows(10));
}

OfaAutocorrOptionsPage::~OfaAutocorrOptionsPage()
{
}

std::unique_ptr<SfxTabPage> OfaAutocorrOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
                                                           const SfxItemSet* rSet)
{
    return std::make_unique<OfaAutocorrOptionsPage>(pPage, pController, *rSet);
}

#define CBCOL_FIRST     0
#define CBCOL_SECOND    1
#define CBCOL_BOTH      2

bool OfaAutocorrOptionsPage::FillItemSet( SfxItemSet* )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    ACFlags nFlags = pAutoCorrect->GetFlags();

    int nPos = 0;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,          m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,     m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,      m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,          m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::SetDOIAttr,           m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,        m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,    m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
    pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,      m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);

    bool bReturn = nFlags != pAutoCorrect->GetFlags();
    if(bReturn )
    {
        SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
        rCfg.SetModified();
        rCfg.Commit();
    }
    return bReturn;
}

void    OfaAutocorrOptionsPage::ActivatePage( const SfxItemSet& )
{
    static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
}

void OfaAutocorrOptionsPage::InsertEntry(const OUString& rTxt)
{
    m_xCheckLB->append();
    const int nRow = m_xCheckLB->n_children() - 1;
    m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE);
    m_xCheckLB->set_text(nRow, rTxt, 0);
}

void OfaAutocorrOptionsPage::Reset( const SfxItemSet* )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    const ACFlags nFlags = pAutoCorrect->GetFlags();

    m_xCheckLB->freeze();
    m_xCheckLB->clear();

    InsertEntry(m_sInput);
    InsertEntry(m_sDoubleCaps);
    InsertEntry(m_sStartCap);
    InsertEntry(m_sBoldUnderline);
    InsertEntry(m_sURL);
    InsertEntry(m_sDOI);
    InsertEntry(m_sDash);
    InsertEntry(m_sNoDblSpaces);
    InsertEntry(m_sAccidentalCaps);

    int nPos = 0;
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetDOIAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE );
    m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE );

    m_xCheckLB->thaw();
}

/*********************************************************************/
/*                                                                   */
/*  helping struct for dUserData of the Checklistbox                 */
/*                                                                   */
/*********************************************************************/

namespace {

struct ImpUserData
{
    OUString  *pString;
    vcl::Font *pFont;

    ImpUserData(OUString* pText, vcl::Font* pFnt)
        { pString = pText; pFont = pFnt;}
};


/*********************************************************************/
/*                                                                   */
/*  dialog for per cent settings                                     */
/*                                                                   */
/*********************************************************************/

class OfaAutoFmtPrcntSet : public weld::GenericDialogController
{
    std::unique_ptr<weld::MetricSpinButton> m_xPrcntMF;
public:
    explicit OfaAutoFmtPrcntSet(weld::Window* pParent)
        : GenericDialogController(pParent, u"cui/ui/percentdialog.ui"_ustr, u"PercentDialog"_ustr)
        , m_xPrcntMF(m_xBuilder->weld_metric_spin_button(u"margin"_ustr, FieldUnit::PERCENT))
    {
    }

    weld::MetricSpinButton& GetPrcntFld()
    {
        return *m_xPrcntMF;
    }
};

/*********************************************************************/
/*                                                                   */
/*  use TabPage autoformat                                           */
/*                                                                   */
/*********************************************************************/

enum OfaAutoFmtOptions
{
    USE_REPLACE_TABLE,
    CORR_UPPER,
    BEGIN_UPPER,
    BOLD_UNDERLINE,
    DETECT_URL,
    DETECT_DOI,
    REPLACE_DASHES,
    DEL_SPACES_AT_STT_END,
    DEL_SPACES_BETWEEN_LINES,
    IGNORE_DBLSPACE,
    CORRECT_CAPS_LOCK,
    APPLY_NUMBERING,
    APPLY_NUMBERING_AFTER_SPACE,
    INSERT_BORDER,
    CREATE_TABLE,
    REPLACE_STYLES,
    DEL_EMPTY_NODE,
    REPLACE_USER_COLL,
    REPLACE_BULLETS,
    MERGE_SINGLE_LINE_PARA
};

}

OfaSwAutoFmtOptionsPage::OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController,
                                                 const SfxItemSet& rSet )
    : SfxTabPage(pPage, pController, u"cui/ui/applyautofmtpage.ui"_ustr, u"ApplyAutoFmtPage"_ustr, &rSet)
    , sDeleteEmptyPara(CuiResId(RID_CUISTR_DEL_EMPTY_PARA))
    , sUseReplaceTbl(CuiResId(RID_CUISTR_USE_REPLACE))
    , sCapitalStartWord(CuiResId(RID_CUISTR_CPTL_STT_WORD))
    , sCapitalStartSentence(CuiResId(RID_CUISTR_CPTL_STT_SENT))
    , sUserStyle(CuiResId(RID_CUISTR_USER_STYLE))
    , sBullet(CuiResId(RID_CUISTR_BULLET))
    , sBoldUnder(CuiResId(RID_CUISTR_BOLD_UNDER))
    , sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
    , sCorrectCapsLock(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
    , sDetectURL(CuiResId(RID_CUISTR_DETECT_URL))
    , sDetectDOI(CuiResId(RID_CUISTR_DETECT_DOI))
    , sDash(CuiResId(RID_CUISTR_DASH))
    , sRightMargin(CuiResId(RID_CUISTR_RIGHT_MARGIN))
    , sNum(CuiResId(RID_CUISTR_NUM))
    , sBulletsAfterSpace(CuiResId(RID_SVXSTR_NUM_FORMAT_AFTER_SPACE))
    , sBorder(CuiResId(RID_CUISTR_BORDER))
    , sTable(CuiResId(RID_CUISTR_CREATE_TABLE))
    , sReplaceTemplates(CuiResId(RID_CUISTR_REPLACE_TEMPLATES))
    , sDelSpaceAtSttEnd(CuiResId(RID_CUISTR_DEL_SPACES_AT_STT_END))
    , sDelSpaceBetweenLines(CuiResId(RID_CUISTR_DEL_SPACES_BETWEEN_LINES))
    , nPercent(50)
    , m_xCheckLB(m_xBuilder->weld_tree_view(u"list"_ustr))
    , m_xEditPB(m_xBuilder->weld_button(u"edit"_ustr))
{
    m_xCheckLB->connect_selection_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl));
    m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl));

    std::vector<int> aWidths
    {
        o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2),
        o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(1)).Width() * 2)
    };
    m_xCheckLB->set_column_fixed_widths(aWidths);

    m_xEditPB->connect_clicked(LINK(this, OfaSwAutoFmtOptionsPage, EditHdl));
}

void OfaSwAutoFmtOptionsPage::CreateEntry(const OUString& rTxt, sal_uInt16 nCol)
{
    m_xCheckLB->append();
    const int nRow = m_xCheckLB->n_children() - 1;
    if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
        m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
    if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
        m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_text(nRow, rTxt, 2);
}

OfaSwAutoFmtOptionsPage::~OfaSwAutoFmtOptionsPage()
{
    delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(REPLACE_BULLETS));
    delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(APPLY_NUMBERING));
    delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA));
}

std::unique_ptr<SfxTabPage> OfaSwAutoFmtOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
                                                            const SfxItemSet* rAttrSet)
{
    return std::make_unique<OfaSwAutoFmtOptionsPage>(pPage, pController, *rAttrSet);
}

bool OfaSwAutoFmtOptionsPage::FillItemSet( SfxItemSet*  )
{
    bool bModified = false;
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
    ACFlags nFlags = pAutoCorrect->GetFlags();

    bool bCheck = m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bAutoCorrect != bCheck;
    pOpt->bAutoCorrect = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,
                        m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bCapitalStartWord != bCheck;
    pOpt->bCapitalStartWord = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,
                        m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bCapitalStartSentence != bCheck;
    pOpt->bCapitalStartSentence = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence,
                        m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bChgWeightUnderl != bCheck;
    pOpt->bChgWeightUnderl = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,
                        m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_SECOND) == TRISTATE_TRUE);

    pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,
                        m_xCheckLB->get_toggle(IGNORE_DBLSPACE, CBCOL_SECOND) == TRISTATE_TRUE);

    pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,
                        m_xCheckLB->get_toggle(CORRECT_CAPS_LOCK, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(DETECT_URL, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bSetINetAttr != bCheck;
    pOpt->bSetINetAttr = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,
                        m_xCheckLB->get_toggle(DETECT_URL, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(DETECT_DOI, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bSetDOIAttr != bCheck;
    pOpt->bSetDOIAttr = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::SetDOIAttr,
                        m_xCheckLB->get_toggle(DETECT_DOI, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(DEL_EMPTY_NODE, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bDelEmptyNode != bCheck;
    pOpt->bDelEmptyNode = bCheck;

    bCheck = m_xCheckLB->get_toggle(REPLACE_USER_COLL, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bChgUserColl != bCheck;
    pOpt->bChgUserColl = bCheck;

    bCheck = m_xCheckLB->get_toggle(REPLACE_BULLETS, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bChgEnumNum != bCheck;
    pOpt->bChgEnumNum = bCheck;
    bModified |= aBulletFont != pOpt->aBulletFont;
    pOpt->aBulletFont = aBulletFont;
    bModified |= sBulletChar != OUString(&pOpt->cBullet, 1);
    pOpt->cBullet = sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));

    bModified |= aByInputBulletFont != pOpt->aByInputBulletFont;
    bModified |= sByInputBulletChar != OUString(&pOpt->cByInputBullet, 1);
    pOpt->aByInputBulletFont = aByInputBulletFont;
    pOpt->cByInputBullet = sByInputBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));

    bCheck = m_xCheckLB->get_toggle(MERGE_SINGLE_LINE_PARA, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bRightMargin != bCheck;
    pOpt->bRightMargin = bCheck;
    bModified |= nPercent != pOpt->nRightMargin;
    pOpt->nRightMargin = static_cast<sal_uInt8>(nPercent);

    bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bSetNumRule != bCheck;
    pOpt->bSetNumRule = bCheck;

    bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING_AFTER_SPACE, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bSetNumRuleAfterSpace != bCheck;
    pOpt->bSetNumRuleAfterSpace = bCheck;

    bCheck = m_xCheckLB->get_toggle(INSERT_BORDER, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bSetBorder != bCheck;
    pOpt->bSetBorder = bCheck;

    bCheck = m_xCheckLB->get_toggle(CREATE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bCreateTable != bCheck;
    pOpt->bCreateTable = bCheck;

    bCheck = m_xCheckLB->get_toggle(REPLACE_STYLES, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bReplaceStyles != bCheck;
    pOpt->bReplaceStyles = bCheck;

    bCheck = m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bChgToEnEmDash != bCheck;
    pOpt->bChgToEnEmDash = bCheck;
    pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,
                        m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_SECOND) == TRISTATE_TRUE);

    bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bAFormatDelSpacesAtSttEnd != bCheck;
    pOpt->bAFormatDelSpacesAtSttEnd = bCheck;
    bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bAFormatByInpDelSpacesAtSttEnd != bCheck;
    pOpt->bAFormatByInpDelSpacesAtSttEnd = bCheck;

    bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_FIRST) == TRISTATE_TRUE;
    bModified |= pOpt->bAFormatDelSpacesBetweenLines != bCheck;
    pOpt->bAFormatDelSpacesBetweenLines = bCheck;
    bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_SECOND) == TRISTATE_TRUE;
    bModified |= pOpt->bAFormatByInpDelSpacesBetweenLines != bCheck;
    pOpt->bAFormatByInpDelSpacesBetweenLines = bCheck;

    if(bModified || nFlags != pAutoCorrect->GetFlags())
    {
        SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
        rCfg.SetModified();
        rCfg.Commit();
    }

    return true;
}

void    OfaSwAutoFmtOptionsPage::ActivatePage( const SfxItemSet& )
{
    static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
}

void OfaSwAutoFmtOptionsPage::Reset( const SfxItemSet* )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
    const ACFlags nFlags = pAutoCorrect->GetFlags();

    aBulletFont = pOpt->aBulletFont;
    sBulletChar = OUString(&pOpt->cBullet, 1);

    aByInputBulletFont = pOpt->aByInputBulletFont;
    sByInputBulletChar = OUString(&pOpt->cByInputBullet, 1);

    nPercent = pOpt->nRightMargin;
    sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());

    m_xCheckLB->freeze();
    m_xCheckLB->clear();

    // The following entries have to be inserted in the same order
    // as in the OfaAutoFmtOptions-enum!
    CreateEntry(sUseReplaceTbl,     CBCOL_BOTH  );
    CreateEntry(sCapitalStartWord,  CBCOL_BOTH  );
    CreateEntry(sCapitalStartSentence, CBCOL_BOTH  );
    CreateEntry(sBoldUnder,         CBCOL_BOTH  );
    CreateEntry(sDetectURL,         CBCOL_BOTH  );
    CreateEntry(sDetectDOI,         CBCOL_BOTH  );
    CreateEntry(sDash,              CBCOL_BOTH  );
    CreateEntry(sDelSpaceAtSttEnd,  CBCOL_BOTH  );
    CreateEntry(sDelSpaceBetweenLines, CBCOL_BOTH  );

    CreateEntry(sNoDblSpaces,       CBCOL_SECOND);
    CreateEntry(sCorrectCapsLock,   CBCOL_SECOND);
    CreateEntry(sNum.replaceFirst("%1", sBulletChar), CBCOL_SECOND);
    CreateEntry(sBulletsAfterSpace,  CBCOL_SECOND);
    CreateEntry(sBorder,            CBCOL_SECOND);
    CreateEntry(sTable,             CBCOL_SECOND);
    CreateEntry(sReplaceTemplates,  CBCOL_SECOND);
    CreateEntry(sDeleteEmptyPara,   CBCOL_FIRST );
    CreateEntry(sUserStyle,         CBCOL_FIRST );
    CreateEntry(sBullet.replaceFirst("%1", sByInputBulletChar), CBCOL_FIRST);
    CreateEntry(sRightMargin.replaceFirst("%1", sMargin), CBCOL_FIRST);

    m_xCheckLB->set_toggle(USE_REPLACE_TABLE, pOpt->bAutoCorrect ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(USE_REPLACE_TABLE, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(CORR_UPPER, pOpt->bCapitalStartWord ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(CORR_UPPER, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(BEGIN_UPPER, pOpt->bCapitalStartSentence ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(BEGIN_UPPER, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(BOLD_UNDERLINE, pOpt->bChgWeightUnderl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(BOLD_UNDERLINE, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(DETECT_URL, pOpt->bSetINetAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(DETECT_URL, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(DETECT_DOI, pOpt->bSetDOIAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(DETECT_DOI, bool(nFlags & ACFlags::SetDOIAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(REPLACE_DASHES, pOpt->bChgToEnEmDash ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(REPLACE_DASHES, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatByInpDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatByInpDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(IGNORE_DBLSPACE, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(CORRECT_CAPS_LOCK, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(APPLY_NUMBERING, pOpt->bSetNumRule ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(APPLY_NUMBERING_AFTER_SPACE, pOpt->bSetNumRuleAfterSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(INSERT_BORDER, pOpt->bSetBorder ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(CREATE_TABLE, pOpt->bCreateTable ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(REPLACE_STYLES, pOpt->bReplaceStyles ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
    m_xCheckLB->set_toggle(DEL_EMPTY_NODE, pOpt->bDelEmptyNode ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(REPLACE_USER_COLL, pOpt->bChgUserColl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(REPLACE_BULLETS, pOpt->bChgEnumNum ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
    m_xCheckLB->set_toggle(MERGE_SINGLE_LINE_PARA, pOpt->bRightMargin ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);

    ImpUserData* pUserData = new ImpUserData(&sBulletChar, &aBulletFont);
    OUString sId(weld::toId(pUserData));
    m_xCheckLB->set_id(REPLACE_BULLETS, sId);

    pUserData = new ImpUserData(&sMargin, nullptr);
    sId = weld::toId(pUserData);
    m_xCheckLB->set_id(MERGE_SINGLE_LINE_PARA, sId);

    ImpUserData* pUserData2 = new ImpUserData(&sByInputBulletChar, &aByInputBulletFont);
    sId = weld::toId(pUserData2);
    m_xCheckLB->set_id(APPLY_NUMBERING, sId);

    m_xCheckLB->thaw();
}

IMPL_LINK(OfaSwAutoFmtOptionsPage, SelectHdl, weld::TreeView&, rBox, void)
{
    m_xEditPB->set_sensitive(rBox.get_selected_id().toInt64() != 0);
}

IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, DoubleClickEditHdl, weld::TreeView&, bool)
{
    EditHdl(*m_xEditPB);
    return true;
}

IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, EditHdl, weld::Button&, void)
{
    int nSelEntryPos = m_xCheckLB->get_selected_index();
    if (nSelEntryPos == REPLACE_BULLETS || nSelEntryPos == APPLY_NUMBERING)
    {
        SvxCharacterMap aMapDlg(GetFrameWeld(), nullptr, nullptr);
        ImpUserData* pUserData = weld::fromId<ImpUserData*>(m_xCheckLB->get_id(nSelEntryPos));
        aMapDlg.SetCharFont(*pUserData->pFont);
        aMapDlg.SetChar( (*pUserData->pString)[0] );
        if (RET_OK == aMapDlg.run())
        {
            const vcl::Font& aFont(aMapDlg.GetCharFont());
            *pUserData->pFont = aFont;
            sal_UCS4 aChar = aMapDlg.GetChar();
            // using the UCS4 constructor
            OUString aOUStr( &aChar, 1 );
            *pUserData->pString = aOUStr;
            if (nSelEntryPos == REPLACE_BULLETS)
                m_xCheckLB->set_text(nSelEntryPos, sNum.replaceFirst("%1", aOUStr), 2);
            else
                m_xCheckLB->set_text(nSelEntryPos, sBullet.replaceFirst("%1", aOUStr), 2);
        }
    }
    else if( MERGE_SINGLE_LINE_PARA == nSelEntryPos )
    {
        // dialog for per cent settings
        OfaAutoFmtPrcntSet aDlg(GetFrameWeld());
        aDlg.GetPrcntFld().set_value(nPercent, FieldUnit::PERCENT);
        if (aDlg.run() == RET_OK)
        {
            nPercent = static_cast<sal_uInt16>(aDlg.GetPrcntFld().get_value(FieldUnit::PERCENT));
            sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
            m_xCheckLB->set_text(nSelEntryPos, sRightMargin.replaceFirst("%1", sMargin), 2);
        }
    }
}


OfaAutocorrReplacePage::OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController,
                                               const SfxItemSet& rSet)
    : SfxTabPage(pPage, pController, u"cui/ui/acorreplacepage.ui"_ustr, u"AcorReplacePage"_ustr, &rSet)
    , maCompareClass(comphelper::getProcessComponentContext())
    , eLang(eLastDialogLanguage)
    , bHasSelectionText(false)
    , bFirstSelect(true)
    , bReplaceEditChanged(false)
    , bSWriter(true)
    , m_xTextOnlyCB(m_xBuilder->weld_check_button(u"textonly"_ustr))
    , m_xShortED(m_xBuilder->weld_entry(u"origtext"_ustr))
    , m_xReplaceED(m_xBuilder->weld_entry(u"newtext"_ustr))
    , m_xReplaceTLB(m_xBuilder->weld_tree_view(u"tabview"_ustr))
    , m_xNewReplacePB(m_xBuilder->weld_button(u"new"_ustr))
    , m_xReplacePB(m_xBuilder->weld_button(u"replace"_ustr))
    , m_xDeleteReplacePB(m_xBuilder->weld_button(u"delete"_ustr))
    , m_xButtonBox(m_xBuilder->weld_container(u"buttonbox"_ustr))
{
    sNew = m_xNewReplacePB->get_label();
    sModify = m_xReplacePB->get_label();

    // lock down the width of the button box to its max
    // desired width
    auto nMaxWidth = m_xButtonBox->get_preferred_size().Width();
    m_xButtonBox->set_size_request(nMaxWidth, -1);
    m_xReplacePB->hide();

    // tdf#125348 set some small but fixed initial width size, final width will
    // depend on the size of the entry boxes
    m_xReplaceTLB->set_size_request(42, m_xReplaceTLB->get_height_rows(10));

    SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
    bSWriter = pMod == SfxModule::GetActiveModule();

    LanguageTag aLanguageTag( eLastDialogLanguage );
    maCompareClass.loadDefaultCollator( aLanguageTag.getLocale(), 0 );
    pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );

    auto nColWidth = m_xReplaceTLB->get_approximate_digit_width() * 32;
    m_aReplaceFixedWidths.push_back(nColWidth);
    m_aReplaceFixedWidths.push_back(nColWidth);

    m_xReplaceTLB->connect_selection_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()
{
    aDoubleStringTable.clear();
    aChangesTable.clear();

    pCharClass.reset();
}

std::unique_ptr<SfxTabPage> OfaAutocorrReplacePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
{
    return std::make_unique<OfaAutocorrReplacePage>(pPage, pController, *rSet);
}

void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
{
    if(eLang != eLastDialogLanguage)
        SetLanguage(eLastDialogLanguage);
    static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
}

DeactivateRC OfaAutocorrReplacePage::DeactivatePage( SfxItemSet*  )
{
    return DeactivateRC::LeavePage;
}

bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet* )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();

    for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); ++it)
    {
        LanguageType eCurrentLang = it->first;
        StringChangeList& rStringChangeList = it->second;
        std::vector<SvxAutocorrWord> aDeleteWords;
        std::vector<SvxAutocorrWord> aNewWords;

        aDeleteWords.reserve( rStringChangeList.aDeletedEntries.size() );
        for (const DoubleString & deleteEntry : rStringChangeList.aDeletedEntries)
        {
            SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
            aDeleteWords.push_back( aDeleteWord );
        }

        aNewWords.reserve( rStringChangeList.aNewEntries.size() );
        for (const DoubleString & newEntry : rStringChangeList.aNewEntries)
        {
            //fdo#67697 if the user data is set then we want to retain the
            //source formatting of the entry, so don't use the optimized
            //text-only MakeCombinedChanges for this entry
            bool bKeepSourceFormatting = newEntry.pUserData == &bHasSelectionText;
            if (bKeepSourceFormatting)
            {
                if (SfxObjectShell* pSh = SfxObjectShell::Current())
                    pAutoCorrect->PutText(newEntry.sShort, *pSh, eCurrentLang);
                continue;
            }

            SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
            aNewWords.push_back( aNewWord );
        }
        pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
    }
    aChangesTable.clear();
    return false;
}

void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
                                        LanguageType eOldLanguage,
                                        LanguageType eNewLanguage)
{
    eLang = eNewLanguage;
    if(bFromReset)
    {
        aDoubleStringTable.clear();
        aChangesTable.clear();
    }
    else
    {
        DoubleStringArray* pArray;
        if(aDoubleStringTable.find(eOldLanguage) != aDoubleStringTable.end())
        {
            pArray = &aDoubleStringTable[eOldLanguage];
            pArray->clear();
        }
        else
        {
            pArray = &aDoubleStringTable[eOldLanguage]; // create new array
        }

        m_xReplaceTLB->all_foreach([this, &pArray](weld::TreeIter& rIter) {
            pArray->push_back(DoubleString(m_xReplaceTLB->get_text(rIter, 0),
                                           m_xReplaceTLB->get_text(rIter, 1)));
            DoubleString& rDouble = pArray->back();
            rDouble.pUserData = weld::fromId<void*>(m_xReplaceTLB->get_id(rIter));
            return false;
        });
    }

    if( !bSWriter )
        aFormatText.clear();

    if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
    {
        DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];

        m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
            DoubleString &rDouble = rArray[nIndex];
            bool bTextOnly = nullptr == rDouble.pUserData;
            // formatted text is only in Writer
            if (bSWriter || bTextOnly)
            {
                if (!bTextOnly)
                {
                    // that means: with format info or even with selection text
                    OUString sId = weld::toId(rDouble.pUserData);
                    m_xReplaceTLB->set_id(rIter, sId);
                }
                m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
                m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
            }
            else
            {
                aFormatText.insert(rDouble.sShort);
            }
        }, nullptr, &m_aReplaceFixedWidths);
    }
    else
    {
        SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
        SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
        const SvxAutocorrWordList::AutocorrWordSetType & rContent = pWordList->getSortedContent();
        m_xReplaceTLB->bulk_insert_for_each(rContent.size(), [this, rContent](weld::TreeIter& rIter, int nIndex) {
            auto const& elem = rContent[nIndex];
            bool bTextOnly = elem.IsTextOnly();
            // formatted text is only in Writer
            if (bSWriter || bTextOnly)
            {
                if (!bTextOnly)
                {
                    // that means: with format info or even with selection text
                    OUString sId = weld::toId(m_xTextOnlyCB.get());
                    m_xReplaceTLB->set_id(rIter, sId);
                }
                m_xReplaceTLB->set_text(rIter, elem.GetShort(), 0);
                m_xReplaceTLB->set_text(rIter, elem.GetLong(), 1);
            }
            else
            {
                aFormatText.insert(elem.GetShort());
            }
        }, nullptr, &m_aReplaceFixedWidths);
        m_xNewReplacePB->set_sensitive(false);
        m_xDeleteReplacePB->set_sensitive(false);
    }

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

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

void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
{
    //save old settings and refill
    if(eSet != eLang)
    {
        RefillReplaceBox(false, eLang, eSet);
        eLastDialogLanguage = eSet;

        LanguageTag aLanguageTag( eLastDialogLanguage );
        maCompareClass = CollatorWrapper( comphelper::getProcessComponentContext() );
        maCompareClass.loadDefaultCollator( aLanguageTag.getLocale(), 0 );
        pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
        ModifyHdl(*m_xShortED);
    }
}

IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
{
    if(!bFirstSelect || !bHasSelectionText)
    {
        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 == maCompareClass.compareString(sTmpShort, m_xShortED->get_text());
        int nStartPos, nEndPos;
        m_xShortED->get_selection_bounds(nStartPos, nEndPos);
        if (m_xShortED->get_text() != sTmpShort)
        {
            m_xShortED->set_text(sTmpShort);
            // if it was only a different notation, the selection has to be set again
            if (bSameContent)
            {
                m_xShortED->select_region(nStartPos, nEndPos);
            }
        }
        m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
        // with UserData there is a Formatinfo
        m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
    }
    else
    {
        bFirstSelect = false;
    }

    m_xNewReplacePB->set_sensitive(false);
    m_xDeleteReplacePB->set_sensitive(true);
};

void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
{
    DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
    for (size_t i = 0; i < rNewArray.size(); i++)
    {
        if (rNewArray[i].sShort == sShort)
        {
            rNewArray.erase(rNewArray.begin() + i);
            break;
        }
    }

    DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
    for (size_t i = 0; i < rDeletedArray.size(); i++)
    {
        if (rDeletedArray[i].sShort == sShort)
        {
            rDeletedArray.erase(rDeletedArray.begin() + i);
            break;
        }
    }

    DoubleString aNewString(sShort, sLong);
    rNewArray.push_back(aNewString);
    if (bKeepSourceFormatting)
        rNewArray.back().pUserData = &bHasSelectionText;
}

void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString&&nbsp;sLong)
{
    DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
    for (size_t i = 0; i < rNewArray.size(); i++)
    {
        if (rNewArray[i].sShort == sShort)
        {
            rNewArray.erase(rNewArray.begin() + i);
            break;
        }
    }

    DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
    for (size_t i = 0; i < rDeletedArray.size(); i++)
    {
        if (rDeletedArray[i].sShort == sShort)
        {
            rDeletedArray.erase(rDeletedArray.begin() + i);
            break;
        }
    }

    DoubleString aDeletedString(sShort, sLong);
    rDeletedArray.push_back(aDeletedString);
}

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

IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
{
    return NewDelHdl(&rEdit);
}

IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
{
    m_aReplaceFixedWidths.clear();
    int x, y, width, height;
    if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
    {
        m_aReplaceFixedWidths.push_back(x);
        m_aReplaceFixedWidths.push_back(width - 1);
        m_xReplaceTLB->set_column_fixed_widths(m_aReplaceFixedWidths);
    }
}

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(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
            m_xReplaceTLB->remove(nEntry);
            ModifyHdl(*m_xShortED);
            return true;
        }
    }

    if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
    {
        OUString sEntry(m_xShortED->get_text());
        if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
                ( bHasSelectionText && bSWriter ) ))
        {
            bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();

            NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
            m_xReplaceTLB->freeze();
            int nPos = -1;
            if (nEntry != -1)
            {
                nPos = nEntry;
                m_xReplaceTLB->remove(nEntry);
            }
            else
            {
                int j;
                int nCount = m_xReplaceTLB->n_children();
                for (j = 0; j < nCount; ++j)
                {
                    if (0 >= maCompareClass.compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
                        break;
                }
                nPos = j;
            }

            OUString sId;
            if (bKeepSourceFormatting)
            {
                sId = weld::toId(&bHasSelectionText); // new formatted text
            }

            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_xReplaceED->has_focus())
            {
                m_xShortED->grab_focus();
            }
        }
    }
    else
    {
        // this can only be an enter in one of the two edit fields
        // which means EndDialog() - has to be evaluated in KeyInput
        return false;
    }
    ModifyHdl(*m_xShortED);
    return true;
}

IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
{
    std::unique_ptr<weld::TreeIter> xFirstSel(m_xReplaceTLB->make_iterator());
    bool bFirstSelIterSet = m_xReplaceTLB->get_selected(xFirstSel.get());
    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)
    {
        if(!rEntry.isEmpty())
        {
            bool bFound = false;
            bool bTmpSelEntry=false;

            m_xReplaceTLB->all_foreach([this, &rEntry, &rRepString, &bFound,
                                        &bTmpSelEntry, &bFirstSelIterSet,
                                        &xFirstSel, &aWordStr](weld::TreeIter& rIter){
                OUString aTestStr = m_xReplaceTLB->get_text(rIter, 0);
                if( maCompareClass.compareString(rEntry, aTestStr ) == 0 )
                {
                    if (!rRepString.isEmpty())
                        bFirstSelect = true;
                    m_xReplaceTLB->set_cursor(rIter);
                    m_xReplaceTLB->copy_iterator(rIter, *xFirstSel);
                    bFirstSelIterSet = true;
                    m_xNewReplacePB->set_label(sModify);
                    bFound = true;
                    return true;
                }
                else
                {
                    aTestStr = pCharClass->lowercase( aTestStr );
                    if( !bTmpSelEntry && ( aTestStr.startsWith(aWordStr)
                        // find also with ".*" and between :colons:
                        || aTestStr.replaceAll(".*","").replaceAll(":""").startsWith(aWordStr) ) )
                    {
                        m_xReplaceTLB->scroll_to_row(rIter);
                        bTmpSelEntry = true;
                    }
                }
                return false;
            });
            if( !bFound )
            {
                m_xReplaceTLB->select(-1);
                bFirstSelIterSet = false;
                m_xNewReplacePB->set_label(sNew);
                if( bReplaceEditChanged )
                    m_xTextOnlyCB->set_sensitive(false);
            }
            m_xDeleteReplacePB->set_sensitive(bFound);
        }
        else if (m_xReplaceTLB->n_children() > 0)
        {
            m_xReplaceTLB->scroll_to_row(0);
        }

    }
    else if( !bShort )
    {
        bReplaceEditChanged = true;
        if (bFirstSelIterSet)
        {
            m_xNewReplacePB->set_label(sModify);
        }
    }

    const OUString aShortTxt = m_xShortED->get_text();
    bool bEnableNew = !aShortTxt.isEmpty() &&
                        ( !rRepString.isEmpty() ||
                                ( bHasSelectionText && bSWriter )) &&
                        ( !bFirstSelIterSet || rRepString !=
                                m_xReplaceTLB->get_text(*xFirstSel, 1) );
    if( bEnableNew )
    {
        for (auto const& elem : aFormatText)
        {
            if(elem == aShortTxt)
            {
                bEnableNew = false;
                break;
            }
        }
    }
    m_xNewReplacePB->set_sensitive(bEnableNew);
}

static bool lcl_FindInArray(std::vector<OUString>& rStrings, std::u16string_view rString)
{
    for (auto const& elem : rStrings)
    {
        if(elem == rString)
        {
            return true;
        }
    }
    return false;
}

OfaAutocorrExceptPage::OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
    : SfxTabPage(pPage, pController, u"cui/ui/acorexceptpage.ui"_ustr, u"AcorExceptPage"_ustr, &rSet)
    , maCompareClass(comphelper::getProcessComponentContext())
    , eLang(eLastDialogLanguage)
    , m_xAbbrevED(m_xBuilder->weld_entry(u"abbrev"_ustr))
    , m_xAbbrevLB(m_xBuilder->weld_tree_view(u"abbrevlist"_ustr))
    , m_xNewAbbrevPB(m_xBuilder->weld_button(u"newabbrev"_ustr))
    , m_xDelAbbrevPB(m_xBuilder->weld_button(u"delabbrev"_ustr))
    , m_xAutoAbbrevCB(m_xBuilder->weld_check_button(u"autoabbrev"_ustr))
    , m_xDoubleCapsED(m_xBuilder->weld_entry(u"double"_ustr))
    , m_xDoubleCapsLB(m_xBuilder->weld_tree_view(u"doublelist"_ustr))
    , m_xNewDoublePB(m_xBuilder->weld_button(u"newdouble"_ustr))
    , m_xDelDoublePB(m_xBuilder->weld_button(u"deldouble"_ustr))
    , m_xAutoCapsCB(m_xBuilder->weld_check_button(u"autodouble"_ustr))
{
    m_xAbbrevLB->make_sorted();
    m_xAbbrevLB->set_size_request(-1, m_xAbbrevLB->get_height_rows(6));

    m_xDoubleCapsLB->make_sorted();
    m_xDoubleCapsLB->set_size_request(-1, m_xDoubleCapsLB->get_height_rows(6));

    css::lang::Locale aLcl( LanguageTag::convertToLocale(eLastDialogLanguage ));
    maCompareClass.loadDefaultCollator( aLcl, 0 );

    m_xNewAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
    m_xDelAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
    m_xNewDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
    m_xDelDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));

    m_xAbbrevLB->connect_selection_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
    m_xDoubleCapsLB->connect_selection_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
    m_xAbbrevED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
    m_xDoubleCapsED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));

    m_xAbbrevED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
    m_xDoubleCapsED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
}

OfaAutocorrExceptPage::~OfaAutocorrExceptPage()
{
    aStringsTable.clear();
}

std::unique_ptr<SfxTabPage> OfaAutocorrExceptPage::Create(weld::Container* pPage, weld::DialogController* pController,
                                                 const SfxItemSet* rSet)
{
    return std::make_unique<OfaAutocorrExceptPage>(pPage, pController, *rSet);
}

void    OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& )
{
    if(eLang != eLastDialogLanguage)
        SetLanguage(eLastDialogLanguage);
    static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
}

DeactivateRC OfaAutocorrExceptPage::DeactivatePage( SfxItemSet* )
{
    return DeactivateRC::LeavePage;
}

bool OfaAutocorrExceptPage::FillItemSet( SfxItemSet*  )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    for(StringsTable::reverse_iterator it1 = aStringsTable.rbegin(); it1 != aStringsTable.rend(); ++it1)
    {
        LanguageType eCurLang = it1->first;
        StringsArrays& rArrays = it1->second;
        if(eCurLang != eLang) // current language is treated later
        {
            SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eCurLang);

            if(pWrdList)
            {
                size_t nCount = pWrdList->size();
                size_t i;
                for( i = nCount; i; )
                {
                    OUString aString = (*pWrdList)[ --i ];

                    if( !lcl_FindInArray(rArrays.aDoubleCapsStrings, aString))
                    {
                      pWrdList->erase_at(i);
                    }
                }

                for (auto const& elem : rArrays.aDoubleCapsStrings)
                {
                    pWrdList->insert(elem);
                }
                pAutoCorrect->SaveWordStartExceptList(eCurLang);
            }

            SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eCurLang);

            if(pCplList)
            {
                size_t nCount = pCplList->size();
                size_t i;
                for( i = nCount; i; )
                {
                    OUString aString = (*pCplList)[ --i ];
                    if( !lcl_FindInArray(rArrays.aAbbrevStrings, aString))
                    {
                        pCplList->erase_at(i);
                    }
                }

                for (auto const& elem : rArrays.aAbbrevStrings)
                {
                    pCplList->insert(elem);
                }

                pAutoCorrect->SaveCplSttExceptList(eCurLang);
            }
        }
    }
    aStringsTable.clear();

    SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eLang);

    if(pWrdList)
    {
        size_t nCount = pWrdList->size();
        size_t i;
        for( i = nCount; i; )
        {
            OUString aString = (*pWrdList)[ --i ];
            if (m_xDoubleCapsLB->find_text(aString) == -1)
            {
                pWrdList->erase_at(i);
            }
        }
        nCount = m_xDoubleCapsLB->n_children();
        for( i = 0; i < nCount; ++i )
        {
            pWrdList->insert(m_xDoubleCapsLB->get_text(i));
        }
        pAutoCorrect->SaveWordStartExceptList(eLang);
    }

    SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eLang);

    if(pCplList)
    {
        size_t nCount = pCplList->size();
        for( size_t i = nCount; i; )
        {
            OUString aString = (*pCplList)[ --i ];
            if (m_xAbbrevLB->find_text(aString) == -1)
            {
                pCplList->erase_at(i);
            }
        }
        sal_Int32 nAbbrevCount = m_xAbbrevLB->n_children();
        for( sal_Int32 ia = 0; ia < nAbbrevCount; ++ia )
        {
            pCplList->insert(m_xAbbrevLB->get_text(ia));
        }
        pAutoCorrect->SaveCplSttExceptList(eLang);
    }
    if (m_xAutoAbbrevCB->get_state_changed_from_saved())
        pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordCplSttLst, m_xAutoAbbrevCB->get_active());
    if (m_xAutoCapsCB->get_state_changed_from_saved())
        pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordWordStartLst, m_xAutoCapsCB->get_active());
    return false;
}

void OfaAutocorrExceptPage::SetLanguage(LanguageType eSet)
{
    if(eLang != eSet)
    {
        // save old settings and fill anew
        RefillReplaceBoxes(false, eLang, eSet);
        eLastDialogLanguage = eSet;
        maCompareClass = CollatorWrapper( comphelper::getProcessComponentContext() );
        maCompareClass.loadDefaultCollator( LanguageTag::convertToLocale( eLastDialogLanguage ), 0 );
        ModifyHdl(*m_xAbbrevED);
        ModifyHdl(*m_xDoubleCapsED);
    }
}

void OfaAutocorrExceptPage::RefillReplaceBoxes(bool bFromReset,
                                        LanguageType eOldLanguage,
                                        LanguageType eNewLanguage)
{
    eLang = eNewLanguage;
    if(bFromReset)
    {
        aStringsTable.clear();
    }
    else
    {
        StringsArrays* pArrays;
        if(aStringsTable.find(eOldLanguage) != aStringsTable.end())
        {
            pArrays = &aStringsTable[eOldLanguage];
            pArrays->aAbbrevStrings.clear();
            pArrays->aDoubleCapsStrings.clear();
        }
        else
        {
            pArrays = &aStringsTable[eOldLanguage]; // create new array
        }

        sal_Int32 i, nCount;
        nCount = m_xAbbrevLB->n_children();
        for(i = 0; i < nCount; i++)
            pArrays->aAbbrevStrings.push_back(m_xAbbrevLB->get_text(i));

        nCount = m_xDoubleCapsLB->n_children();
        for(i = 0; i < nCount; i++)
            pArrays->aDoubleCapsStrings.push_back(m_xDoubleCapsLB->get_text(i));
    }
    m_xDoubleCapsLB->clear();
    m_xAbbrevLB->clear();
    m_xAbbrevED->set_text(u""_ustr);
    m_xDoubleCapsED->set_text(u""_ustr);

    if(aStringsTable.find(eLang) != aStringsTable.end())
    {
        StringsArrays& rArrays = aStringsTable[eLang];
        for (auto const& elem : rArrays.aAbbrevStrings)
            m_xAbbrevLB->append_text(elem);

        for (auto const& elem : rArrays.aDoubleCapsStrings)
            m_xDoubleCapsLB->append_text(elem);
    }
    else
    {
        SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
        const SvStringsISortDtor* pCplList = pAutoCorrect->GetCplSttExceptList(eLang);
        const SvStringsISortDtor* pWrdList = pAutoCorrect->GetWordStartExceptList(eLang);
        size_t i;
        for( i = 0; i < pCplList->size(); i++ )
        {
            m_xAbbrevLB->append_text((*pCplList)[i]);
        }
        for( i = 0; i < pWrdList->size(); i++ )
        {
            m_xDoubleCapsLB->append_text((*pWrdList)[i]);
        }
    }
}

void OfaAutocorrExceptPage::Reset( const SfxItemSet* )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    RefillReplaceBoxes(true, eLang, eLang);
    m_xAutoAbbrevCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordCplSttLst));
    m_xAutoCapsCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordWordStartLst));
    m_xAutoAbbrevCB->save_state();
    m_xAutoCapsCB->save_state();
}

IMPL_LINK(OfaAutocorrExceptPage, NewDelButtonHdl, weld::Button&, rBtn, void)
{
    NewDelHdl(&rBtn);
}

IMPL_LINK(OfaAutocorrExceptPage, NewDelActionHdl, weld::Entry&, rEdit, bool)
{
    return NewDelHdl(&rEdit);
}

bool OfaAutocorrExceptPage::NewDelHdl(const weld::Widget* pBtn)
{
    if ((pBtn == m_xNewAbbrevPB.get() || pBtn == m_xAbbrevED.get())
        && !m_xAbbrevED->get_text().isEmpty() && m_xNewAbbrevPB->get_sensitive())
    {
        m_xAbbrevLB->append_text(m_xAbbrevED->get_text());
        ModifyHdl(*m_xAbbrevED);
    }
    else if(pBtn == m_xDelAbbrevPB.get())
    {
        m_xAbbrevLB->remove_text(m_xAbbrevED->get_text());
        ModifyHdl(*m_xAbbrevED);
    }
    else if((pBtn == m_xNewDoublePB.get() || pBtn == m_xDoubleCapsED.get() )
            && !m_xDoubleCapsED->get_text().isEmpty() && m_xNewDoublePB->get_sensitive())
    {
        m_xDoubleCapsLB->append_text(m_xDoubleCapsED->get_text());
        ModifyHdl(*m_xDoubleCapsED);
    }
    else if (pBtn == m_xDelDoublePB.get())
    {
        m_xDoubleCapsLB->remove_text(m_xDoubleCapsED->get_text());
        ModifyHdl(*m_xDoubleCapsED);
    }
    else
    {
        // we didn't do anything, if this was because of 'activate' in an
        // entry then let it continue to close the dialog like the replace
        // page does
        return false;
    }
    return true;
}

IMPL_LINK(OfaAutocorrExceptPage, SelectHdl, weld::TreeView&, rBox, void)
{
    if (&rBox == m_xAbbrevLB.get())
    {
        m_xAbbrevED->set_text(rBox.get_selected_text());
        m_xNewAbbrevPB->set_sensitive(false);
        m_xDelAbbrevPB->set_sensitive(true);
    }
    else
    {
        m_xDoubleCapsED->set_text(rBox.get_selected_text());
        m_xNewDoublePB->set_sensitive(false);
        m_xDelDoublePB->set_sensitive(true);
    }
}

IMPL_LINK(OfaAutocorrExceptPage, ModifyHdl, weld::Entry&, rEdt, void)
{
    const OUString sEntry = rEdt.get_text();
    bool bEntryLen = !sEntry.isEmpty();
    if (&rEdt == m_xAbbrevED.get())
    {
        bool bSame = lcl_FindEntry(*m_xAbbrevLB, sEntry, maCompareClass);
        if(bSame && sEntry != m_xAbbrevLB->get_selected_text())
            rEdt.set_text(m_xAbbrevLB->get_selected_text());
        m_xNewAbbrevPB->set_sensitive(!bSame && bEntryLen);
        m_xDelAbbrevPB->set_sensitive(bSame && bEntryLen);
    }
    else
    {
        bool bSame = lcl_FindEntry(*m_xDoubleCapsLB, sEntry, maCompareClass);
        if(bSame && sEntry != m_xDoubleCapsLB->get_selected_text())
            rEdt.set_text(m_xDoubleCapsLB->get_selected_text());
        m_xNewDoublePB->set_sensitive(!bSame && bEntryLen);
        m_xDelDoublePB->set_sensitive(bSame && bEntryLen);
    }
}

namespace {

enum OfaQuoteOptions
{
    ADD_NONBRK_SPACE,
    REPLACE_1ST,
    TRANSLITERATE_RTL,
    REPLACE_ANGLE_QUOTES
};

}

void OfaQuoteTabPage::CreateEntry(weld::TreeView& rCheckLB, const OUString& rTxt, sal_uInt16 nCol, sal_uInt16 nTextCol)
{
    rCheckLB.append();
    const int nRow = rCheckLB.n_children() - 1;
    if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
        rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
    if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
        rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
    rCheckLB.set_text(nRow, rTxt, nTextCol);
}

OfaQuoteTabPage::OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
    : SfxTabPage(pPage, pController, u"cui/ui/applylocalizedpage.ui"_ustr, u"ApplyLocalizedPage"_ustr, &rSet)
    , sNonBrkSpace(CuiResId(RID_CUISTR_NON_BREAK_SPACE))
    , sOrdinal(CuiResId(RID_CUISTR_ORDINAL))
    , sTransliterateRTL(CuiResId(RID_CUISTR_OLD_HUNGARIAN))
    , sAngleQuotes(CuiResId(RID_CUISTR_ANGLE_QUOTES))
    , cSglStartQuote(0)
    , cSglEndQuote(0)
    , cStartQuote(0)
    , cEndQuote(0)
    , m_xSingleTypoCB(m_xBuilder->weld_check_button(u"singlereplace"_ustr))
    , m_xSglStartQuotePB(m_xBuilder->weld_button(u"startsingle"_ustr))
    , m_xSglStartExFT(m_xBuilder->weld_label(u"singlestartex"_ustr))
    , m_xSglEndQuotePB(m_xBuilder->weld_button(u"endsingle"_ustr))
    , m_xSglEndExFT(m_xBuilder->weld_label(u"singleendex"_ustr))
    , m_xSglStandardPB(m_xBuilder->weld_button(u"defaultsingle"_ustr))
    , m_xDoubleTypoCB(m_xBuilder->weld_check_button(u"doublereplace"_ustr))
    , m_xDblStartQuotePB(m_xBuilder->weld_button(u"startdouble"_ustr))
    , m_xDblStartExFT(m_xBuilder->weld_label(u"doublestartex"_ustr))
    , m_xDblEndQuotePB(m_xBuilder->weld_button(u"enddouble"_ustr))
    , m_xDblEndExFT(m_xBuilder->weld_label(u"doubleendex"_ustr))
    , m_xDblStandardPB(m_xBuilder->weld_button(u"defaultdouble"_ustr))
    , m_sStandard(m_xSglStartExFT->get_label())
    , m_xCheckLB(m_xBuilder->weld_tree_view(u"checklist"_ustr))
    , m_xSwCheckLB(m_xBuilder->weld_tree_view(u"list"_ustr))
{
    m_xSwCheckLB->set_size_request(m_xSwCheckLB->get_approximate_digit_width() * 50,
                                   m_xSwCheckLB->get_height_rows(6));

    bool bShowSWOptions = false;

    const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>(SID_AUTO_CORRECT_DLG, false);
    if ( pItem && pItem->GetValue() )
        bShowSWOptions = true;

    if ( bShowSWOptions )
    {
        std::vector<int> aWidths
        {
            o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2),
            o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(1)).Width() * 2)
        };
        m_xSwCheckLB->set_column_fixed_widths(aWidths);
        m_xCheckLB->hide();
    }
    else
    {
        m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
        m_xSwCheckLB->hide();
    }

    m_xDblStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
    m_xDblEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
    m_xSglStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
    m_xSglEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
    m_xDblStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
    m_xSglStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
}

OfaQuoteTabPage::~OfaQuoteTabPage()
{
}

std::unique_ptr<SfxTabPage> OfaQuoteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
                                                    const SfxItemSet* rAttrSet)
{
    return std::make_unique<OfaQuoteTabPage>(pPage, pController, *rAttrSet);
}

bool OfaQuoteTabPage::FillItemSet( SfxItemSet*  )
{
    SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();

    ACFlags nFlags = pAutoCorrect->GetFlags();

    if (m_xCheckLB->get_visible())
    {
        int nPos = 0;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=94 H=94 G=93

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.