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

Quelle  dlistimp.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 <cppuhelper/factory.hxx>
#include <osl/file.hxx>
#include <tools/debug.hxx>
#include <tools/stream.hxx>
#include <tools/urlobj.hxx>
#include <unotools/useroptions.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/weak.hxx>
#include <unotools/localfilehelper.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/sequence.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
#include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <svtools/strings.hrc>
#include <unotools/resmgr.hxx>
#include <unotools/charclass.hxx>
#include <sal/log.hxx>
#include <utility>

#include "dlistimp.hxx"
#include "dicimp.hxx"
#include "lngopt.hxx"

using namespace osl;
using namespace com::sun::star;
using namespace com::sun::star::lang;
using namespace com::sun::star::uno;
using namespace com::sun::star::linguistic2;
using namespace linguistic;


static bool IsVers2OrNewer( const OUString& rFileURL, LanguageType& nLng, bool&&nbsp;bNeg, OUString& aDicName );

static void AddInternal( const uno::Reference< XDictionary > &rDic,
                         const OUString& rNew );
static void AddUserData( const uno::Reference< XDictionary > &rDic );


class DicEvtListenerHelper :
    public cppu::WeakImplHelper
    <
        XDictionaryEventListener
    >
{
    comphelper::OInterfaceContainerHelper3<XDictionaryListEventListener> aDicListEvtListeners;
    uno::Reference< XDictionaryList >       xMyDicList;

    sal_Int16                               nCondensedEvt;
    sal_Int16                               nNumCollectEvtListeners;

public:
    explicit DicEvtListenerHelper( uno::Reference< XDictionaryList > xDicList );
    virtual ~DicEvtListenerHelper() override;

    // XEventListener
    virtual void SAL_CALL
        disposing( const EventObject& rSource ) override;

    // XDictionaryEventListener
    virtual void SAL_CALL
        processDictionaryEvent( const DictionaryEvent& rDicEvent ) override;

    // non-UNO functions
    void    DisposeAndClear( const EventObject &rEvtObj );

    bool    AddDicListEvtListener(
                const uno::Reference< XDictionaryListEventListener >& rxListener );
    bool    RemoveDicListEvtListener(
                const uno::Reference< XDictionaryListEventListener >& rxListener );
    sal_Int16   BeginCollectEvents() { return ++nNumCollectEvtListeners;}
    sal_Int16   EndCollectEvents();
    sal_Int16   FlushEvents();
    void    ClearEvents()   { nCondensedEvt = 0; }
};


DicEvtListenerHelper::DicEvtListenerHelper(
        uno::Reference< XDictionaryList > xDicList ) :
    aDicListEvtListeners    ( GetLinguMutex() ),
    xMyDicList              (std::move( xDicList )),
    nCondensedEvt(0), nNumCollectEvtListeners(0)
{
}


DicEvtListenerHelper::~DicEvtListenerHelper()
{
    DBG_ASSERT(aDicListEvtListeners.getLength() == 0,
        "lng : event listeners are still existing");
}


void DicEvtListenerHelper::DisposeAndClear( const EventObject &rEvtObj )
{
    aDicListEvtListeners.disposeAndClear( rEvtObj );
}


void SAL_CALL DicEvtListenerHelper::disposing( const EventObject& rSource )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    uno::Reference< XDictionaryListEventListener > xSrc( rSource.Source, UNO_QUERY );

    // remove event object from EventListener list
    if (xSrc.is())
        aDicListEvtListeners.removeInterface( xSrc );

    // if object is a dictionary then remove it from the dictionary list
    // Note: this will probably happen only if someone makes a XDictionary
    // implementation of his own that is also a XComponent.
    uno::Reference< XDictionary > xDic( rSource.Source, UNO_QUERY );
    if (xDic.is())
    {
        xMyDicList->removeDictionary( xDic );
    }
}


void SAL_CALL DicEvtListenerHelper::processDictionaryEvent(
            const DictionaryEvent& rDicEvent )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    uno::Reference< XDictionary > xDic( rDicEvent.Source, UNO_QUERY );
    DBG_ASSERT(xDic.is(), "lng : missing event source");

    // assert that there is a corresponding dictionary entry if one was
    // added or deleted
    DBG_ASSERT( !(rDicEvent.nEvent &
                    (DictionaryEventFlags::ADD_ENTRY | DictionaryEventFlags::DEL_ENTRY))
                || rDicEvent.xDictionaryEntry.is(),
                "lng : missing dictionary entry" );

    // evaluate DictionaryEvents and update data for next DictionaryListEvent
    DictionaryType eDicType = xDic->getDictionaryType();
    DBG_ASSERT(eDicType != DictionaryType_MIXED,
        "lng : unexpected dictionary type");
    if ((rDicEvent.nEvent & DictionaryEventFlags::ADD_ENTRY) && xDic->isActive())
        nCondensedEvt |= rDicEvent.xDictionaryEntry->isNegative() ?
            DictionaryListEventFlags::ADD_NEG_ENTRY :
            DictionaryListEventFlags::ADD_POS_ENTRY;
    if ((rDicEvent.nEvent & DictionaryEventFlags::DEL_ENTRY) && xDic->isActive())
        nCondensedEvt |= rDicEvent.xDictionaryEntry->isNegative() ?
            DictionaryListEventFlags::DEL_NEG_ENTRY :
            DictionaryListEventFlags::DEL_POS_ENTRY;
    if ((rDicEvent.nEvent & DictionaryEventFlags::ENTRIES_CLEARED) && xDic->isActive())
        nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
            DictionaryListEventFlags::DEL_NEG_ENTRY :
            DictionaryListEventFlags::DEL_POS_ENTRY;
    if ((rDicEvent.nEvent & DictionaryEventFlags::CHG_LANGUAGE) && xDic->isActive())
        nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
            DictionaryListEventFlags::DEACTIVATE_NEG_DIC
                | DictionaryListEventFlags::ACTIVATE_NEG_DIC :
            DictionaryListEventFlags::DEACTIVATE_POS_DIC
                | DictionaryListEventFlags::ACTIVATE_POS_DIC;
    if (rDicEvent.nEvent & DictionaryEventFlags::ACTIVATE_DIC)
        nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
            DictionaryListEventFlags::ACTIVATE_NEG_DIC :
            DictionaryListEventFlags::ACTIVATE_POS_DIC;
    if (rDicEvent.nEvent & DictionaryEventFlags::DEACTIVATE_DIC)
        nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
            DictionaryListEventFlags::DEACTIVATE_NEG_DIC :
            DictionaryListEventFlags::DEACTIVATE_POS_DIC;

    if (nNumCollectEvtListeners == 0 && nCondensedEvt != 0)
        FlushEvents();
}


bool DicEvtListenerHelper::AddDicListEvtListener(
            const uno::Reference< XDictionaryListEventListener >& xListener )
{
    DBG_ASSERT( xListener.is(), "empty reference" );
    sal_Int32   nCount = aDicListEvtListeners.getLength();
    return aDicListEvtListeners.addInterface( xListener ) != nCount;
}


bool DicEvtListenerHelper::RemoveDicListEvtListener(
            const uno::Reference< XDictionaryListEventListener >& xListener )
{
    DBG_ASSERT( xListener.is(), "empty reference" );
    sal_Int32   nCount = aDicListEvtListeners.getLength();
    return aDicListEvtListeners.removeInterface( xListener ) != nCount;
}


sal_Int16 DicEvtListenerHelper::EndCollectEvents()
{
    DBG_ASSERT(nNumCollectEvtListeners > 0, "lng: mismatched function call");
    if (nNumCollectEvtListeners > 0)
    {
        FlushEvents();
        nNumCollectEvtListeners--;
    }

    return nNumCollectEvtListeners;
}


sal_Int16 DicEvtListenerHelper::FlushEvents()
{
    if (0 != nCondensedEvt)
    {
        // build DictionaryListEvent to pass on to listeners
        uno::Sequence< DictionaryEvent > aDicEvents;
        DictionaryListEvent aEvent( xMyDicList, nCondensedEvt, aDicEvents );

        // pass on event
        aDicListEvtListeners.notifyEach( &XDictionaryListEventListener::processDictionaryListEvent, aEvent );

        // clear "list" of events
        nCondensedEvt = 0;
    }

    return nNumCollectEvtListeners;
}


void DicList::MyAppExitListener::AtExit()
{
    rMyDicList.SaveDics();
}


DicList::DicList() :
    aEvtListeners   ( GetLinguMutex() )
{
    mxDicEvtLstnrHelper  = new DicEvtListenerHelper( this );
    bDisposing = false;
    bInCreation = false;

    mxExitListener = new MyAppExitListener( *this );
    mxExitListener->Activate();
}

DicList::~DicList()
{
    mxExitListener->Deactivate();
}


void DicList::SearchForDictionaries(
    DictionaryVec_t&rDicList,
    const OUString &rDicDirURL,
    bool bIsWriteablePath )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    const uno::Sequence< OUString > aDirCnt( utl::LocalFileHelper::
                                        GetFolderContents( rDicDirURL, false ) );
    SvtSysLocale aSysLocale;

    for (const OUString& aURL : aDirCnt)
    {
        LanguageType nLang = LANGUAGE_NONE;
        bool         bNeg  = false;
        OUString     aDicTitle = u""_ustr;

        if(!::IsVers2OrNewer( aURL, nLang, bNeg, aDicTitle ))
        {
            // When not
            sal_Int32 nPos  = aURL.indexOf('.');
            OUString aExt( aURL.copy(nPos + 1).toAsciiLowerCase() );

            if ("dcn" == aExt)       // negative
                bNeg = true;
            else if ("dcp" == aExt)  // positive
                bNeg = false;
            else
                continue;          // other files
        }

        // Record in the list of Dictionaries
        // When it already exists don't record
        OUString aTmp1 = aSysLocale.GetCharClass().lowercase( aURL);
        sal_Int32 nPos = aTmp1.lastIndexOf( '/' );
        if (-1 != nPos)
            aTmp1 = aTmp1.copy( nPos + 1 );
        OUString aTmp2;
        size_t j;
        size_t nCount = rDicList.size();
        for(j = 0;  j < nCount;  j++)
        {
            aTmp2 = rDicList[j]->getName();
            aTmp2 = aSysLocale.GetCharClass().lowercase( aTmp2);
            if(aTmp1 == aTmp2)
                break;
        }
        if(j >= nCount)     // dictionary not yet in DicList
        {
            // get decoded dictionary file name
            INetURLObject aURLObj( aURL );
            OUString aDicName = aURLObj.getName( INetURLObject::LAST_SEGMENT,
                        true, INetURLObject::DecodeMechanism::WithCharset );

            DictionaryType eType = bNeg ? DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
            uno::Reference< XDictionary > xDic =
                        new DictionaryNeo( aDicTitle.isEmpty() ? aDicName : aDicTitle, nLang, eType, aURL, bIsWriteablePath );

            // when using libreofficekit we don't have "options" dialog to make user-dictionaries active
            // so when we add user-dictionary, we make them active as well
            if (comphelper::LibreOfficeKit::isActive())
                xDic->setActive(true);

            addDictionary( xDic );
            nCount++;
        }
    }
}


sal_Int32 DicList::GetDicPos(const uno::Reference< XDictionary > &xDic)
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    DictionaryVec_t& rDicList = GetOrCreateDicList();
    size_t n = rDicList.size();
    for (size_t i = 0;  i < n;  i++)
    {
        if ( rDicList[i] == xDic )
            return i;
    }
    return -1;
}

sal_Int16 SAL_CALL DicList::getCount()
{
    osl::MutexGuard aGuard( GetLinguMutex() );
    return static_cast< sal_Int16 >(GetOrCreateDicList().size());
}

uno::Sequence< uno::Reference< XDictionary > > SAL_CALL
        DicList::getDictionaries()
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    DictionaryVec_t& rDicList = GetOrCreateDicList();

    return comphelper::containerToSequence(rDicList);
}

uno::Reference< XDictionary > SAL_CALL
        DicList::getDictionaryByName( const OUString& aDictionaryName )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    uno::Reference< XDictionary > xDic;
    DictionaryVec_t& rDicList = GetOrCreateDicList();
    size_t nCount = rDicList.size();
    for (size_t i = 0;  i < nCount;  i++)
    {
        const uno::Reference< XDictionary > &rDic = rDicList[i];
        if (rDic.is()  &&  rDic->getName() == aDictionaryName)
        {
            xDic = rDic;
            break;
        }
    }

    return xDic;
}

sal_Bool SAL_CALL DicList::addDictionary(
            const uno::Reference< XDictionary >& xDictionary )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (bDisposing)
        return false;

    bool bRes = false;
    if (xDictionary.is())
    {
        DictionaryVec_t& rDicList = GetOrCreateDicList();
        rDicList.push_back( xDictionary );
        bRes = true;

        // add listener helper to the dictionaries listener lists
        xDictionary->addDictionaryEventListener( mxDicEvtLstnrHelper );
    }
    return bRes;
}

sal_Bool SAL_CALL
    DicList::removeDictionary( const uno::Reference< XDictionary >& xDictionary )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (bDisposing)
        return false;

    bool  bRes = false;
    sal_Int32 nPos = GetDicPos( xDictionary );
    if (nPos >= 0)
    {
        // remove dictionary list from the dictionaries listener lists
        DictionaryVec_t& rDicList = GetOrCreateDicList();
        uno::Reference< XDictionary > xDic( rDicList[ nPos ] );
        DBG_ASSERT(xDic.is(), "lng : empty reference");
        if (xDic.is())
        {
            // deactivate dictionary if not already done
            xDic->setActive( false );

            xDic->removeDictionaryEventListener( mxDicEvtLstnrHelper );
        }

        // remove element at nPos
        rDicList.erase( rDicList.begin() + nPos );
        bRes = true;
    }
    return bRes;
}

sal_Bool SAL_CALL DicList::addDictionaryListEventListener(
            const uno::Reference< XDictionaryListEventListener >& xListener,
            sal_Bool bReceiveVerbose )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (bDisposing)
        return false;

    DBG_ASSERT(!bReceiveVerbose, "lng : not yet supported");

    bool bRes = false;
    if (xListener.is()) //! don't add empty references
    {
        bRes = mxDicEvtLstnrHelper->AddDicListEvtListener( xListener );
    }
    return bRes;
}

sal_Bool SAL_CALL DicList::removeDictionaryListEventListener(
            const uno::Reference< XDictionaryListEventListener >& xListener )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (bDisposing)
        return false;

    bool bRes = false;
    if(xListener.is())
    {
        bRes = mxDicEvtLstnrHelper->RemoveDicListEvtListener( xListener );
    }
    return bRes;
}

sal_Int16 SAL_CALL DicList::beginCollectEvents()
{
    osl::MutexGuard aGuard( GetLinguMutex() );
    return mxDicEvtLstnrHelper->BeginCollectEvents();
}

sal_Int16 SAL_CALL DicList::endCollectEvents()
{
    osl::MutexGuard aGuard( GetLinguMutex() );
    return mxDicEvtLstnrHelper->EndCollectEvents();
}

sal_Int16 SAL_CALL DicList::flushEvents()
{
    osl::MutexGuard aGuard( GetLinguMutex() );
    return mxDicEvtLstnrHelper->FlushEvents();
}

uno::Reference< XDictionary > SAL_CALL
    DicList::createDictionary( const OUString& rName, const Locale& rLocale,
            DictionaryType eDicType, const OUString& rURL )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    LanguageType nLanguage = LinguLocaleToLanguage( rLocale );
    bool bIsWriteablePath = rURL.match( GetDictionaryWriteablePath() );
    return new DictionaryNeo( rName, nLanguage, eDicType, rURL, bIsWriteablePath );
}


uno::Reference< XDictionaryEntry > SAL_CALL
    DicList::queryDictionaryEntry( const OUString& rWord, const Locale& rLocale,
            sal_Bool bSearchPosDics, sal_Bool bSearchSpellEntry )
{
    osl::MutexGuard aGuard( GetLinguMutex() );
    return SearchDicList( this, rWord, LinguLocaleToLanguage( rLocale ),
                            bSearchPosDics, bSearchSpellEntry );
}


void SAL_CALL
    DicList::dispose()
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (bDisposing)
        return;

    bDisposing = true;
    EventObject aEvtObj( static_cast<XDictionaryList *>(this) );

    aEvtListeners.disposeAndClear( aEvtObj );
    if (mxDicEvtLstnrHelper.is())
        mxDicEvtLstnrHelper->DisposeAndClear( aEvtObj );

    //! avoid creation of dictionaries if not already done
    if ( !aDicList.empty() )
    {
        DictionaryVec_t& rDicList = GetOrCreateDicList();
        size_t nCount = rDicList.size();
        for (size_t i = 0;  i < nCount;  i++)
        {
            // save (modified) dictionaries
            uno::Reference< frame::XStorable >  xStor( rDicList[i] , UNO_QUERY );
            if (xStor.is())
            {
                try
                {
                    if (!xStor->isReadonly() && xStor->hasLocation())
                        xStor->store();
                }
                catch(Exception &)
                {
                }
            }

            // release references to (members of) this object hold by
            // dictionaries
            if (rDicList[i].is())
                rDicList[i]->removeDictionaryEventListener( mxDicEvtLstnrHelper );
        }
    }
    mxDicEvtLstnrHelper.clear();
}

void SAL_CALL
    DicList::addEventListener( const uno::Reference< XEventListener >& rxListener )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (!bDisposing && rxListener.is())
        aEvtListeners.addInterface( rxListener );
}

void SAL_CALL
    DicList::removeEventListener( const uno::Reference< XEventListener >& rxListener )
{
    osl::MutexGuard aGuard( GetLinguMutex() );

    if (!bDisposing && rxListener.is())
        aEvtListeners.removeInterface( rxListener );
}

void SAL_CALL DicList::initialize(const css::uno::Sequence<css::uno::Any>& /*rArguments*/)
{
    osl::MutexGuard aGuard(GetLinguMutex());

    if (!bInCreation && !bDisposing)
    {
        CreateDicList();
    }
}

void DicList::CreateDicList()
{
    bInCreation = true;

    // look for dictionaries
    const OUString aWriteablePath( GetDictionaryWriteablePath() );
    std::vector< OUString > aPaths( GetDictionaryPaths() );
    for (const OUString & aPath : aPaths)
    {
        const bool bIsWriteablePath = (aPath == aWriteablePath);
        SearchForDictionaries( aDicList, aPath, bIsWriteablePath );
    }

    // create IgnoreAllList dictionary with empty URL (non persistent)
    // and add it to list
    const LanguageTag tag = comphelper::LibreOfficeKit::isActive()
                                ? LanguageTag(u"en-US"_ustr)
                                : SvtSysLocale().GetUILanguageTag();
    std::locale loc(Translate::Create("svt", tag));
    uno::Reference< XDictionary > xIgnAll(
            createDictionary( Translate::get(STR_DESCRIPTION_IGNOREALLLIST, loc), LinguLanguageToLocale( LANGUAGE_NONE ),
                              DictionaryType_POSITIVE, OUString() ) );
    if (xIgnAll.is())
    {
        AddUserData( xIgnAll );
        xIgnAll->setActive( true );
        addDictionary( xIgnAll );
    }


    // evaluate list of dictionaries to be activated from configuration
    //! to suppress overwriting the list of active dictionaries in the
    //! configuration with incorrect arguments during the following
    //! activation of the dictionaries
    mxDicEvtLstnrHelper->BeginCollectEvents();
    const uno::Sequence< OUString > aActiveDics( aOpt.GetActiveDics() );
    for (const OUString& rActiveDic : aActiveDics)
    {
        if (!rActiveDic.isEmpty())
        {
            uno::Reference< XDictionary > xDic( getDictionaryByName( rActiveDic ) );
            if (xDic.is())
                xDic->setActive( true );
        }
    }

    // suppress collected events during creation of the dictionary list.
    // there should be no events during creation.
    mxDicEvtLstnrHelper->ClearEvents();

    mxDicEvtLstnrHelper->EndCollectEvents();

    bInCreation = false;
}


void DicList::SaveDics()
{
    // save dics only if they have already been used/created.
    //! don't create them just for the purpose of saving them !
    if ( aDicList.empty() )
        return;

    // save (modified) dictionaries
    DictionaryVec_t& rDicList = GetOrCreateDicList();
    size_t nCount = rDicList.size();
    for (size_t i = 0;  i < nCount;  i++)
    {
        // save (modified) dictionaries
        uno::Reference< frame::XStorable >  xStor( rDicList[i], UNO_QUERY );
        if (xStor.is())
        {
            try
            {
                if (!xStor->isReadonly() && xStor->hasLocation())
                    xStor->store();
            }
            catch(Exception &)
            {
            }
        }
    }
}


// Service specific part

OUString SAL_CALL DicList::getImplementationName(  )
{
    return u"com.sun.star.lingu2.DicList"_ustr;
}


sal_Bool SAL_CALL DicList::supportsService( const OUString& ServiceName )
{
    return cppu::supportsService(this, ServiceName);
}

uno::Sequence< OUString > SAL_CALL DicList::getSupportedServiceNames(  )
{
    return { u"com.sun.star.linguistic2.DictionaryList"_ustr };
}



static sal_Int32 lcl_GetToken( OUString &rToken,
            const OUString &rText, sal_Int32 nPos, std::u16string_view rDelim )
{
    sal_Int32 nRes = -1;

    if (rText.isEmpty() ||  nPos >= rText.getLength())
        rToken.clear();
    else if (rDelim.empty())
    {
        rToken = rText;
        if (!rToken.isEmpty())
            nRes = rText.getLength();
    }
    else
    {
        sal_Int32 i;
        for (i = nPos; i < rText.getLength(); ++i)
        {
            if (std::string_view::npos != rDelim.find( rText[i] ))
                break;
        }

        if (i >= rText.getLength())   // delimiter not found
            rToken  = rText.copy( nPos );
        else
            rToken  = rText.copy( nPos, i - nPos );
        nRes    = i + 1;    // continue after found delimiter
    }

    return nRes;
}


static void AddInternal(
        const uno::Reference<XDictionary> &rDic,
        const OUString& rNew )
{
    if (!rDic.is())
        return;

    //! TL TODO: word iterator should be used to break up the text
    OUString aDelim(u"!\"#$%&'()*+,-/:;<=>?[]\\_^`{|}~\t \n"_ustr);
    OSL_ENSURE(aDelim.indexOf(u'.') == -1,
        "ensure no '.'");

    OUString      aToken;
    sal_Int32 nPos = 0;
    while (-1 != (nPos = lcl_GetToken( aToken, rNew, nPos, aDelim )))
    {
        if( !aToken.isEmpty()  &&  !IsNumeric( aToken ) )
        {
            rDic->add( aToken, false, OUString() );
        }
    }
}

static void AddUserData( const uno::Reference< XDictionary > &rDic )
{
    if (rDic.is())
    {
        SvtUserOptions aUserOpt;
        AddInternal( rDic, aUserOpt.GetFullName() );
        AddInternal( rDic, aUserOpt.GetCompany() );
        AddInternal( rDic, aUserOpt.GetStreet() );
        AddInternal( rDic, aUserOpt.GetCity() );
        AddInternal( rDic, aUserOpt.GetTitle() );
        AddInternal( rDic, aUserOpt.GetPosition() );
        AddInternal( rDic, aUserOpt.GetEmail() );
    }
}

static bool IsVers2OrNewer( const OUString& rFileURL, LanguageType& nLng, bool&&nbsp;bNeg, OUString& aDicName )
{
    if (rFileURL.isEmpty())
        return false;
    OUString aExt;
    sal_Int32 nPos = rFileURL.lastIndexOf( '.' );
    if (-1 != nPos)
        aExt = rFileURL.copy( nPos + 1 ).toAsciiLowerCase();

    if (aExt != "dic")
        return false;

    // get stream to be used
    const uno::Reference< uno::XComponentContext >& xContext( comphelper::getProcessComponentContext() );

    // get XInputStream stream
    uno::Reference< io::XInputStream > xStream;
    try
    {
        uno::Reference< ucb::XSimpleFileAccess3 > xAccess( ucb::SimpleFileAccess::create(xContext) );
        xStream = xAccess->openFileRead( rFileURL );
    }
    catch (const uno::Exception &)
    {
        SAL_WARN( "linguistic""failed to get input stream" );
    }
    DBG_ASSERT( xStream.is(), "failed to get stream for read" );
    if (!xStream.is())
        return false;

    std::unique_ptr<SvStream> pStream( utl::UcbStreamHelper::CreateStream( xStream ) );

    int nDicVersion = ReadDicVersion(*pStream, nLng, bNeg, aDicName);
    return 2 == nDicVersion || nDicVersion >= 5;
}

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
linguistic_DicList_get_implementation(
    css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
{
    return cppu::acquire(new DicList());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

¤ Dauer der Verarbeitung: 0.14 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.