diff options
Diffstat (limited to 'cui/source/options/optdict.cxx')
-rw-r--r-- | cui/source/options/optdict.cxx | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/cui/source/options/optdict.cxx b/cui/source/options/optdict.cxx new file mode 100644 index 0000000000..dbe7f80e3d --- /dev/null +++ b/cui/source/options/optdict.cxx @@ -0,0 +1,781 @@ +/* -*- 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 <editeng/unolingu.hxx> +#include <o3tl/safeint.hxx> +#include <svx/dialmgr.hxx> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/linguistic2/XDictionary.hpp> +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#include <comphelper/string.hxx> +#include <tools/debug.hxx> +#include <unotools/collatorwrapper.hxx> +#include <unotools/intlwrapper.hxx> +#include <unotools/syslocale.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> + +#include <linguistic/misc.hxx> +#include <strings.hrc> +#include <optdict.hxx> +#include <dialmgr.hxx> +#include <svx/svxerr.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::linguistic2; +using namespace linguistic; + +// static function ------------------------------------------------------- + +static OUString getNormDicEntry_Impl(std::u16string_view rText) +{ + OUString aTmp(comphelper::string::stripEnd(rText, '.')); + // non-standard hyphenation + if (aTmp.indexOf('[') > -1) + { + OUStringBuffer aTmp2 ( aTmp.getLength() ); + bool bSkip = false; + for (sal_Int32 i = 0; i < aTmp.getLength(); i++) + { + sal_Unicode cTmp = aTmp[i]; + if (cTmp == '[') + bSkip = true; + else if (!bSkip) + aTmp2.append( cTmp ); + else if (cTmp == ']') + bSkip = false; + } + aTmp = aTmp2.makeStringAndClear(); + } + return aTmp.replaceAll("=", ""); +} + +// tdf#154499 separate words of a phrase only by a single space, +// i.e. trim terminating spaces and replace space sequences with single spaces +static OUString fixSpace(OUString sText) +{ + sText = sText.trim(); + + sal_Int32 nLen; + do + { + nLen = sText.getLength(); + sText = sText.replaceAll(" ", " "); + } + while ( sText.getLength() < nLen ); + + return sText; +} + +namespace { + +// Compare Dictionary Entry result +enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT }; + +} + +static CDE_RESULT cmpDicEntry_Impl( std::u16string_view rText1, std::u16string_view rText2 ) +{ + CDE_RESULT eRes = CDE_DIFFERENT; + + if (rText1 == rText2) + eRes = CDE_EQUAL; + else + { // similar = equal up to trailing '.' and hyphenation positions + // marked with '=' and '[' + alternative spelling pattern + ']' + if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 )) + eRes = CDE_SIMILAR; + } + + return eRes; +} + +// class SvxNewDictionaryDialog ------------------------------------------- + +SvxNewDictionaryDialog::SvxNewDictionaryDialog(weld::Window* pParent) + : GenericDialogController(pParent, "cui/ui/optnewdictionarydialog.ui", "OptNewDictionaryDialog") + , m_xNameEdit(m_xBuilder->weld_entry("nameedit")) + , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language"))) + , m_xExceptBtn(m_xBuilder->weld_check_button("except")) + , m_xOKBtn(m_xBuilder->weld_button("ok")) +{ + // Prevent creation of dictionary without a name. + m_xOKBtn->set_sensitive(false); + + // install handler + m_xNameEdit->connect_changed(LINK(this, SvxNewDictionaryDialog, ModifyHdl_Impl)); + m_xOKBtn->connect_clicked(LINK(this, SvxNewDictionaryDialog, OKHdl_Impl)); + + // display languages + m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::ALL, true, true); + m_xLanguageLB->set_active(0); +} + +IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl, weld::Button&, void) +{ + + // add extension for personal dictionaries + OUString sDict = comphelper::string::stripEnd(m_xNameEdit->get_text(), ' ') + ".dic"; + + Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() ); + + Sequence< Reference< XDictionary > > aDics; + if (xDicList.is()) + aDics = xDicList->getDictionaries(); + const Reference< XDictionary > *pDic = aDics.getConstArray(); + sal_Int32 nCount = aDics.getLength(); + + bool bFound = false; + sal_Int32 i; + for (i = 0; !bFound && i < nCount; ++i ) + if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) ) + bFound = true; + + if ( sDict.indexOf("/") != -1 || sDict.indexOf("\\") != -1 ) + { + // Detected an invalid character. + std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Info, VclButtonsType::Ok, + CuiResId(RID_CUISTR_OPT_INVALID_DICT_NAME))); + xInfoBox->run(); + m_xNameEdit->grab_focus(); + return; + } + + if ( bFound ) + { + // duplicate names? + std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Info, VclButtonsType::Ok, + CuiResId(RID_CUISTR_OPT_DOUBLE_DICTS))); + xInfoBox->run(); + m_xNameEdit->grab_focus(); + return; + } + + // create and add + LanguageType nLang = m_xLanguageLB->get_active_id(); + try + { + // create new dictionary + DictionaryType eType = m_xExceptBtn->get_active() ? + DictionaryType_NEGATIVE : DictionaryType_POSITIVE; + if (xDicList.is()) + { + lang::Locale aLocale( LanguageTag::convertToLocale(nLang) ); + OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) ); + m_xNewDic = xDicList->createDictionary(sDict, aLocale, eType, aURL); + m_xNewDic->setActive(true); + } + DBG_ASSERT(m_xNewDic.is(), "NULL pointer"); + } + catch(...) + { + m_xNewDic = nullptr; + // error: couldn't create new dictionary + SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(), + m_xDialog.get(), RID_SVXERRCTX, SvxResLocale() ); + ErrorHandler::HandleError( ErrCodeMsg( + ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) ); + m_xDialog->response(RET_CANCEL); + } + + if (xDicList.is() && m_xNewDic.is()) + { + xDicList->addDictionary(m_xNewDic); + + // refresh list of dictionaries + //! dictionaries may have been added/removed elsewhere too. + aDics = xDicList->getDictionaries(); + } + + m_xDialog->response(RET_OK); +} + +IMPL_LINK_NOARG(SvxNewDictionaryDialog, ModifyHdl_Impl, weld::Entry&, void) +{ + m_xOKBtn->set_sensitive(!m_xNameEdit->get_text().isEmpty()); +} + +// class SvxEditDictionaryDialog ------------------------------------------- + +SvxEditDictionaryDialog::SvxEditDictionaryDialog(weld::Window* pParent, std::u16string_view rName) + : GenericDialogController(pParent, "cui/ui/editdictionarydialog.ui", "EditDictionaryDialog") + , sModify(CuiResId(STR_MODIFY)) + , bFirstSelect(false) + , bDoNothing(false) + , bDicIsReadonly(false) + , m_xAllDictsLB(m_xBuilder->weld_combo_box("book")) + , m_xLangFT(m_xBuilder->weld_label("lang_label")) + , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang"))) + , m_xWordED(m_xBuilder->weld_entry("word")) + , m_xReplaceFT(m_xBuilder->weld_label("replace_label")) + , m_xReplaceED(m_xBuilder->weld_entry("replace")) + , m_xSingleColumnLB(m_xBuilder->weld_tree_view("words")) + , m_xDoubleColumnLB(m_xBuilder->weld_tree_view("replaces")) + , m_xNewReplacePB(m_xBuilder->weld_button("newreplace")) + , m_xDeletePB(m_xBuilder->weld_button("delete")) +{ + sReplaceFT_Text = m_xReplaceFT->get_label(); + m_xSingleColumnLB->set_size_request(-1, m_xSingleColumnLB->get_height_rows(8)); + m_xDoubleColumnLB->set_size_request(-1, m_xDoubleColumnLB->get_height_rows(8)); + m_pWordsLB = m_xDoubleColumnLB.get(); + m_xSingleColumnLB->hide(); + + //set to max of both sizes to avoid resizes + sNew = m_xNewReplacePB->get_label(); + auto nNewWidth = m_xNewReplacePB->get_preferred_size().Width(); + m_xNewReplacePB->set_label(sModify); + auto nReplaceWidth = m_xNewReplacePB->get_preferred_size().Width(); + m_xNewReplacePB->set_label(sNew); + m_xNewReplacePB->set_size_request(std::max(nNewWidth, nReplaceWidth), -1); + + if (LinguMgr::GetDictionaryList().is()) + aDics = LinguMgr::GetDictionaryList()->getDictionaries(); + + m_xSingleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl)); + m_xDoubleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl)); + + std::vector<int> aWidths + { + o3tl::narrowing<int>(m_xDoubleColumnLB->get_approximate_digit_width() * 22) + }; + m_xDoubleColumnLB->set_column_fixed_widths(aWidths); + + // install handler + m_xNewReplacePB->connect_clicked( + LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl)); + m_xDeletePB->connect_clicked( + LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl)); + + m_xLangLB->connect_changed( + LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) ); + m_xAllDictsLB->connect_changed( + LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) ); + + m_xWordED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl)); + m_xReplaceED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl)); + m_xWordED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl)); + m_xReplaceED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl)); + + // fill listbox with all available WB's + const Reference< XDictionary > *pDic = aDics.getConstArray(); + sal_Int32 nCount = aDics.getLength(); + + OUString aLookUpEntry; + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + Reference< XDictionary > xDic = pDic[i]; + if (xDic.is()) + { + bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE; + OUString aDicName( xDic->getName() ); + const OUString aTxt( ::GetDicInfoStr( aDicName, + LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) ); + m_xAllDictsLB->append_text(aTxt); + + if (rName == aDicName) + aLookUpEntry = aTxt; + } + } + + m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true ); + + if ( nCount > 0 ) + { + m_xAllDictsLB->set_active_text(aLookUpEntry); + int nPos = m_xAllDictsLB->get_active(); + + if (nPos == -1) + { + nPos = 0; + m_xAllDictsLB->set_active(nPos); + } + Reference< XDictionary > xDic; + if (nPos != -1) + xDic = aDics[ nPos ]; + if (xDic.is()) + SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() ); + + // check if dictionary is read-only + SetDicReadonly_Impl(xDic); + bool bEnable = !IsDicReadonly_Impl(); + m_xNewReplacePB->set_sensitive( false ); + m_xDeletePB->set_sensitive( false ); + m_xLangFT->set_sensitive( bEnable ); + m_xLangLB->set_sensitive( bEnable ); + ShowWords_Impl( nPos ); + } + else + { + m_xNewReplacePB->set_sensitive(false); + m_xDeletePB->set_sensitive(false); + } + + m_xWordED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl)); + m_xReplaceED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl)); +} + +IMPL_LINK_NOARG(SvxEditDictionaryDialog, EntrySizeAllocHdl, const Size&, void) +{ + std::vector<int> aWidths; + int x, y, width, height; + if (m_xReplaceED->get_extents_relative_to(*m_pWordsLB, x, y, width, height)) + { + aWidths.push_back(x); + m_xDoubleColumnLB->set_column_fixed_widths(aWidths); + } +} + +SvxEditDictionaryDialog::~SvxEditDictionaryDialog() +{ +} + +void SvxEditDictionaryDialog::SetDicReadonly_Impl( + Reference< XDictionary > const &xDic ) +{ + // enable or disable new and delete button according to file attributes + bDicIsReadonly = true; + if (xDic.is()) + { + Reference< frame::XStorable > xStor( xDic, UNO_QUERY ); + if ( !xStor.is() // non persistent dictionary + || !xStor->hasLocation() // not yet persistent + || !xStor->isReadonly() ) + { + bDicIsReadonly = false; + } + } +} + +void SvxEditDictionaryDialog::SetLanguage_Impl(LanguageType nLanguage) +{ + // select language + m_xLangLB->set_active_id(nLanguage); +} + +int SvxEditDictionaryDialog::GetLBInsertPos(std::u16string_view rDicWord) +{ + IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag()); + const CollatorWrapper* pCollator = aIntlWrapper.getCollator(); + int j; + int nCount = m_pWordsLB->n_children(); + for (j = 0; j < nCount; ++j) + { + OUString aNormEntry( getNormDicEntry_Impl( rDicWord ) ); + sal_Int32 nCmpRes = pCollator-> + compareString( aNormEntry, getNormDicEntry_Impl( m_pWordsLB->get_text(j, 0) ) ); + if (nCmpRes < 0) + break; + } + + return j; +} + +void SvxEditDictionaryDialog::RemoveDictEntry(int nEntry) +{ + int nLBPos = m_xAllDictsLB->get_active(); + if (nEntry != -1 && nLBPos != -1) + { + OUString sTmpShort(m_pWordsLB->get_text(nEntry, 0)); + + Reference<XDictionary> xDic = aDics.getConstArray()[nLBPos]; + if (xDic->remove(sTmpShort)) // sal_True on success + { + m_pWordsLB->remove(nEntry); + SelectHdl(*m_pWordsLB); + } + } +} + +IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectBookHdl_Impl, weld::ComboBox&, void) +{ + int nPos = m_xAllDictsLB->get_active(); + if (nPos == -1) + return; + + m_xNewReplacePB->set_sensitive( false ); + m_xDeletePB->set_sensitive( false ); + // display dictionary + ShowWords_Impl( nPos ); + // enable or disable new and delete button according to file attributes + Reference< XDictionary > const & xDic = aDics[ nPos ]; + if (xDic.is()) + SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() ); + + SetDicReadonly_Impl(xDic); + bool bEnable = !IsDicReadonly_Impl(); + m_xLangFT->set_sensitive( bEnable ); + m_xLangLB->set_sensitive( bEnable ); +} + +IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectLangHdl_Impl, weld::ComboBox&, void) +{ + int nDicPos = m_xAllDictsLB->get_active(); + LanguageType nLang = m_xLangLB->get_active_id(); + Reference< XDictionary > const & xDic = aDics[ nDicPos ]; + LanguageType nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType(); + + if ( nLang == nOldLang ) + return; + + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Question, VclButtonsType::YesNo, + CuiResId(RID_CUISTR_CONFIRM_SET_LANGUAGE))); + OUString sTxt(xBox->get_primary_text()); + sTxt = sTxt.replaceFirst("%1", m_xAllDictsLB->get_active_text()); + xBox->set_primary_text(sTxt); + + if (xBox->run() == RET_YES) + { + xDic->setLocale( LanguageTag::convertToLocale( nLang ) ); + bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE; + + const OUString sName( + ::GetDicInfoStr( xDic->getName(), + LanguageTag( xDic->getLocale() ).getLanguageType(), + bNegativ ) ); + m_xAllDictsLB->remove(nDicPos); + m_xAllDictsLB->insert_text(nDicPos, sName); + m_xAllDictsLB->set_active(nDicPos); + } + else + SetLanguage_Impl( nOldLang ); +} + +void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId ) +{ + Reference< XDictionary > xDic = aDics.getConstArray()[ nId ]; + + weld::WaitObject aWait(m_xDialog.get()); + + m_xWordED->set_text(OUString()); + m_xReplaceED->set_text(OUString()); + + bool bIsNegative = xDic->getDictionaryType() != DictionaryType_POSITIVE; + bool bLangNone = LanguageTag( + xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE; + + // The label is "Replace By" only in negative dictionaries (forbidden + // words), otherwise "Grammar By" in language-specific dictionaries + // (where the optional second word is the sample word for + // the Hunspell based affixation/compounding of the new dictionary word) + if (bIsNegative) + { + m_xReplaceFT->set_label(sReplaceFT_Text); + } else if (!bLangNone) { + m_xReplaceFT->set_label(CuiResId(RID_CUISTR_OPT_GRAMMAR_BY)); + } + + if(bIsNegative || !bLangNone) + { + // make controls for replacement text active + if (!m_xReplaceFT->get_visible()) + { + m_xReplaceFT->show(); + m_xReplaceED->show(); + m_xSingleColumnLB->hide(); + m_xDoubleColumnLB->show(); + m_pWordsLB = m_xDoubleColumnLB.get(); + } + } + else + { + // deactivate controls for replacement text + if (m_xReplaceFT->get_visible()) + { + m_xReplaceFT->hide(); + m_xReplaceED->hide(); + m_xDoubleColumnLB->hide(); + m_xSingleColumnLB->show(); + m_pWordsLB = m_xSingleColumnLB.get(); + } + } + + m_pWordsLB->clear(); + + Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() ); + const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray(); + sal_Int32 nCount = aEntries.getLength(); + std::vector<OUString> aSortedDicEntries; + aSortedDicEntries.reserve(nCount); + for (sal_Int32 i = 0; i < nCount; i++) + { + OUString aStr = pEntry[i]->getDictionaryWord(); + if(!pEntry[i]->getReplacementText().isEmpty()) + { + aStr += "\t" + pEntry[i]->getReplacementText(); + } + aSortedDicEntries.push_back(aStr); + } + + IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag()); + const CollatorWrapper* pCollator = aIntlWrapper.getCollator(); + std::sort(aSortedDicEntries.begin(), aSortedDicEntries.end(), + [&] (OUString const & lhs, OUString const & rhs) + { + sal_Int32 nCmpRes = pCollator-> + compareString( getNormDicEntry_Impl(lhs), getNormDicEntry_Impl( rhs ) ); + return nCmpRes < 0; + }); + + m_pWordsLB->freeze(); // speed up insert + int nRow = 0; + for (OUString const & rStr : aSortedDicEntries) + { + m_pWordsLB->append_text(rStr.getToken(0, '\t')); + if (m_pWordsLB == m_xDoubleColumnLB.get()) + { + OUString sReplace = rStr.getToken(1, '\t'); + m_pWordsLB->set_text(nRow, sReplace, 1); + ++nRow; + } + } + m_pWordsLB->thaw(); + + if (m_pWordsLB->n_children()) + { + m_pWordsLB->select(0); + m_pWordsLB->set_cursor(0); + SelectHdl(*m_pWordsLB); + } +} + +IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, weld::TreeView&, rBox, void) +{ + if (bDoNothing) + return; + + int nEntry = rBox.get_selected_index(); + + if(!bFirstSelect) + { + if (nEntry != -1) + { + OUString sTmpShort(rBox.get_text(nEntry, 0)); + // without this the cursor is always at the beginning of a word, if the text + // is set over the ModifyHdl, although you're editing there at the moment + if (m_xWordED->get_text() != sTmpShort) + m_xWordED->set_text(sTmpShort); + if (&rBox == m_xDoubleColumnLB.get()) + m_xReplaceED->set_text(rBox.get_text(nEntry, 1)); + } + } + else + bFirstSelect = false; + + // entries in the list box should exactly correspond to those from the + // dictionary. Thus: + m_xNewReplacePB->set_sensitive(false); + m_xDeletePB->set_sensitive(nEntry != -1 && !IsDicReadonly_Impl()); +} + +IMPL_LINK(SvxEditDictionaryDialog, NewDelButtonHdl, weld::Button&, rBtn, void) +{ + NewDelHdl(&rBtn); +} + +IMPL_LINK(SvxEditDictionaryDialog, NewDelActionHdl, weld::Entry&, rDictEdit, bool) +{ + return NewDelHdl(&rDictEdit); +} + +bool SvxEditDictionaryDialog::NewDelHdl(const weld::Widget* pBtn) +{ + if (pBtn == m_xDeletePB.get()) + { + m_xWordED->set_text(""); + m_xReplaceED->set_text(""); + m_xDeletePB->set_sensitive(false); + + int nEntry = m_pWordsLB->get_selected_index(); + RemoveDictEntry(nEntry); // remove entry from dic and list-box + } + if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive()) + { + int nEntry = m_pWordsLB->get_selected_index(); + OUString aNewWord(fixSpace(m_xWordED->get_text())); + OUString sEntry(aNewWord); + OUString aReplaceStr(fixSpace(m_xReplaceED->get_text())); + + DictionaryError nAddRes = DictionaryError::UNKNOWN; + int nPos = m_xAllDictsLB->get_active(); + if (nPos != -1 && !aNewWord.isEmpty()) + { + DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index"); + Reference< XDictionary > const & xDic = aDics[ nPos ]; + if (xDic.is()) + { + // make changes in dic + + bool bIsNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE; + + OUString aRplcText; + if(!aReplaceStr.isEmpty()) + aRplcText = aReplaceStr; + + if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry + xDic->remove(m_pWordsLB->get_text(nEntry, 0)); + // if remove has failed the following add should fail too + // and thus a warning message should be triggered... + + nAddRes = linguistic::AddEntryToDic( xDic, + aNewWord, bIsNegEntry, + aRplcText, false ); + } + } + if (DictionaryError::NONE != nAddRes) + SvxDicError(m_xDialog.get(), nAddRes); + + if (DictionaryError::NONE == nAddRes && !sEntry.isEmpty()) + { + // insert new entry in list-box etc... + m_pWordsLB->freeze(); + + if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry + { + m_pWordsLB->set_text(nEntry, sEntry); + if (!aReplaceStr.isEmpty()) + m_pWordsLB->set_text(nEntry, aReplaceStr, 1); + } + else + { + nEntry = GetLBInsertPos(aNewWord); + m_pWordsLB->insert_text(nEntry, sEntry); + if(!aReplaceStr.isEmpty()) + m_pWordsLB->set_text(nEntry, aReplaceStr, 1); + } + + m_pWordsLB->thaw(); + m_pWordsLB->scroll_to_row(nEntry); + + // if the request came from the ReplaceEdit, give focus to the ShortEdit + if (m_xReplaceED->has_focus()) + m_xWordED->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_xWordED); + return true; +} + +IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, weld::Entry&, rEdt, void) +{ + OUString rEntry = rEdt.get_text(); + + sal_Int32 nWordLen = rEntry.getLength(); + const OUString& rRepString = fixSpace(m_xReplaceED->get_text()); + + bool bEnableNewReplace = false; + bool bEnableDelete = false; + OUString aNewReplaceText = sNew; + + if (&rEdt == m_xWordED.get()) + { + if(nWordLen>0) + { + bool bFound = false; + bool bTmpSelEntry=false; + CDE_RESULT eCmpRes = CDE_DIFFERENT; + + bool bDoubleColumn = m_pWordsLB == m_xDoubleColumnLB.get(); + + for (int i = 0, nCount = m_pWordsLB->n_children(); i < nCount; ++i) + { + OUString aTestStr(m_pWordsLB->get_text(i, 0)); + eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr ); + if(CDE_DIFFERENT != eCmpRes) + { + if(!rRepString.isEmpty()) + bFirstSelect = true; + bDoNothing=true; + m_pWordsLB->set_cursor(i); + bDoNothing=false; + if (bDoubleColumn) + m_xReplaceED->set_text(m_pWordsLB->get_text(i, 1)); + + if (CDE_SIMILAR == eCmpRes) + { + aNewReplaceText = sModify; + bEnableNewReplace = true; + } + bFound= true; + break; + } + else if(getNormDicEntry_Impl(aTestStr).indexOf( + getNormDicEntry_Impl( rEntry ) ) == 0 + && !bTmpSelEntry) + { + bDoNothing=true; + m_pWordsLB->scroll_to_row(i); + bDoNothing=false; + bTmpSelEntry=true; + + aNewReplaceText = sNew; + bEnableNewReplace = true; + } + } + + if(!bFound) + { + m_pWordsLB->unselect_all(); + aNewReplaceText = sNew; + bEnableNewReplace = true; + } + bEnableDelete = CDE_DIFFERENT != eCmpRes; + } + else if (m_pWordsLB->n_children() > 0) + { + bDoNothing=true; + m_pWordsLB->scroll_to_row(0); + bDoNothing=false; + } + } + else if(&rEdt == m_xReplaceED.get()) + { + OUString aReplaceText; + OUString aWordText; + int nFirstSel = m_pWordsLB->get_selected_index(); + if (nFirstSel != -1) // a m_pWordsLB entry is selected + { + aWordText = m_pWordsLB->get_text(nFirstSel, 0); + aReplaceText = m_pWordsLB->get_text(nFirstSel, 1); + + aNewReplaceText = sModify; + bEnableDelete = true; + } + bool bIsChange = + CDE_EQUAL != cmpDicEntry_Impl(fixSpace(m_xWordED->get_text()), aWordText) + || CDE_EQUAL != cmpDicEntry_Impl(fixSpace(m_xReplaceED->get_text()), aReplaceText); + if (!fixSpace(m_xWordED->get_text()).isEmpty() && bIsChange) + bEnableNewReplace = true; + } + + m_xNewReplacePB->set_label(aNewReplaceText); + m_xNewReplacePB->set_sensitive(bEnableNewReplace && !IsDicReadonly_Impl()); + m_xDeletePB->set_sensitive(bEnableDelete && !IsDicReadonly_Impl()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |