/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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(_pSet, SID_AUTO_CORRECT_DLG, false); if ( pItem && pItem->GetValue() ) bShowSWOptions = true; const SfxBoolItem* pItem2 = SfxItemSet::GetItem(_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, true, true ); 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(GetTabPage(sPageId)); assert(pPage); pPage->SetLanguage(eNewLang); } else if (sPageId == "exceptions") { OfaAutocorrExceptPage* pPage = static_cast(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 OfaAutocorrOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet) { return std::make_unique(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(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 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_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl)); m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl)); std::vector aWidths { o3tl::narrowing(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2), o3tl::narrowing(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(m_xCheckLB->get_id(REPLACE_BULLETS)); delete weld::fromId(m_xCheckLB->get_id(APPLY_NUMBERING)); delete weld::fromId(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA)); } std::unique_ptr OfaSwAutoFmtOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet) { return std::make_unique(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(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(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(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(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_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 OfaAutocorrReplacePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet) { return std::make_unique(pPage, pController, *rSet); } void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& ) { if(eLang != eLastDialogLanguage) SetLanguage(eLastDialogLanguage); static_cast(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 aDeleteWords; std::vector 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(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& 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 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& 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_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl)); m_xDoubleCapsLB->connect_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 OfaAutocorrExceptPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet) { return std::make_unique(pPage, pController, *rSet); } void OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& ) { if(eLang != eLastDialogLanguage) SetLanguage(eLastDialogLanguage); static_cast(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(SID_AUTO_CORRECT_DLG, false); if ( pItem && pItem->GetValue() ) bShowSWOptions = true; if ( bShowSWOptions ) { std::vector aWidths { o3tl::narrowing(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2), o3tl::narrowing(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 OfaQuoteTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet) { return std::make_unique(pPage, pController, *rAttrSet); } bool OfaQuoteTabPage::FillItemSet( SfxItemSet* ) { SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); ACFlags nFlags = pAutoCorrect->GetFlags(); if (m_xCheckLB->get_visible()) { int nPos = 0; pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE); pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE); pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE); pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE); } bool bModified = false; if (m_xSwCheckLB->get_visible()) { SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags(); bool bCheck = m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_FIRST) == TRISTATE_TRUE; bModified |= pOpt->bAddNonBrkSpace != bCheck; pOpt->bAddNonBrkSpace = bCheck; pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_SECOND) == TRISTATE_TRUE); bCheck = m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_FIRST) == TRISTATE_TRUE; bModified |= pOpt->bChgOrdinalNumber != bCheck; pOpt->bChgOrdinalNumber = bCheck; pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE); bCheck = m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_FIRST) == TRISTATE_TRUE; bModified |= pOpt->bTransliterateRTL != bCheck; pOpt->bTransliterateRTL = bCheck; pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_SECOND) == TRISTATE_TRUE); bCheck = m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_FIRST) == TRISTATE_TRUE; bModified |= pOpt->bChgAngleQuotes != bCheck; pOpt->bChgAngleQuotes = bCheck; pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes, m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_SECOND) == TRISTATE_TRUE); } pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active()); pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgSglQuotes, m_xSingleTypoCB->get_active()); bool bReturn = nFlags != pAutoCorrect->GetFlags(); if(cStartQuote != pAutoCorrect->GetStartDoubleQuote()) { bReturn = true; sal_Unicode cUCS2 = static_cast(cStartQuote); //TODO pAutoCorrect->SetStartDoubleQuote(cUCS2); } if(cEndQuote != pAutoCorrect->GetEndDoubleQuote()) { bReturn = true; sal_Unicode cUCS2 = static_cast(cEndQuote); //TODO pAutoCorrect->SetEndDoubleQuote(cUCS2); } if(cSglStartQuote != pAutoCorrect->GetStartSingleQuote()) { bReturn = true; sal_Unicode cUCS2 = static_cast(cSglStartQuote); //TODO pAutoCorrect->SetStartSingleQuote(cUCS2); } if(cSglEndQuote != pAutoCorrect->GetEndSingleQuote()) { bReturn = true; sal_Unicode cUCS2 = static_cast(cSglEndQuote); //TODO pAutoCorrect->SetEndSingleQuote(cUCS2); } if( bModified || bReturn ) { SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get(); rCfg.SetModified(); rCfg.Commit(); } return bReturn; } void OfaQuoteTabPage::ActivatePage( const SfxItemSet& ) { static_cast(GetDialogController())->EnableLanguage(false); } void OfaQuoteTabPage::Reset( const SfxItemSet* ) { SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); const ACFlags nFlags = pAutoCorrect->GetFlags(); // Initialize the Sw options if (m_xSwCheckLB->get_visible()) { SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags(); m_xSwCheckLB->freeze(); m_xSwCheckLB->clear(); CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2); CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2); CreateEntry(*m_xSwCheckLB, sTransliterateRTL, CBCOL_BOTH, 2); CreateEntry(*m_xSwCheckLB, sAngleQuotes, CBCOL_BOTH, 2); m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, pOpt->bTransliterateRTL ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, pOpt->bChgAngleQuotes ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); m_xSwCheckLB->thaw(); } // Initialize the non Sw options if (m_xCheckLB->get_visible()) { m_xCheckLB->freeze(); m_xCheckLB->clear(); int nPos = 0; m_xCheckLB->append(); m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE); m_xCheckLB->set_text(nPos++, sNonBrkSpace, 0); m_xCheckLB->append(); m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE); m_xCheckLB->set_text(nPos++, sOrdinal, 0); m_xCheckLB->append(); m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE); m_xCheckLB->set_text(nPos++, sTransliterateRTL, 0); m_xCheckLB->append(); m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE); m_xCheckLB->set_text(nPos++, sAngleQuotes, 0); m_xCheckLB->thaw(); } // Initialize the quote stuffs m_xDoubleTypoCB->set_active(bool(nFlags & ACFlags::ChgQuotes)); m_xSingleTypoCB->set_active(bool(nFlags & ACFlags::ChgSglQuotes)); m_xDoubleTypoCB->save_state(); m_xSingleTypoCB->save_state(); cStartQuote = pAutoCorrect->GetStartDoubleQuote(); cEndQuote = pAutoCorrect->GetEndDoubleQuote(); cSglStartQuote = pAutoCorrect->GetStartSingleQuote(); cSglEndQuote = pAutoCorrect->GetEndSingleQuote(); m_xSglStartExFT->set_label(ChangeStringExt_Impl(cSglStartQuote)); m_xSglEndExFT->set_label(ChangeStringExt_Impl(cSglEndQuote)); m_xDblStartExFT->set_label(ChangeStringExt_Impl(cStartQuote)); m_xDblEndExFT->set_label(ChangeStringExt_Impl(cEndQuote)); } #define SGL_START 0 #define DBL_START 1 #define SGL_END 2 #define DBL_END 3 IMPL_LINK(OfaQuoteTabPage, QuoteHdl, weld::Button&, rBtn, void) { sal_uInt16 nMode = SGL_START; if (&rBtn == m_xSglEndQuotePB.get()) nMode = SGL_END; else if (&rBtn == m_xDblStartQuotePB.get()) nMode = DBL_START; else if (&rBtn == m_xDblEndQuotePB.get()) nMode = DBL_END; // start character selection dialog SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr); aMap.SetCharFont( OutputDevice::GetDefaultFont(DefaultFontType::LATIN_TEXT, LANGUAGE_ENGLISH_US, GetDefaultFontFlags::OnlyOne )); aMap.set_title(nMode < SGL_END ? CuiResId(RID_CUISTR_STARTQUOTE) : CuiResId(RID_CUISTR_ENDQUOTE)); sal_UCS4 cDlg; SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType(); switch( nMode ) { case SGL_START: cDlg = cSglStartQuote; if(cDlg == 0) cDlg = pAutoCorrect->GetQuote('\'', true, eLang); break; case SGL_END: cDlg = cSglEndQuote; if(cDlg == 0) cDlg = pAutoCorrect->GetQuote('\'', false, eLang); break; case DBL_START: cDlg = cStartQuote; if(cDlg == 0) cDlg = pAutoCorrect->GetQuote('\"', true, eLang); break; case DBL_END: cDlg = cEndQuote; if(cDlg == 0) cDlg = pAutoCorrect->GetQuote('\"', false, eLang); break; default: OSL_FAIL("svx::OfaQuoteTabPage::QuoteHdl(), how to initialize cDlg?" ); cDlg = 0; break; } aMap.SetChar( cDlg ); aMap.DisableFontSelection(); if (aMap.run() != RET_OK) return; sal_UCS4 cNewChar = aMap.GetChar(); switch( nMode ) { case SGL_START: cSglStartQuote = cNewChar; m_xSglStartExFT->set_label(ChangeStringExt_Impl(cNewChar)); break; case SGL_END: cSglEndQuote = cNewChar; m_xSglEndExFT->set_label(ChangeStringExt_Impl(cNewChar)); break; case DBL_START: cStartQuote = cNewChar; m_xDblStartExFT->set_label(ChangeStringExt_Impl(cNewChar)); break; case DBL_END: cEndQuote = cNewChar; m_xDblEndExFT->set_label(ChangeStringExt_Impl(cNewChar)); break; } } IMPL_LINK(OfaQuoteTabPage, StdQuoteHdl, weld::Button&, rBtn, void) { if (&rBtn == m_xDblStandardPB.get()) { cStartQuote = 0; m_xDblStartExFT->set_label(ChangeStringExt_Impl(0)); cEndQuote = 0; m_xDblEndExFT->set_label(ChangeStringExt_Impl(0)); } else { cSglStartQuote = 0; m_xSglStartExFT->set_label(ChangeStringExt_Impl(0)); cSglEndQuote = 0; m_xSglEndExFT->set_label(ChangeStringExt_Impl(0)); } } OUString OfaQuoteTabPage::ChangeStringExt_Impl( sal_UCS4 cChar ) { if (!cChar) return m_sStandard; // convert codepoint value to unicode-hex string sal_UCS4 aStrCodes[32] = { 0, ' ', '(', 'U', '+', '0' }; aStrCodes[0] = cChar; int nFullLen = 5; int nHexLen = 4; while( (cChar >> (4*nHexLen)) != 0 ) ++nHexLen; for( int i = nHexLen; --i >= 0;) { sal_UCS4 cHexDigit = ((cChar >> (4*i)) & 0x0f) + '0'; if( cHexDigit > '9' ) cHexDigit += 'A' - ('9' + 1); aStrCodes[ nFullLen++ ] = cHexDigit; } aStrCodes[ nFullLen++ ] = ')'; // using the new UCS4 constructor OUString aOUStr( aStrCodes, nFullLen ); return aOUStr; } OfaAutoCompleteTabPage::OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) : SfxTabPage(pPage, pController, u"cui/ui/wordcompletionpage.ui"_ustr, u"WordCompletionPage"_ustr, &rSet) , m_pAutoCompleteList(nullptr) , m_nAutoCmpltListCnt(0) , m_xCBActiv(m_xBuilder->weld_check_button(u"enablewordcomplete"_ustr)) , m_xCBAppendSpace(m_xBuilder->weld_check_button(u"appendspace"_ustr)) , m_xCBAsTip(m_xBuilder->weld_check_button(u"showastip"_ustr)) , m_xCBCollect(m_xBuilder->weld_check_button(u"collectwords"_ustr)) , m_xCBRemoveList(m_xBuilder->weld_check_button(u"whenclosing"_ustr)) , m_xDCBExpandKey(m_xBuilder->weld_combo_box(u"acceptwith"_ustr)) , m_xNFMinWordlen(m_xBuilder->weld_spin_button(u"minwordlen"_ustr)) , m_xNFMaxEntries(m_xBuilder->weld_spin_button(u"maxentries"_ustr)) , m_xLBEntries(m_xBuilder->weld_tree_view(u"entries"_ustr)) , m_xPBEntries(m_xBuilder->weld_button(u"delete"_ustr)) { //fdo#65595, we need height-for-width support here, but for now we can //bodge it Size aPrefSize(m_xCBRemoveList->get_preferred_size()); int nMaxWidth = m_xCBRemoveList->get_approximate_digit_width() * 40; if (aPrefSize.Width() > nMaxWidth) { m_xCBRemoveList->set_label_wrap(true); m_xCBRemoveList->set_size_request(nMaxWidth, -1); } m_xLBEntries->set_size_request(m_xLBEntries->get_approximate_digit_width() * 30, m_xLBEntries->get_height_rows(10)); m_xLBEntries->set_selection_mode(SelectionMode::Multiple); // the defined KEYs static const sal_uInt16 aKeyCodes[] = { KEY_END, KEY_RETURN, KEY_SPACE, KEY_RIGHT, KEY_TAB, 0 }; for( const sal_uInt16* pKeys = aKeyCodes; *pKeys; ++pKeys ) { vcl::KeyCode aKCode(*pKeys); m_xDCBExpandKey->append(OUString::number(static_cast(*pKeys)), aKCode.GetName()); if (KEY_RETURN == *pKeys) // default to RETURN m_xDCBExpandKey->set_active(std::distance(aKeyCodes, pKeys)); } m_xPBEntries->connect_clicked(LINK(this, OfaAutoCompleteTabPage, DeleteHdl)); m_xCBActiv->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl)); m_xCBCollect->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl)); m_xLBEntries->connect_key_release(LINK(this, OfaAutoCompleteTabPage, KeyReleaseHdl)); } OfaAutoCompleteTabPage::~OfaAutoCompleteTabPage() { } std::unique_ptr OfaAutoCompleteTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet) { return std::make_unique(pPage, pController, *rSet); } bool OfaAutoCompleteTabPage::FillItemSet( SfxItemSet* ) { bool bModified = false, bCheck; SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags(); bCheck = m_xCBActiv->get_active(); bModified |= pOpt->bAutoCompleteWords != bCheck; pOpt->bAutoCompleteWords = bCheck; bCheck = m_xCBCollect->get_active(); bModified |= pOpt->bAutoCmpltCollectWords != bCheck; pOpt->bAutoCmpltCollectWords = bCheck; bCheck = !m_xCBRemoveList->get_active(); // inverted value! bModified |= pOpt->bAutoCmpltKeepList != bCheck; pOpt->bAutoCmpltKeepList = bCheck; bCheck = m_xCBAppendSpace->get_active(); bModified |= pOpt->bAutoCmpltAppendBlank != bCheck; pOpt->bAutoCmpltAppendBlank = bCheck; bCheck = m_xCBAsTip->get_active(); bModified |= pOpt->bAutoCmpltShowAsTip != bCheck; pOpt->bAutoCmpltShowAsTip = bCheck; sal_uInt16 nVal = static_cast(m_xNFMinWordlen->get_value()); bModified |= nVal != pOpt->nAutoCmpltWordLen; pOpt->nAutoCmpltWordLen = nVal; sal_uInt32 nList = static_cast(m_xNFMaxEntries->get_value()); bModified |= nList != pOpt->nAutoCmpltListLen; pOpt->nAutoCmpltListLen = nList; const int nPos = m_xDCBExpandKey->get_active(); if (nPos != -1) { sal_Int32 nKey = m_xDCBExpandKey->get_id(nPos).toInt32(); bModified |= nKey != pOpt->nAutoCmpltExpandKey; pOpt->nAutoCmpltExpandKey = static_cast(nKey); } if (m_pAutoCompleteList && m_nAutoCmpltListCnt != m_xLBEntries->n_children()) { bModified = true; pOpt->m_pAutoCompleteList = m_pAutoCompleteList; } if( bModified ) { SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get(); rCfg.SetModified(); rCfg.Commit(); } return true; } void OfaAutoCompleteTabPage::Reset( const SfxItemSet* ) { SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags(); m_xCBActiv->set_active( pOpt->bAutoCompleteWords ); m_xCBCollect->set_active( pOpt->bAutoCmpltCollectWords ); m_xCBRemoveList->set_active( !pOpt->bAutoCmpltKeepList ); //inverted value! m_xCBAppendSpace->set_active( pOpt->bAutoCmpltAppendBlank ); m_xCBAsTip->set_active( pOpt->bAutoCmpltShowAsTip ); m_xNFMinWordlen->set_value( pOpt->nAutoCmpltWordLen ); m_xNFMaxEntries->set_value( pOpt->nAutoCmpltListLen ); // select the specific KeyCode: { sal_Int32 nKey = pOpt->nAutoCmpltExpandKey; for (int n = 0, nCnt = m_xDCBExpandKey->get_count(); n < nCnt; ++n) { if (nKey == m_xDCBExpandKey->get_id(n).toInt32()) { m_xDCBExpandKey->set_active(n); break; } } } if (pOpt->m_pAutoCompleteList && !pOpt->m_pAutoCompleteList->empty()) { m_pAutoCompleteList = const_cast( pOpt->m_pAutoCompleteList); pOpt->m_pAutoCompleteList = nullptr; m_nAutoCmpltListCnt = m_pAutoCompleteList->size(); for (size_t n = 0; n < m_nAutoCmpltListCnt; ++n) { const OUString* pStr = &(*m_pAutoCompleteList)[n]->GetAutoCompleteString(); OUString sId(weld::toId(pStr)); m_xLBEntries->append(sId, *pStr); } } else { m_xLBEntries->set_sensitive(false); m_xPBEntries->set_sensitive(false); } CheckHdl(*m_xCBActiv); CheckHdl(*m_xCBCollect); } void OfaAutoCompleteTabPage::ActivatePage( const SfxItemSet& ) { static_cast(GetDialogController())->EnableLanguage( false ); } IMPL_LINK_NOARG(OfaAutoCompleteTabPage, DeleteHdl, weld::Button&, void) { auto rows = m_xLBEntries->get_selected_rows(); std::sort(rows.begin(), rows.end()); while (!rows.empty()) { sal_Int32 nPos = rows.back(); OUString* pStr = weld::fromId(m_xLBEntries->get_id(nPos)); m_xLBEntries->remove(nPos); editeng::IAutoCompleteString hack(*pStr); // UGLY m_pAutoCompleteList->erase(&hack); rows.pop_back(); } } IMPL_LINK(OfaAutoCompleteTabPage, CheckHdl, weld::Toggleable&, rBox, void) { bool bEnable = rBox.get_active(); if (&rBox == m_xCBActiv.get()) { m_xCBAppendSpace->set_sensitive(bEnable); m_xCBAppendSpace->set_sensitive(bEnable); m_xCBAsTip->set_sensitive(bEnable); m_xDCBExpandKey->set_sensitive(bEnable); } else if (&rBox == m_xCBCollect.get()) m_xCBRemoveList->set_sensitive(bEnable); } void OfaAutoCompleteTabPage::CopyToClipboard() const { auto rows = m_xLBEntries->get_selected_rows(); if (!m_pAutoCompleteList || rows.empty()) return; rtl::Reference pCntnr = new TransferDataContainer; OStringBuffer sData; rtl_TextEncoding nEncode = osl_getThreadTextEncoding(); for (auto a : rows) { sData.append(OUStringToOString(m_xLBEntries->get_text(a), nEncode) + SAL_NEWLINE_STRING); } pCntnr->CopyByteString( SotClipboardFormatId::STRING, sData.makeStringAndClear() ); pCntnr->CopyToClipboard(m_xLBEntries->get_clipboard()); } IMPL_LINK(OfaAutoCompleteTabPage, KeyReleaseHdl, const KeyEvent&, rEvent, bool) { bool bHandled = false; const vcl::KeyCode& rKeyCode = rEvent.GetKeyCode(); switch (rKeyCode.GetModifier() | rKeyCode.GetCode()) { case KEY_DELETE: DeleteHdl(*m_xPBEntries); bHandled = true; break; default: if (KeyFuncType::COPY == rKeyCode.GetFunction()) { CopyToClipboard(); bHandled = true; } break; } return bHandled; } // class OfaSmartTagOptionsTabPage --------------------------------------------- OfaSmartTagOptionsTabPage::OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet ) : SfxTabPage(pPage, pController, u"cui/ui/smarttagoptionspage.ui"_ustr, u"SmartTagOptionsPage"_ustr, &rSet) , m_xMainCB(m_xBuilder->weld_check_button(u"main"_ustr)) , m_xSmartTagTypesLB(m_xBuilder->weld_tree_view(u"list"_ustr)) , m_xPropertiesPB(m_xBuilder->weld_button(u"properties"_ustr)) { m_xSmartTagTypesLB->set_size_request(m_xSmartTagTypesLB->get_approximate_digit_width() * 50, m_xSmartTagTypesLB->get_height_rows(6)); m_xSmartTagTypesLB->enable_toggle_buttons(weld::ColumnToggleType::Check); // set the handlers: m_xMainCB->connect_toggled(LINK(this, OfaSmartTagOptionsTabPage, CheckHdl)); m_xPropertiesPB->connect_clicked(LINK(this, OfaSmartTagOptionsTabPage, ClickHdl)); m_xSmartTagTypesLB->connect_changed(LINK(this, OfaSmartTagOptionsTabPage, SelectHdl)); } OfaSmartTagOptionsTabPage::~OfaSmartTagOptionsTabPage() { } std::unique_ptr OfaSmartTagOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet) { return std::make_unique(pPage, pController, *rSet); } namespace { /** This struct is used to associate list box entries with smart tag data */ struct ImplSmartTagLBUserData { OUString maSmartTagType; uno::Reference< smarttags::XSmartTagRecognizer > mxRec; sal_Int32 mnSmartTagIdx; ImplSmartTagLBUserData( OUString aSmartTagType, uno::Reference< smarttags::XSmartTagRecognizer > xRec, sal_Int32 nSmartTagIdx ) : maSmartTagType(std::move( aSmartTagType )), mxRec(std::move( xRec )), mnSmartTagIdx( nSmartTagIdx ) {} }; } /** Clears m_xSmartTagTypesLB */ void OfaSmartTagOptionsTabPage::ClearListBox() { const int nCount = m_xSmartTagTypesLB->n_children(); for (int i = 0; i < nCount; ++i) { const ImplSmartTagLBUserData* pUserData = weld::fromId(m_xSmartTagTypesLB->get_id(i)); delete pUserData; } m_xSmartTagTypesLB->clear(); } /** Inserts items into m_xSmartTagTypesLB */ void OfaSmartTagOptionsTabPage::FillListBox( const SmartTagMgr& rSmartTagMgr ) { // first we have to clear the list box: ClearListBox(); // fill list box: const sal_uInt32 nNumberOfRecognizers = rSmartTagMgr.NumberOfRecognizers(); const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) ); for ( sal_uInt32 i = 0; i < nNumberOfRecognizers; ++i ) { const uno::Reference< smarttags::XSmartTagRecognizer >& xRec = rSmartTagMgr.GetRecognizer(i); const OUString aName = xRec->getName( aLocale ); const sal_Int32 nNumberOfSupportedSmartTags = xRec->getSmartTagCount(); for ( sal_Int32 j = 0; j < nNumberOfSupportedSmartTags; ++j ) { const OUString aSmartTagType = xRec->getSmartTagName(j); OUString aSmartTagCaption = rSmartTagMgr.GetSmartTagCaption( aSmartTagType, aLocale ); if ( aSmartTagCaption.isEmpty() ) aSmartTagCaption = aSmartTagType; const OUString aLBEntry = aSmartTagCaption + " (" + aName + ")"; m_xSmartTagTypesLB->append(); const int nRow = m_xSmartTagTypesLB->n_children() - 1; const bool bCheck = rSmartTagMgr.IsSmartTagTypeEnabled( aSmartTagType ); m_xSmartTagTypesLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE); m_xSmartTagTypesLB->set_text(nRow, aLBEntry, 0); m_xSmartTagTypesLB->set_id(nRow, weld::toId(new ImplSmartTagLBUserData(aSmartTagType, xRec, j))); } } } /** Handler for the push button */ IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, ClickHdl, weld::Button&, void) { const int nPos = m_xSmartTagTypesLB->get_selected_index(); const ImplSmartTagLBUserData* pUserData = weld::fromId(m_xSmartTagTypesLB->get_id(nPos)); uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec; const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx; const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) ); if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) ) xRec->displayPropertyPage( nSmartTagIdx, aLocale ); } /** Handler for the check box */ IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, CheckHdl, weld::Toggleable&, void) { const bool bEnable = m_xMainCB->get_active(); m_xSmartTagTypesLB->set_sensitive(bEnable); m_xPropertiesPB->set_sensitive(false); // if the controls are currently enabled, we still have to check // if the properties button should be disabled because the currently // selected smart tag type does not have a properties dialog. // We do this by calling SelectHdl: if (bEnable) SelectHdl(*m_xSmartTagTypesLB); } /** Handler for the list box */ IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, SelectHdl, weld::TreeView&, void) { const int nPos = m_xSmartTagTypesLB->get_selected_index(); if (nPos == -1) return; const ImplSmartTagLBUserData* pUserData = weld::fromId(m_xSmartTagTypesLB->get_id(nPos)); uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec; const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx; const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) ); if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) ) m_xPropertiesPB->set_sensitive(true); else m_xPropertiesPB->set_sensitive(false); } /** Propagates the current settings to the smart tag manager. */ bool OfaSmartTagOptionsTabPage::FillItemSet( SfxItemSet* ) { SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags(); SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr; // robust! if ( !pSmartTagMgr ) return false; bool bModifiedSmartTagTypes = false; std::vector< OUString > aDisabledSmartTagTypes; const int nCount = m_xSmartTagTypesLB->n_children(); for (int i = 0; i < nCount; ++i) { const ImplSmartTagLBUserData* pUserData = weld::fromId(m_xSmartTagTypesLB->get_id(i)); const bool bChecked = m_xSmartTagTypesLB->get_toggle(i) == TRISTATE_TRUE; const bool bIsCurrentlyEnabled = pSmartTagMgr->IsSmartTagTypeEnabled( pUserData->maSmartTagType ); bModifiedSmartTagTypes = bModifiedSmartTagTypes || ( !bChecked != !bIsCurrentlyEnabled ); if ( !bChecked ) aDisabledSmartTagTypes.push_back( pUserData->maSmartTagType ); delete pUserData; } const bool bModifiedRecognize = ( !m_xMainCB->get_active() != !pSmartTagMgr->IsLabelTextWithSmartTags() ); if ( bModifiedSmartTagTypes || bModifiedRecognize ) { bool bLabelTextWithSmartTags = m_xMainCB->get_active(); pSmartTagMgr->WriteConfiguration( bModifiedRecognize ? &bLabelTextWithSmartTags : nullptr, bModifiedSmartTagTypes ? &aDisabledSmartTagTypes : nullptr ); } return true; } /** Sets the controls based on the current settings at SmartTagMgr. */ void OfaSmartTagOptionsTabPage::Reset( const SfxItemSet* ) { SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags(); const SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr; // robust, should not happen! if ( !pSmartTagMgr ) return; FillListBox(*pSmartTagMgr); m_xSmartTagTypesLB->select(0); m_xMainCB->set_active(pSmartTagMgr->IsLabelTextWithSmartTags()); CheckHdl(*m_xMainCB); } void OfaSmartTagOptionsTabPage::ActivatePage( const SfxItemSet& ) { static_cast(GetDialogController())->EnableLanguage( false ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */