Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  optdict.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <editeng/unolingu.hxx>
#include <o3tl/safeint.hxx>
#include <svx/dialmgr.hxx>
#include <svx/ehdl.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, u"cui/ui/optnewdictionarydialog.ui"_ustr, u"OptNewDictionaryDialog"_ustr)
    , m_xNameEdit(m_xBuilder->weld_entry(u"nameedit"_ustr))
    , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"language"_ustr)))
    , m_xExceptBtn(m_xBuilder->weld_check_button(u"except"_ustr))
    , m_xOKBtn(m_xBuilder->weld_button(u"ok"_ustr))
{
    // 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, truetrue);
    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() );

    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;
    }

    Sequence< Reference< XDictionary >  > aDics;
    if (xDicList.is())
        aDics = xDicList->getDictionaries();

    if (std::any_of(aDics.begin(), aDics.end(),
                    [&sDict](auto& d) { return sDict.equalsIgnoreAsciiCase(d->getName()); }))
    {
        // 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
        SvxErrorContext aContext(ERRCTX_SVX_LINGU_DICTIONARY, OUString(), m_xDialog.get());
        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, u"cui/ui/editdictionarydialog.ui"_ustr, u"EditDictionaryDialog"_ustr)
    , sModify(CuiResId(STR_MODIFY))
    , bFirstSelect(false)
    , bDoNothing(false)
    , bDicIsReadonly(false)
    , m_xAllDictsLB(m_xBuilder->weld_combo_box(u"book"_ustr))
    , m_xLangFT(m_xBuilder->weld_label(u"lang_label"_ustr))
    , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"lang"_ustr)))
    , m_xWordED(m_xBuilder->weld_entry(u"word"_ustr))
    , m_xReplaceFT(m_xBuilder->weld_label(u"replace_label"_ustr))
    , m_xReplaceED(m_xBuilder->weld_entry(u"replace"_ustr))
    , m_xSingleColumnLB(m_xBuilder->weld_tree_view(u"words"_ustr))
    , m_xDoubleColumnLB(m_xBuilder->weld_tree_view(u"replaces"_ustr))
    , m_xNewReplacePB(m_xBuilder->weld_button(u"newreplace"_ustr))
    , m_xDeletePB(m_xBuilder->weld_button(u"delete"_ustr))
{
    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_selection_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
    m_xDoubleColumnLB->connect_selection_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
    OUString aLookUpEntry;
    for (auto& xDic : aDics)
    {
        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, truetrue );

    if (aDics.hasElements())
    {
        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[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[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() );
    std::vector<OUString> aSortedDicEntries;
    aSortedDicEntries.reserve(aEntries.getLength());
    for (auto& xDictionaryEntry : aEntries)
    {
        OUString aStr = xDictionaryEntry->getDictionaryWord();
        if (!xDictionaryEntry->getReplacementText().isEmpty())
        {
            aStr += "\t" + xDictionaryEntry->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
    for (OUString const & rStr : aSortedDicEntries)
    {
        sal_Int32 index = 0;
        m_pWordsLB->append_text(rStr.getToken(0, '\t', index));
        if (index != -1 && m_pWordsLB == m_xDoubleColumnLB.get())
        {
            OUString sReplace = rStr.getToken(0, '\t', index);
            m_pWordsLB->set_text(m_pWordsLB->n_children() - 1, sReplace, 1);
        }
    }
    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(u""_ustr);
        m_xReplaceED->set_text(u""_ustr);
        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 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 && !aNewWord.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, aNewWord);
                if (!aReplaceStr.isEmpty())
                    m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
            }
            else
            {
                nEntry = GetLBInsertPos(aNewWord);
                m_pWordsLB->insert_text(nEntry, aNewWord);
                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 aRepString = 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(!aRepString.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: */

Messung V0.5
C=93 H=90 G=91

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge