diff options
Diffstat (limited to 'linguistic/workben')
-rw-r--r-- | linguistic/workben/exports.dxp | 2 | ||||
-rw-r--r-- | linguistic/workben/makefile.mk | 98 | ||||
-rw-r--r-- | linguistic/workben/sprophelp.cxx | 387 | ||||
-rw-r--r-- | linguistic/workben/sprophelp.hxx | 155 | ||||
-rw-r--r-- | linguistic/workben/sreg.cxx | 63 | ||||
-rw-r--r-- | linguistic/workben/sspellimp.cxx | 476 | ||||
-rw-r--r-- | linguistic/workben/sspellimp.hxx | 157 |
7 files changed, 1338 insertions, 0 deletions
diff --git a/linguistic/workben/exports.dxp b/linguistic/workben/exports.dxp new file mode 100644 index 0000000000..86214860d5 --- /dev/null +++ b/linguistic/workben/exports.dxp @@ -0,0 +1,2 @@ +component_getFactory +component_writeInfo diff --git a/linguistic/workben/makefile.mk b/linguistic/workben/makefile.mk new file mode 100644 index 0000000000..5b94668170 --- /dev/null +++ b/linguistic/workben/makefile.mk @@ -0,0 +1,98 @@ +# +# 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 . +# + +PRJ = .. + +PRJNAME = linguistic +TARGET = lex +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE + +#----- Settings --------------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +UNOTYPES=\ + com.sun.star.linguistic2.DictionaryEvent\ + com.sun.star.linguistic2.DictionaryEventFlags\ + com.sun.star.linguistic2.DictionaryListEvent\ + com.sun.star.linguistic2.DictionaryListEventFlags\ + com.sun.star.linguistic2.DictionaryType\ + com.sun.star.linguistic2.LinguServiceEventFlags\ + com.sun.star.linguistic2.SpellFailure\ + com.sun.star.linguistic2.XDictionary\ + com.sun.star.linguistic2.XDictionary1\ + com.sun.star.linguistic2.XDictionaryEntry\ + com.sun.star.linguistic2.XDictionaryEventListener\ + com.sun.star.linguistic2.XDictionaryList\ + com.sun.star.linguistic2.XDictionaryListEventListener\ + com.sun.star.linguistic2.XHyphenatedWord\ + com.sun.star.linguistic2.XHyphenator\ + com.sun.star.linguistic2.XLinguServiceEventBroadcaster\ + com.sun.star.linguistic2.XLinguServiceEventListener\ + com.sun.star.linguistic2.XLinguServiceManager\ + com.sun.star.linguistic2.XMeaning\ + com.sun.star.linguistic2.XPossibleHyphens\ + com.sun.star.linguistic2.XSearchableDictionaryList\ + com.sun.star.linguistic2.XSpellAlternatives\ + com.sun.star.linguistic2.XSpellChecker\ + com.sun.star.linguistic2.XSupportedLocales\ + com.sun.star.linguistic2.XThesaurus + + +SLOFILES= \ + $(SLO)$/sprophelp.obj\ + $(SLO)$/sreg.obj\ + $(SLO)$/sspellimp.obj + + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX) + +SHL1STDLIBS= \ + $(COMPHELPERLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(TOOLSLIB) \ + $(SVTOOLLIB) \ + $(SVLLIB) \ + $(VCLLIB) \ + $(SFXLIB) \ + $(SALLIB) \ + $(UCBHELPERLIB) \ + $(UNOTOOLSLIB) \ + $(LNGLIB) + +# build DLL +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1IMPLIB= i$(TARGET) +SHL1DEPN= $(SHL1LIBS) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +.IF "$(OS)"!="MACOSX" +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +.ENDIF + +# build DEF file +DEF1NAME =$(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/linguistic/workben/sprophelp.cxx b/linguistic/workben/sprophelp.cxx new file mode 100644 index 0000000000..9da626319a --- /dev/null +++ b/linguistic/workben/sprophelp.cxx @@ -0,0 +1,387 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sal/macros.h> +#include "linguistic/misc.hxx" + +#include "sprophelp.hxx" +#include "linguistic/lngprops.hxx" + +#include <com/sun/star/linguistic2/LinguServiceEvent.hpp> +#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp> +#include <com/sun/star/linguistic2/XLinguServiceEventListener.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <osl/mutex.hxx> + +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::linguistic2; +using namespace linguistic; + + +PropertyChgHelper::PropertyChgHelper( + const Reference< XInterface > & rxSource, + Reference< XPropertySet > &rxPropSet, + const char *pPropNames[], sal_uInt16 nPropCount ) + : aPropNames(nPropCount) + , xMyEvtObj(rxSource) + , aLngSvcEvtListeners(GetLinguMutex()) + , xPropSet(rxPropSet) +{ + OUString *pName = aPropNames.getArray(); + for (sal_Int32 i = 0; i < nPropCount; ++i) + { + pName[i] = OUString::createFromAscii( pPropNames[i] ); + } +} + + +PropertyChgHelper::PropertyChgHelper( const PropertyChgHelper &rHelper ) : + aPropNames(rHelper.aPropNames), + xMyEvtObj(rHelper.xMyEvtObj), + aLngSvcEvtListeners (GetLinguMutex()), + xPropSet(rHelper.xPropSet) +{ + AddAsPropListener(); + +} + + +PropertyChgHelper::~PropertyChgHelper() +{ +} + + +void PropertyChgHelper::AddAsPropListener() +{ + if (xPropSet.is()) + { + sal_Int32 nLen = aPropNames.getLength(); + const OUString *pPropName = aPropNames.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + if (pPropName[i].getLength()) + xPropSet->addPropertyChangeListener( pPropName[i], this ); + } + } +} + +void PropertyChgHelper::RemoveAsPropListener() +{ + if (xPropSet.is()) + { + sal_Int32 nLen = aPropNames.getLength(); + const OUString *pPropName = aPropNames.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + if (pPropName[i].getLength()) + xPropSet->removePropertyChangeListener( pPropName[i], this ); + } + } +} + + +void PropertyChgHelper::LaunchEvent( const LinguServiceEvent &rEvt ) +{ + cppu::OInterfaceIteratorHelper aIt( aLngSvcEvtListeners ); + while (aIt.hasMoreElements()) + { + Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->processLinguServiceEvent( rEvt ); + } +} + + +void SAL_CALL PropertyChgHelper::disposing( const EventObject& rSource ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + if (rSource.Source == xPropSet) + { + RemoveAsPropListener(); + xPropSet = NULL; + aPropNames.realloc( 0 ); + } +} + + +sal_Bool SAL_CALL + PropertyChgHelper::addLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (rxListener.is()) + { + sal_Int32 nCount = aLngSvcEvtListeners.getLength(); + bRes = aLngSvcEvtListeners.addInterface( rxListener ) != nCount; + } + return bRes; +} + + +sal_Bool SAL_CALL + PropertyChgHelper::removeLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (rxListener.is()) + { + sal_Int32 nCount = aLngSvcEvtListeners.getLength(); + bRes = aLngSvcEvtListeners.removeInterface( rxListener ) != nCount; + } + return bRes; +} + + +static const char *aSP[] = +{ + UPN_IS_GERMAN_PRE_REFORM, + UPN_IS_IGNORE_CONTROL_CHARACTERS, + UPN_IS_USE_DICTIONARY_LIST, + UPN_IS_SPELL_UPPER_CASE, + UPN_IS_SPELL_WITH_DIGITS, + UPN_IS_SPELL_CAPITALIZATION, + UPN_IS_SPELL_CLOSED_COMPOUND, + UPN_IS_SPELL_HYPHENATED_COMPOUND +}; + + +PropertyHelper_Spell::PropertyHelper_Spell( + const Reference< XInterface > & rxSource, + Reference< XPropertySet > &rxPropSet ) : + PropertyChgHelper ( rxSource, rxPropSet, aSP, SAL_N_ELEMENTS(aSP) ) +{ + SetDefault(); + sal_Int32 nLen = GetPropNames().getLength(); + if (rxPropSet.is() && nLen) + { + const OUString *pPropName = GetPropNames().getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + sal_Bool *pbVal = NULL, + *pbResVal = NULL; + + if (OUString( UPN_IS_GERMAN_PRE_REFORM ) == pPropName[i]) + { + pbVal = &bIsGermanPreReform; + pbResVal = &bResIsGermanPreReform; + } + else if (OUString( UPN_IS_IGNORE_CONTROL_CHARACTERS ) == pPropName[i]) + { + pbVal = &bIsIgnoreControlCharacters; + pbResVal = &bResIsIgnoreControlCharacters; + } + else if (OUString( UPN_IS_USE_DICTIONARY_LIST ) == pPropName[i]) + { + pbVal = &bIsUseDictionaryList; + pbResVal = &bResIsUseDictionaryList; + } + else if (OUString( UPN_IS_SPELL_UPPER_CASE ) == pPropName[i]) + { + pbVal = &bIsSpellUpperCase; + pbResVal = &bResIsSpellUpperCase; + } + else if (OUString( UPN_IS_SPELL_WITH_DIGITS ) == pPropName[i]) + { + pbVal = &bIsSpellWithDigits; + pbResVal = &bResIsSpellWithDigits; + } + else if (OUString( UPN_IS_SPELL_CAPITALIZATION ) == pPropName[i]) + { + pbVal = &bIsSpellCapitalization; + pbResVal = &bResIsSpellCapitalization; + } + else if (OUString( UPN_IS_SPELL_CLOSED_COMPOUND ) == pPropName[i]) + { + pbVal = &bIsSpellClosedCompound; + pbResVal = &bResIsSpellClosedCompound; + } + else if (OUString( UPN_IS_SPELL_HYPHENATED_COMPOUND ) == pPropName[i]) + { + pbVal = &bIsSpellHyphenatedCompound; + pbResVal = &bResIsSpellHyphenatedCompound; + } + + if (pbVal && pbResVal) + { + rxPropSet->getPropertyValue( pPropName[i] ) >>= *pbVal; + *pbResVal = *pbVal; + } + } + } +} + + +PropertyHelper_Spell::~PropertyHelper_Spell() +{ +} + + +void PropertyHelper_Spell::SetDefault() +{ + bResIsGermanPreReform = bIsGermanPreReform = sal_False; + bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters = sal_True; + bResIsUseDictionaryList = bIsUseDictionaryList = sal_True; + bResIsSpellUpperCase = bIsSpellUpperCase = sal_False; + bResIsSpellWithDigits = bIsSpellWithDigits = sal_False; + bResIsSpellCapitalization = bIsSpellCapitalization = sal_True; + bResIsSpellClosedCompound = bIsSpellClosedCompound = sal_True; + bResIsSpellHyphenatedCompound = bIsSpellHyphenatedCompound = sal_True; +} + + +void SAL_CALL + PropertyHelper_Spell::propertyChange( const PropertyChangeEvent& rEvt ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (GetPropSet().is() && rEvt.Source == GetPropSet()) + { + sal_Int16 nLngSvcFlags = 0; + sal_Bool bSCWA = sal_False, // SPELL_CORRECT_WORDS_AGAIN ? + bSWWA = sal_False; // SPELL_WRONG_WORDS_AGAIN ? + + sal_Bool *pbVal = NULL; + switch (rEvt.PropertyHandle) + { + case UPH_IS_IGNORE_CONTROL_CHARACTERS : + { + pbVal = &bIsIgnoreControlCharacters; + break; + } + case UPH_IS_GERMAN_PRE_REFORM : + { + pbVal = &bIsGermanPreReform; + bSCWA = bSWWA = sal_True; + break; + } + case UPH_IS_USE_DICTIONARY_LIST : + { + pbVal = &bIsUseDictionaryList; + bSCWA = bSWWA = sal_True; + break; + } + case UPH_IS_SPELL_UPPER_CASE : + { + pbVal = &bIsSpellUpperCase; + bSCWA = sal_False == *pbVal; // sal_False->sal_True change? + bSWWA = !bSCWA; // sal_True->sal_False change? + break; + } + case UPH_IS_SPELL_WITH_DIGITS : + { + pbVal = &bIsSpellWithDigits; + bSCWA = sal_False == *pbVal; // sal_False->sal_True change? + bSWWA = !bSCWA; // sal_True->sal_False change? + break; + } + case UPH_IS_SPELL_CAPITALIZATION : + { + pbVal = &bIsSpellCapitalization; + bSCWA = sal_False == *pbVal; // sal_False->sal_True change? + bSWWA = !bSCWA; // sal_True->sal_False change? + break; + } + case UPH_IS_SPELL_CLOSED_COMPOUND : + { + pbVal = &bIsSpellClosedCompound; + bSCWA = sal_False == *pbVal; // sal_False->sal_True change? + bSWWA = !bSCWA; // sal_True->sal_False change? + break; + } + case UPH_IS_SPELL_HYPHENATED_COMPOUND : + { + pbVal = &bIsSpellHyphenatedCompound; + bSCWA = sal_False == *pbVal; // sal_False->sal_True change? + bSWWA = !bSCWA; // sal_True->sal_False change? + break; + } + + default: + OSL_FAIL( "unknown property" ); + } + if (pbVal) + rEvt.NewValue >>= *pbVal; + + if (bSCWA) + nLngSvcFlags |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN; + if (bSWWA) + nLngSvcFlags |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN; + if (nLngSvcFlags) + { + LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags ); + LaunchEvent( aEvt ); + } + } +} + + +void PropertyHelper_Spell::SetTmpPropVals( const PropertyValues &rPropVals ) +{ + // set return value to default value unless there is an + // explicitly supplied temporary value + bResIsGermanPreReform = bIsGermanPreReform; + bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters; + bResIsUseDictionaryList = bIsUseDictionaryList; + bResIsSpellUpperCase = bIsSpellUpperCase; + bResIsSpellWithDigits = bIsSpellWithDigits; + bResIsSpellCapitalization = bIsSpellCapitalization; + bResIsSpellClosedCompound = bIsSpellClosedCompound; + bResIsSpellHyphenatedCompound = bIsSpellHyphenatedCompound; + + sal_Int32 nLen = rPropVals.getLength(); + if (nLen) + { + const PropertyValue *pVal = rPropVals.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + sal_Bool *pbResVal = NULL; + switch (pVal[i].Handle) + { + case UPH_IS_GERMAN_PRE_REFORM : pbResVal = &bResIsGermanPreReform; break; + case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbResVal = &bResIsIgnoreControlCharacters; break; + case UPH_IS_USE_DICTIONARY_LIST : pbResVal = &bResIsUseDictionaryList; break; + case UPH_IS_SPELL_UPPER_CASE : pbResVal = &bResIsSpellUpperCase; break; + case UPH_IS_SPELL_WITH_DIGITS : pbResVal = &bResIsSpellWithDigits; break; + case UPH_IS_SPELL_CAPITALIZATION : pbResVal = &bResIsSpellCapitalization; break; + case UPH_IS_SPELL_CLOSED_COMPOUND : pbResVal = &bResIsSpellClosedCompound; break; + case UPH_IS_SPELL_HYPHENATED_COMPOUND : pbResVal = &bResIsSpellHyphenatedCompound; break; + default: + OSL_FAIL( "unknown property" ); + } + if (pbResVal) + pVal[i].Value >>= *pbResVal; + } + } +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/linguistic/workben/sprophelp.hxx b/linguistic/workben/sprophelp.hxx new file mode 100644 index 0000000000..55fd481983 --- /dev/null +++ b/linguistic/workben/sprophelp.hxx @@ -0,0 +1,155 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_LINGUISTIC_WORKBEN_SPROPHELP_HXX +#define INCLUDED_LINGUISTIC_WORKBEN_SPROPHELP_HXX + +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp> + +namespace com::sun::star::beans { + class XPropertySet; +}}}}; + +namespace com::sun::star::linguistic2 { + struct LinguServiceEvent; +}}}}; + + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::linguistic2; + +// PropertyChgHelper +// virtual base class for all XPropertyChangeListener members of the +// various lingu services. +// Only propertyChange needs to be implemented. + +class PropertyChgHelper : + public cppu::WeakImplHelper + < + XPropertyChangeListener, + XLinguServiceEventBroadcaster + > +{ + Sequence< OUString > aPropNames; + Reference< XInterface > xMyEvtObj; + ::comphelper::OInterfaceContainerHelper2 aLngSvcEvtListeners; + Reference< XPropertySet > xPropSet; + + // disallow use of copy-constructor and assignment-operator + PropertyChgHelper( const PropertyChgHelper & ); + PropertyChgHelper & operator = ( const PropertyChgHelper & ); + +public: + PropertyChgHelper( + const Reference< XInterface > &rxSource, + Reference< XPropertySet > &rxPropSet, + const char *pPropNames[], sal_uInt16 nPropCount ); + virtual ~PropertyChgHelper(); + + // XEventListener + virtual void SAL_CALL + disposing( const EventObject& rSource ) + throw(RuntimeException); + + // XPropertyChangeListener + virtual void SAL_CALL + propertyChange( const PropertyChangeEvent& rEvt ) + throw(RuntimeException) = 0; + + // XLinguServiceEventBroadcaster + virtual sal_Bool SAL_CALL + addLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxListener ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL + removeLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxListener ) + throw(RuntimeException); + + // non UNO functions + void AddAsPropListener(); + void RemoveAsPropListener(); + void LaunchEvent( const LinguServiceEvent& rEvt ); + + const Sequence< OUString > & + GetPropNames() const { return aPropNames; } + const Reference< XPropertySet > & + GetPropSet() const { return xPropSet; } + const Reference< XInterface > & + GetEvtObj() const { return xMyEvtObj; } +}; + + +class PropertyHelper_Spell : + public PropertyChgHelper +{ + // default values + sal_Bool bIsGermanPreReform; + sal_Bool bIsIgnoreControlCharacters; + sal_Bool bIsUseDictionaryList; + sal_Bool bIsSpellUpperCase; + sal_Bool bIsSpellWithDigits; + sal_Bool bIsSpellCapitalization; + + // return values, will be set to default value or current temporary value + sal_Bool bResIsGermanPreReform; + sal_Bool bResIsIgnoreControlCharacters; + sal_Bool bResIsUseDictionaryList; + sal_Bool bResIsSpellUpperCase; + sal_Bool bResIsSpellWithDigits; + sal_Bool bResIsSpellCapitalization; + + + // disallow use of copy-constructor and assignment-operator + PropertyHelper_Spell( const PropertyHelper_Spell & ); + PropertyHelper_Spell & operator = ( const PropertyHelper_Spell & ); + + void SetDefault(); + +public: + PropertyHelper_Spell( + const Reference< XInterface > &rxSource, + Reference< XPropertySet > &rxPropSet ); + virtual ~PropertyHelper_Spell(); + + // XPropertyChangeListener + virtual void SAL_CALL + propertyChange( const PropertyChangeEvent& rEvt ) + throw(RuntimeException); + + void SetTmpPropVals( const PropertyValues &rPropVals ); + + sal_Bool IsGermanPreReform() const { return bResIsGermanPreReform; } + sal_Bool IsIgnoreControlCharacters() const { return bResIsIgnoreControlCharacters; } + sal_Bool IsUseDictionaryList() const { return bResIsUseDictionaryList; } + sal_Bool IsSpellUpperCase() const { return bResIsSpellUpperCase; } + sal_Bool IsSpellWithDigits() const { return bResIsSpellWithDigits; } + sal_Bool IsSpellCapitalization() const { return bResIsSpellCapitalization; } +}; + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/linguistic/workben/sreg.cxx b/linguistic/workben/sreg.cxx new file mode 100644 index 0000000000..64af55925d --- /dev/null +++ b/linguistic/workben/sreg.cxx @@ -0,0 +1,63 @@ +/* -*- 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 <rtl/string.hxx> + +#include <com/sun/star/registry/XRegistryKey.hpp> + +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; + +// declaration of external RegEntry-functions defined by the service objects + +extern sal_Bool SAL_CALL SpellChecker_writeInfo( + void * /*pServiceManager*/, XRegistryKey * pRegistryKey ); + +extern void * SAL_CALL SpellChecker_getFactory( + const char * pImplName, + XMultiServiceFactory * pServiceManager, + void * /*pRegistryKey*/ ); + +// definition of the two functions that are used to provide the services + +extern "C" +{ + +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, XRegistryKey * pRegistryKey ) +{ + return SpellChecker_writeInfo( pServiceManager, pRegistryKey ); +} + +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = SpellChecker_getFactory( + pImplName, + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + pRegistryKey ); + + return pRet; +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/linguistic/workben/sspellimp.cxx b/linguistic/workben/sspellimp.cxx new file mode 100644 index 0000000000..04c5d03d62 --- /dev/null +++ b/linguistic/workben/sspellimp.cxx @@ -0,0 +1,476 @@ +/* -*- 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 <com/sun/star/uno/Reference.h> +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#include <com/sun/star/linguistic2/SpellFailure.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <tools/debug.hxx> +#include <osl/mutex.hxx> + +#include <sspellimp.hxx> + +#include "linguistic/lngprops.hxx" +#include "linguistic/spelldta.hxx" + +using namespace utl; +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::linguistic2; +using namespace linguistic; + + +sal_Bool operator == ( const Locale &rL1, const Locale &rL2 ) +{ + return rL1.Language == rL2.Language && + rL1.Country == rL2.Country && + rL1.Variant == rL2.Variant; +} + + +SpellChecker::SpellChecker() : + aEvtListeners ( GetLinguMutex() ), + pPropHelper(NULL), + bDisposing(sal_False) +{ +} + + +SpellChecker::~SpellChecker() +{ + if (pPropHelper) + pPropHelper->RemoveAsPropListener(); +} + + +PropertyHelper_Spell & SpellChecker::GetPropHelper_Impl() +{ + if (!pPropHelper) + { + Reference< XLinguProperties > xPropSet = GetLinguProperties(); + + pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet ); + xPropHelper = pPropHelper; + pPropHelper->AddAsPropListener(); //! after a reference is established + } + return *pPropHelper; +} + + +Sequence< Locale > SAL_CALL SpellChecker::getLocales() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!aSuppLocales.getLength()) + { + aSuppLocales.realloc( 3 ); + Locale *pLocale = aSuppLocales.getArray(); + pLocale[0] = Locale( "en", "US", OUString() ); + pLocale[1] = Locale( "de", "DE", OUString() ); + pLocale[2] = Locale( "de", "CH", OUString() ); + } + + return aSuppLocales; +} + + +sal_Bool SAL_CALL SpellChecker::hasLocale(const Locale& rLocale) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (!aSuppLocales.getLength()) + getLocales(); + sal_Int32 nLen = aSuppLocales.getLength(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + const Locale *pLocale = aSuppLocales.getConstArray(); + if (rLocale == pLocale[i]) + { + bRes = sal_True; + break; + } + } + return bRes; +} + + +sal_Int16 SpellChecker::GetSpellFailure( const OUString &rWord, const Locale & ) +{ + // Checks whether a word is OK in a given language (Locale) or not, and + // provides a failure type for the incorrect ones. + // - words with "liss" (case sensitive) as substring will be negative. + // - words with 'x' or 'X' will have incorrect spelling. + // - words with 's' or 'S' as first letter will have the wrong caption. + // - all other words will be OK. + + sal_Int16 nRes = -1; + + String aTmp( rWord ); + if (aTmp.Len()) + { + if (-1 != aTmp.indexOf( "liss" )) + { + nRes = SpellFailure::IS_NEGATIVE_WORD; + } + else if (-1 != aTmp.indexOf( 'x' ) || + -1 != aTmp.indexOf( 'X' )) + { + nRes = SpellFailure::SPELLING_ERROR; + } + else + { + sal_Unicode cChar = aTmp.GetChar( 0 ); + if (cChar == 's' || cChar == 'S') + nRes = SpellFailure::CAPTION_ERROR; + } + } + + return nRes; +} + + +sal_Bool SAL_CALL + SpellChecker::isValid( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (rLocale == Locale() || !rWord.getLength()) + return sal_True; + + if (!hasLocale( rLocale )) +#ifdef LINGU_EXCEPTIONS + throw( IllegalArgumentException() ); +#else + return sal_True; +#endif + + // Get property values to be used. + // These are be the default values set in the SN_LINGU_PROPERTIES + // PropertySet which are overridden by the supplied ones from the + // last argument. + // You'll probably like to use a simpler solution than the provided + // one using the PropertyHelper_Spell. + PropertyHelper_Spell &rHelper = GetPropHelper(); + rHelper.SetTmpPropVals( rProperties ); + + sal_Int16 nFailure = GetSpellFailure( rWord, rLocale ); + if (nFailure != -1) + { + sal_Int16 nLang = LinguLocaleToLanguage( rLocale ); + // postprocess result for errors that should be ignored + if ( (!rHelper.IsSpellUpperCase() && IsUpper( rWord, nLang )) + || (!rHelper.IsSpellWithDigits() && HasDigits( rWord )) + || (!rHelper.IsSpellCapitalization() + && nFailure == SpellFailure::CAPTION_ERROR) + ) + nFailure = -1; + } + return nFailure == -1; +} + + +Reference< XSpellAlternatives > + SpellChecker::GetProposals( const OUString &rWord, const Locale &rLocale ) +{ + // Retrieves the return values for the 'spell' function call in case + // of a misspelled word. + // Especially it may give a list of suggested (correct) words: + // - a "liss" substring will be replaced by "liz". + // - 'x' or 'X' will be replaced by 'u' or 'U' for the first proposal + // and they will be removed from the word for the second proposal. + // - 's' or 'S' as first letter will be changed to the other caption. + + Reference< XSpellAlternatives > xRes; + + String aTmp( rWord ); + if (aTmp.Len()) + { + sal_Int16 nLang = LinguLocaleToLanguage( rLocale ); + + if (-1 != aTmp.indexOf( "liss" )) + { + aTmp.SearchAndReplaceAllAscii( "liss", "liz" ); + xRes = new SpellAlternatives( aTmp, nLang, + SpellFailure::IS_NEGATIVE_WORD, css::uno::Sequence< OUString >() ); + } + else if (-1 != aTmp.indexOf( 'x' ) || + -1 != aTmp.indexOf( 'X' )) + { + Sequence< OUString > aStr( 2 ); + OUString *pStr = aStr.getArray(); + String aAlt1( aTmp ), + aAlt2( aTmp ); + aAlt1.SearchAndReplaceAll( 'x', 'u'); + aAlt1.SearchAndReplaceAll( 'X', 'U'); + aAlt2 = aAlt2.replaceAll("x", "").replaceAll("X", ""); + pStr[0] = aAlt1; + pStr[1] = aAlt2; + + SpellAlternatives *pAlt = new SpellAlternatives; + pAlt->SetWordLanguage( aTmp, nLang ); + pAlt->SetFailureType( SpellFailure::SPELLING_ERROR ); + pAlt->SetAlternatives( aStr ); + + xRes = pAlt; + } + else + { + sal_Unicode cChar = aTmp.GetChar( 0 ); + if (cChar == 's' || cChar == 'S') + { + sal_Unicode cNewChar = cChar == 's' ? + 'S': 's'; + aTmp.GetBufferAccess()[0] = cNewChar; + xRes = new SpellAlternatives( aTmp, nLang, + SpellFailure::CAPTION_ERROR, css::uno::Sequence< OUString >() ); + } + } + } + + return xRes; +} + + +Reference< XSpellAlternatives > SAL_CALL + SpellChecker::spell( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (rLocale == Locale() || !rWord.getLength()) + return NULL; + + if (!hasLocale( rLocale )) +#ifdef LINGU_EXCEPTIONS + throw( IllegalArgumentException() ); +#else + return NULL; +#endif + + Reference< XSpellAlternatives > xAlt; + if (!isValid( rWord, rLocale, rProperties )) + { + xAlt = GetProposals( rWord, rLocale ); + } + return xAlt; +} + + +Reference< XInterface > SAL_CALL SpellChecker_CreateInstance( + const Reference< XMultiServiceFactory > & ) + throw(Exception) +{ + Reference< XInterface > xService = (cppu::OWeakObject*) new SpellChecker; + return xService; +} + + +sal_Bool SAL_CALL + SpellChecker::addLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxLstnr ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (!bDisposing && rxLstnr.is()) + { + bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr ); + } + return bRes; +} + + +sal_Bool SAL_CALL + SpellChecker::removeLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxLstnr ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (!bDisposing && rxLstnr.is()) + { + DBG_ASSERT( xPropHelper.is(), "xPropHelper non existent" ); + bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr ); + } + return bRes; +} + + +OUString SAL_CALL + SpellChecker::getServiceDisplayName( const Locale& ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return OUString( "OpenOffice example spellchecker" ); +} + + +void SAL_CALL + SpellChecker::initialize( const Sequence< Any >& rArguments ) + throw(Exception, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!pPropHelper) + { + sal_Int32 nLen = rArguments.getLength(); + if (2 == nLen) + { + Reference< XPropertySet > xPropSet; + rArguments.getConstArray()[0] >>= xPropSet; + + //! Pointer allows for access of the non-UNO functions. + //! And the reference to the UNO-functions while increasing + //! the ref-count and will implicitly free the memory + //! when the object is no longer used. + pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet ); + xPropHelper = pPropHelper; + pPropHelper->AddAsPropListener(); //! after a reference is established + } + else + OSL_FAIL( "wrong number of arguments in sequence" ); + } +} + + +void SAL_CALL + SpellChecker::dispose() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing) + { + bDisposing = sal_True; + EventObject aEvtObj( (XSpellChecker *) this ); + aEvtListeners.disposeAndClear( aEvtObj ); + } +} + + +void SAL_CALL + SpellChecker::addEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.addInterface( rxListener ); +} + + +void SAL_CALL + SpellChecker::removeEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.removeInterface( rxListener ); +} + + +// Service specific part + +OUString SAL_CALL SpellChecker::getImplementationName() + throw(RuntimeException) +{ + return getImplementationName_Static(); +} + + +sal_Bool SAL_CALL SpellChecker::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + return cppu::supportsService(this, ServiceName); +} + +Sequence< OUString > SAL_CALL SpellChecker::getSupportedServiceNames() + throw(RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + + +Sequence< OUString > SpellChecker::getSupportedServiceNames_Static() + throw() +{ + Sequence< OUString > aSNS { SN_SPELLCHECKER }; + return aSNS; +} + + +sal_Bool SAL_CALL SpellChecker_writeInfo( + void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey ) +{ + try + { + OUString aImpl( "/" + SpellChecker::getImplementationName_Static().getStr() + + "/UNO/SERVICES" ); + + Reference< registry::XRegistryKey > xNewKey = + pRegistryKey->createKey( aImpl ); + Sequence< OUString > aServices = + SpellChecker::getSupportedServiceNames_Static(); + for( sal_Int32 i = 0; i < aServices.getLength(); i++ ) + xNewKey->createKey( aServices.getConstArray()[i] ); + + return sal_True; + } + catch(Exception &) + { + return sal_False; + } +} + + +void * SAL_CALL SpellChecker_getFactory( const char * pImplName, + XMultiServiceFactory * pServiceManager, void * ) +{ + void * pRet = 0; + if ( SpellChecker::getImplementationName_Static().equalsAscii( pImplName ) ) + { + Reference< XSingleServiceFactory > xFactory = + cppu::createOneInstanceFactory( + pServiceManager, + SpellChecker::getImplementationName_Static(), + SpellChecker_CreateInstance, + SpellChecker::getSupportedServiceNames_Static()); + // acquire, because we return an interface pointer instead of a reference + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/linguistic/workben/sspellimp.hxx b/linguistic/workben/sspellimp.hxx new file mode 100644 index 0000000000..f07674ca13 --- /dev/null +++ b/linguistic/workben/sspellimp.hxx @@ -0,0 +1,157 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_LINGUISTIC_WORKBEN_SSPELLIMP_HXX +#define INCLUDED_LINGUISTIC_WORKBEN_SSPELLIMP_HXX + +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceDisplayName.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/linguistic2/XSpellChecker.hpp> +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp> + +#include "linguistic/misc.hxx" +#include "sprophelp.hxx" + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::linguistic2; + + +class SpellChecker : + public cppu::WeakImplHelper + < + XSpellChecker, + XLinguServiceEventBroadcaster, + XInitialization, + XComponent, + XServiceInfo, + XServiceDisplayName + > +{ + Sequence< Locale > aSuppLocales; + ::comphelper::OInterfaceContainerHelper2 aEvtListeners; + Reference< XPropertyChangeListener > xPropHelper; + PropertyHelper_Spell * pPropHelper; + sal_Bool bDisposing; + + // disallow copy-constructor and assignment-operator for now + SpellChecker(const SpellChecker &); + SpellChecker & operator = (const SpellChecker &); + + PropertyHelper_Spell & GetPropHelper_Impl(); + PropertyHelper_Spell & GetPropHelper() + { + return pPropHelper ? *pPropHelper : GetPropHelper_Impl(); + } + + sal_Int16 GetSpellFailure( const OUString &rWord, const Locale &rLocale ); + Reference< XSpellAlternatives > + GetProposals( const OUString &rWord, const Locale &rLocale ); + +public: + SpellChecker(); + virtual ~SpellChecker(); + + // XSupportedLocales (for XSpellChecker) + virtual Sequence< Locale > SAL_CALL + getLocales() + throw(RuntimeException); + virtual sal_Bool SAL_CALL + hasLocale( const Locale& rLocale ) + throw(RuntimeException); + + // XSpellChecker + virtual sal_Bool SAL_CALL + isValid( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, + RuntimeException); + virtual Reference< XSpellAlternatives > SAL_CALL + spell( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, + RuntimeException); + + // XLinguServiceEventBroadcaster + virtual sal_Bool SAL_CALL + addLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxLstnr ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL + removeLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxLstnr ) + throw(RuntimeException); + + // XServiceDisplayName + virtual OUString SAL_CALL + getServiceDisplayName( const Locale& rLocale ) + throw(RuntimeException); + + // XInitialization + virtual void SAL_CALL + initialize( const Sequence< Any >& rArguments ) + throw(Exception, RuntimeException); + + // XComponent + virtual void SAL_CALL + dispose() + throw(RuntimeException); + virtual void SAL_CALL + addEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException); + virtual void SAL_CALL + removeEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException); + + // Service specific part + + // XServiceInfo + virtual OUString SAL_CALL + getImplementationName() + throw(RuntimeException); + virtual sal_Bool SAL_CALL + supportsService( const OUString& rServiceName ) + throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL + getSupportedServiceNames() + throw(RuntimeException); + + + static inline OUString + getImplementationName_Static() throw(); + static Sequence< OUString > + getSupportedServiceNames_Static() throw(); +}; + +inline OUString SpellChecker::getImplementationName_Static() throw() +{ + return OUString( "com.sun.star.lingu.examples.SpellChecker" ); +} + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |