diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-11-17 11:37:46 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-11-17 11:37:46 +0000 |
commit | 0bea775c56bdfa2a2d7a348fc2293e11f09883a6 (patch) | |
tree | e64e6787277bbabe6ae42603e9c2f55906a407e5 | |
parent | e17057898a48786f5663eb9de3ae4c6b1a348c2d (diff) |
Initial_Import
34 files changed, 12068 insertions, 0 deletions
diff --git a/linguistic/inc/iprcache.hxx b/linguistic/inc/iprcache.hxx new file mode 100644 index 000000000000..c5a2fbd89564 --- /dev/null +++ b/linguistic/inc/iprcache.hxx @@ -0,0 +1,183 @@ +/************************************************************************* + * + * $RCSfile: iprcache.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:29 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_IPRCACHE_HXX_ +#define _LINGUISTIC_IPRCACHE_HXX_ + + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations + +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/linguistic2/XDictionaryListEventListener.hpp> +#include <com/sun/star/linguistic2/XDictionaryList.hpp> + +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif + + +namespace linguistic +{ + +class IPRCachedWord; + +/////////////////////////////////////////////////////////////////////////// + +class Flushable +{ +public: + virtual void Flush() = 0; +}; + +/////////////////////////////////////////////////////////////////////////// + +class FlushListener : + public cppu::WeakImplHelper1 + < + ::com::sun::star::linguistic2::XDictionaryListEventListener + > +{ + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryList > xDicList; + Flushable *pFlushObj; + + // don't allow to use copy-constructor and assignment-operator + FlushListener(const FlushListener &); + FlushListener & operator = (const FlushListener &); + +public: + FlushListener( Flushable *pFO ); + virtual ~FlushListener(); + + void SetDicList( + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryList > &xDL ); + inline void SetFlushObj( Flushable *pFO) { pFlushObj = pFO; } + + //XEventListener + virtual void SAL_CALL + disposing( const ::com::sun::star::lang::EventObject& Source ) + throw(::com::sun::star::uno::RuntimeException); + + // XDictionaryListEventListener + virtual void SAL_CALL + processDictionaryListEvent( + const ::com::sun::star::linguistic2::DictionaryListEvent& aDicListEvent ) + throw(::com::sun::star::uno::RuntimeException); +}; + +/////////////////////////////////////////////////////////////////////////// + +class IPRSpellCache : + public Flushable +{ + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryListEventListener > + xFlushLstnr; + FlushListener *pFlushLstnr; + + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryList > + xDicList; + + IPRCachedWord **ppHash; + IPRCachedWord *pFirst; + IPRCachedWord *pLast; + IPRCachedWord *pRun; + IPRCachedWord *pInput; + ULONG nIndex; + ULONG nCount; + ULONG nInputPos; + ULONG nInputValue; + ULONG nTblSize; +#ifdef DBG_STATISTIC + ULONG nMaxInput; + ULONG nMax; + ULONG nFound; + ULONG nLost; +#endif + + // don't allow to use copy-constructor and assignment-operator + IPRSpellCache(const IPRSpellCache &); + IPRSpellCache & operator = (const IPRSpellCache &); + +public: + IPRSpellCache( ULONG nSize ); + virtual ~IPRSpellCache(); + + // Flushable + virtual void Flush(); + + void AddWord( const String& rWord, INT16 nLang ); + BOOL CheckWord( const String& rWord, INT16 nLang, BOOL bAllLang ); +}; + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + +#endif + diff --git a/linguistic/inc/lngprops.hxx b/linguistic/inc/lngprops.hxx new file mode 100644 index 000000000000..c787a5451a82 --- /dev/null +++ b/linguistic/inc/lngprops.hxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * $RCSfile: lngprops.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:29 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_LNGPROPS_HHX_ +#define _LINGUISTIC_LNGPROPS_HHX_ + + +#define UPN_IS_GERMAN_PRE_REFORM "IsGermanPreReform" +#define UPN_IS_USE_DICTIONARY_LIST "IsUseDictionaryList" +#define UPN_IS_IGNORE_CONTROL_CHARACTERS "IsIgnoreControlCharacters" + +// UNO property names for SpellChecker +#define UPN_IS_SPELL_UPPER_CASE "IsSpellUpperCase" +#define UPN_IS_SPELL_WITH_DIGITS "IsSpellWithDigits" +#define UPN_IS_SPELL_CAPITALIZATION "IsSpellCapitalization" + +// UNO property names for Hyphenator +#define UPN_HYPH_MIN_LEADING "HyphMinLeading" +#define UPN_HYPH_MIN_TRAILING "HyphMinTrailing" +#define UPN_HYPH_MIN_WORD_LENGTH "HyphMinWordLength" + +// UNO property names for OtherLingu (foreign Linguistik) +#define UPN_IS_STANDARD_HYPHENATOR "IsStandardHyphenator" +#define UPN_IS_STANDARD_SPELL_CHECKER "IsStandardSpellChecker" +#define UPN_IS_STANDARD_THESAURUS "IsStandardThesaurus" +#define UPN_OTHER_LINGU_INDEX "OtherLinguIndex" + +// UNO property names for Lingu +// (those not covered by the SpellChecker, Hyphenator and OtherLingu properties +// and more likely used in other modules only) +#define UPN_DEFAULT_LANGUAGE "DefaultLanguage" +#define UPN_DEFAULT_LOCALE "DefaultLocale" +#define UPN_IS_HYPH_AUTO "IsHyphAuto" +#define UPN_IS_HYPH_SPECIAL "IsHyphSpecial" +#define UPN_IS_SPELL_AUTO "IsSpellAuto" +#define UPN_IS_SPELL_HIDE "IsSpellHide" +#define UPN_IS_SPELL_IN_ALL_LANGUAGES "IsSpellInAllLanguages" +#define UPN_IS_SPELL_SPECIAL "IsSpellSpecial" +#define UPN_IS_WRAP_REVERSE "IsWrapReverse" + +// WIDs for property names +//!! Don't change values! They are used as the property handles in +//!! the service description +#define WID_IS_GERMAN_PRE_REFORM 0 +#define WID_IS_USE_DICTIONARY_LIST 1 +#define WID_IS_IGNORE_CONTROL_CHARACTERS 2 +#define WID_IS_SPELL_UPPER_CASE 3 +#define WID_IS_SPELL_WITH_DIGITS 4 +#define WID_IS_SPELL_CAPITALIZATION 5 +#define WID_HYPH_MIN_LEADING 6 +#define WID_HYPH_MIN_TRAILING 7 +#define WID_HYPH_MIN_WORD_LENGTH 8 +#define WID_DEFAULT_LOCALE 9 +#define WID_IS_SPELL_AUTO 10 +#define WID_IS_SPELL_HIDE 11 +#define WID_IS_SPELL_IN_ALL_LANGUAGES 12 +#define WID_IS_SPELL_SPECIAL 13 +#define WID_IS_HYPH_AUTO 14 +#define WID_IS_HYPH_SPECIAL 15 +#define WID_IS_WRAP_REVERSE 16 +#define WID_IS_STANDARD_HYPHENATOR 17 +#define WID_IS_STANDARD_SPELL_CHECKER 18 +#define WID_IS_STANDARD_THESAURUS 19 +#define WID_OTHER_LINGU_INDEX 20 +#define WID_DEFAULT_LANGUAGE 21 + + +// UNO property handles +#define UPH_IS_GERMAN_PRE_REFORM WID_IS_GERMAN_PRE_REFORM +#define UPH_IS_USE_DICTIONARY_LIST WID_IS_USE_DICTIONARY_LIST +#define UPH_IS_IGNORE_CONTROL_CHARACTERS WID_IS_IGNORE_CONTROL_CHARACTERS +// +#define UPH_IS_SPELL_UPPER_CASE WID_IS_SPELL_UPPER_CASE +#define UPH_IS_SPELL_WITH_DIGITS WID_IS_SPELL_WITH_DIGITS +#define UPH_IS_SPELL_CAPITALIZATION WID_IS_SPELL_CAPITALIZATION +// +#define UPH_HYPH_MIN_LEADING WID_HYPH_MIN_LEADING +#define UPH_HYPH_MIN_TRAILING WID_HYPH_MIN_TRAILING +#define UPH_HYPH_MIN_WORD_LENGTH WID_HYPH_MIN_WORD_LENGTH + + +#endif + diff --git a/linguistic/inc/misc.hxx b/linguistic/inc/misc.hxx new file mode 100644 index 000000000000..c428573bfa0a --- /dev/null +++ b/linguistic/inc/misc.hxx @@ -0,0 +1,256 @@ +/************************************************************************* + * + * $RCSfile: misc.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:30 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_MISC_HXX_ +#define _LINGUISTIC_MISC_HXX_ + + +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_ +#include <com/sun/star/uno/Sequence.h> +#endif +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif +#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_ +#include <com/sun/star/beans/PropertyValues.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_XTERMINATELISTENER_HPP_ +#include <com/sun/star/frame/XTerminateListener.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_ +#include <com/sun/star/lang/Locale.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_XDICTIONARYENTRY_HPP_ +#include <com/sun/star/linguistic2/XDictionaryEntry.hpp> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_ +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#endif + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations + +#ifndef _ISOLANG_HXX +#include <tools/isolang.hxx> +#endif +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif +#ifndef _TOOLS_INTN_HXX +#include <tools/intn.hxx> +#endif +#ifndef _UNOTOOLS_CHARCLASS_HXX +#include <unotools/charclass.hxx> +#endif +#ifndef _OSL_THREAD_H_ +#include <osl/thread.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +namespace com { namespace sun { namespace star { namespace beans { + class XPropertySet; + class XFastPropertySet; +}}}}; + +namespace com { namespace sun { namespace star { namespace frame { + class XDesktop; +}}}}; + +/////////////////////////////////////////////////////////////////////////// + +#define SN_SPELLCHECKER "com.sun.star.linguistic2.SpellChecker" +#define SN_HYPHENATOR "com.sun.star.linguistic2.Hyphenator" +#define SN_THESAURUS "com.sun.star.linguistic2.Thesaurus" +#define SN_LINGU_SERVCICE_MANAGER "com.sun.star.linguistic2.LinguServiceManager" +#define SN_LINGU_PROPERTIES "com.sun.star.linguistic2.LinguProperties" +#define SN_DICTIONARY_LIST "com.sun.star.linguistic2.DictionaryList" +#define SN_OTHER_LINGU "com.sun.star.linguistic2.OtherLingu" +#define SN_DESKTOP "com.sun.star.frame.Desktop" + + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + +::osl::Mutex & GetLinguMutex(); + +/////////////////////////////////////////////////////////////////////////// + +inline rtl_TextEncoding GetTextEncoding() { return osl_getThreadTextEncoding(); } + +inline ::rtl::OUString BS2OU(const ByteString &rText) +{ + return ::rtl::OUString( rText.GetBuffer(), rText.Len(), GetTextEncoding() ); +} + +inline ByteString OU2BS(const ::rtl::OUString &rText) +{ + return ByteString( rText.getStr(), GetTextEncoding() ); +} + +/////////////////////////////////////////////////////////////////////////// + +::com::sun::star::lang::Locale + CreateLocale( LanguageType eLang ); + +LanguageType + LocaleToLanguage( const ::com::sun::star::lang::Locale& rLocale ); + +::com::sun::star::lang::Locale& + LanguageToLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang ); + +::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > + LangSeqToLocaleSeq( const ::com::sun::star::uno::Sequence< INT16 > &rLangSeq ); + +::com::sun::star::uno::Sequence< INT16 > + LocaleSeqToLangSeq( ::com::sun::star::uno::Sequence< + ::com::sun::star::lang::Locale > &rLocaleSeq ); + +/////////////////////////////////////////////////////////////////////////// + +BOOL IsUpper( const String &rText, INT16 nLanguage ); +BOOL IsLower( const String &rText, INT16 nLanguage ); +String ToLower( const String &rText, INT16 nLanguage ); +sal_Unicode ToLower( const sal_Unicode cChar, INT16 nLanguage ); +sal_Unicode ToUpper( const sal_Unicode cChar, INT16 nLanguage ); +BOOL HasDigits( const String &rText ); +BOOL IsNumeric( const String &rText ); + +/////////////////////////////////////////////////////////////////////////// + +::com::sun::star::uno::Reference< + ::com::sun::star::uno::XInterface > + GetOneInstanceService( const char *pServiceName ); + +::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + GetLinguProperties(); + +::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > + GetSearchableDictionaryList(); + +::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryList > + GetDictionaryList(); + +/////////////////////////////////////////////////////////////////////////// + +BOOL IsUseDicList( const ::com::sun::star::beans::PropertyValues &rProperties, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > &rxPropSet ); + +::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > + SearchDicList( + const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryList >& rDicList, + const ::rtl::OUString& rWord, INT16 nLanguage, + BOOL bSearchPosDics, BOOL bSearchSpellEntry ); + +/////////////////////////////////////////////////////////////////////////// +// +// AppExitLstnr: +// virtual base class that calls it AtExit function when the application +// (ie the Desktop) is about to terminate +// + +class AppExitListener : + public cppu::WeakImplHelper1 + < + ::com::sun::star::frame::XTerminateListener + > +{ + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDesktop > xDesktop; + +public: + AppExitListener(); + virtual ~AppExitListener(); + + virtual void AtExit() = 0; + + void Activate(); + void Deactivate(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); + + // XTerminateListener + virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); +}; + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + +#endif + diff --git a/linguistic/inc/spelldta.hxx b/linguistic/inc/spelldta.hxx new file mode 100644 index 000000000000..48201d8b530d --- /dev/null +++ b/linguistic/inc/spelldta.hxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * $RCSfile: spelldta.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:30 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_SPELLDTA_HXX_ +#define _LINGUISTIC_SPELLDTA_HXX_ + + +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSPELLALTERNATIVES_HPP_ +#include <com/sun/star/linguistic2/XSpellAlternatives.hpp> +#endif + +#include <tools/solar.h> + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations + + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + +::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > + MergeProposals( + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > &rxAlt1, + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > &rxAlt2 ); + +/////////////////////////////////////////////////////////////////////////// + + +class SpellAlternatives : + public cppu::WeakImplHelper1 + < + ::com::sun::star::linguistic2::XSpellAlternatives + > +{ + ::com::sun::star::uno::Sequence< ::rtl::OUString > aAlt; // list of alternatives, may be empty. + ::rtl::OUString aWord; + INT16 nType; // type of failure + INT16 nLanguage; + + // disallow copy-constructor and assignment-operator for now + SpellAlternatives(const SpellAlternatives &); + SpellAlternatives & operator = (const SpellAlternatives &); + +public: + SpellAlternatives(); + SpellAlternatives(const ::rtl::OUString &rWord, INT16 nLang, INT16 nFailureType, + const ::rtl::OUString &rRplcWord ); + virtual ~SpellAlternatives(); + + // XSpellAlternatives + virtual ::rtl::OUString SAL_CALL + getWord() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL + getLocale() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL + getFailureType() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL + getAlternativesCount() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getAlternatives() + throw(::com::sun::star::uno::RuntimeException); + + // non-interface specific functions + void SetWordLanguage(const ::rtl::OUString &rWord, INT16 nLang); + void SetFailureType(INT16 nTypeP); + void SetAlternatives( + const ::com::sun::star::uno::Sequence< ::rtl::OUString > &rAlt ); +}; + + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + +#endif + diff --git a/linguistic/prj/d.lst b/linguistic/prj/d.lst new file mode 100644 index 000000000000..7505a60b1270 --- /dev/null +++ b/linguistic/prj/d.lst @@ -0,0 +1,9 @@ +..\%__SRC%\bin\lng* %_DEST%\bin%_EXT%\lng* +..\%__SRC%\lib\lib* %_DEST%\lib%_EXT%\lib* +mkdir: %_DEST%\inc%_EXT%\linguistic +hedabu: ..\inc\lngprops.hxx %_DEST%\inc%_EXT%\linguistic\lngprops.hxx +hedabu: ..\inc\misc.hxx %_DEST%\inc%_EXT%\linguistic\misc.hxx +hedabu: ..\inc\spelldta.hxx %_DEST%\inc%_EXT%\linguistic\spelldta.hxx +hedabu: ..\inc\hyphdta.hxx %_DEST%\inc%_EXT%\linguistic\hyphdta.hxx +hedabu: ..\inc\thesdta.hxx %_DEST%\inc%_EXT%\linguistic\thesdta.hxx +hedabu: ..\inc\iprcache.hxx %_DEST%\inc%_EXT%\linguistic\iprcache.hxx diff --git a/linguistic/source/defs.hxx b/linguistic/source/defs.hxx new file mode 100644 index 000000000000..f16f30c08cbf --- /dev/null +++ b/linguistic/source/defs.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * $RCSfile: defs.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:30 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_DEFS_HXX_ +#define _LINGUISTIC_DEFS_HXX_ + +/////////////////////////////////////////////////////////////////////////// + +#define A2OU(x) ::rtl::OUString::createFromAscii( x ) + +/////////////////////////////////////////////////////////////////////////// + +struct SvcFlags +{ + INT16 nLastTriedSvcIndex; // index in sequence of the last + // service tried to instantiate + // (used for cascading) + BOOL bAlreadyWarned : 1; + BOOL bDoWarnAgain : 1; + + SvcFlags() : + nLastTriedSvcIndex(-1), bAlreadyWarned(FALSE), bDoWarnAgain(FALSE) + { + } +}; + +/////////////////////////////////////////////////////////////////////////// + +// virtual base class for the different dispatchers +class LinguDispatcher +{ +public: + virtual void + SetServiceList( const ::com::sun::star::lang::Locale &rLocale, + const ::com::sun::star::uno::Sequence< + rtl::OUString > &rSvcImplNames ) = 0; + virtual ::com::sun::star::uno::Sequence< rtl::OUString > + GetServiceList( const ::com::sun::star::lang::Locale &rLocale ) = 0; +}; + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/source/dicimp.cxx b/linguistic/source/dicimp.cxx new file mode 100644 index 000000000000..62c01a12c591 --- /dev/null +++ b/linguistic/source/dicimp.cxx @@ -0,0 +1,1095 @@ +/************************************************************************* + * + * $RCSfile: dicimp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:32 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LANG_HXX //autogen wg. LANGUAGE_ENGLISH_US +#include <tools/lang.hxx> +#endif + +#ifndef _DICIMP_HXX +#include <dicimp.hxx> +#endif +#ifndef _HYPHIMP_HXX +#include <hyphdsp.hxx> +#endif + +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef _FSYS_HXX +#include <tools/fsys.hxx> +#endif +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif +#ifndef _SFXDOCFILE_HXX +#include <sfx2/docfile.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _UCBHELPER_CONTENT_HXX +#include <ucbhelper/content.hxx> +#endif + + +#include <com/sun/star/linguistic2/DictionaryType.hpp> +#include <com/sun/star/linguistic2/DictionaryEventFlags.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <cppuhelper/factory.hxx> // helper for factories + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + +/////////////////////////////////////////////////////////////////////////// + +#define BUFSIZE 256 +#define VERS2_NOLANGUAGE 1024 + +static const sal_Char* aIntExt = "int"; +static const sal_Char* aVerStr2 = "WBSWG2"; +static const sal_Char* aVerStr5 = "WBSWG5"; + +/////////////////////////////////////////////////////////////////////////// + +DictionaryNeo::DictionaryNeo() : + aDicEvtListeners( GetLinguMutex() ), + eDicType (DictionaryType_POSITIVE), + nLanguage (LANGUAGE_NONE) +{ + nCount = 0; + bNeedEntries = FALSE; + bIsModified = bIsActive = FALSE; + bIsReadonly = FALSE; +} + +DictionaryNeo::DictionaryNeo(const OUString &rName, + INT16 nLang, DictionaryType eType, + const OUString &rMainURL) : + aDicEvtListeners( GetLinguMutex() ), + aDicName (rName), + eDicType (eType), + nLanguage (nLang), + aMainURL (rMainURL) +{ + nCount = 0; + bNeedEntries = TRUE; + bIsModified = bIsActive = FALSE; + + if (rMainURL.getLength() > 0) + { + // get DirEntry to object + INetURLObject aURLObject; + aURLObject.SetSmartProtocol( INET_PROT_FILE ); + aURLObject.SetURL( rMainURL ); + DBG_ASSERT(!aURLObject.HasError(), "lng : invalid URL"); + String aPathToFile( aURLObject.PathToFileName() ); + DirEntry aDest( aPathToFile ); + + if (!aDest.Exists()) + { + //! create physical representation of an **empty** dictionary + //! that could be searched for (see DicList::searchForDictionaries) + // (Note: empty dictionaries are not just empty files!) + saveEntries( rMainURL ); + bNeedEntries = FALSE; + } + } + else + { + bNeedEntries = FALSE; + } + + //! Creates empty file if there is no one yet! + //! Thus it must be called after the test for the files existence. + bIsReadonly = isReadonly_Impl(); +} + +DictionaryNeo::~DictionaryNeo() +{ +} + +ULONG DictionaryNeo::loadEntries(const OUString &rMainURL) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // counter check that it is safe to set bIsModified to FALSE at + // the end of the function + DBG_ASSERT(!bIsModified, "lng : dictionary already modified!"); + + // function should only be called once in order to load entries from file + bNeedEntries = FALSE; + + if (rMainURL.getLength() == 0) + return 0; + + ULONG nErr = -1; + + // get stream to use + SfxMedium aMedium( rMainURL, STREAM_READ | STREAM_SHARE_DENYWRITE, FALSE ); + aMedium.SetTransferPriority( SFX_TFPRIO_SYNCHRON ); + SvStream *pStream = aMedium.GetInStream(); + if (!pStream) + return nErr; + + // Header einlesen + BOOL bSkip = FALSE; + USHORT nLen; + + *pStream >> nLen; + if ((nErr = pStream->GetError())) + return nErr; + +#ifdef NO_MORE + if( nLen > ICMAX ) // ICMAX = 64 max ICS Wortlnge + { + bDirty = TRUE; + return FALSE; + } +#endif + + sal_Char aWordBuf[ BUFSIZE ]; + BOOL bNegativ; + + pStream->Read(aWordBuf, nLen); + if ((nErr = pStream->GetError())) + return nErr; + *(aWordBuf + nLen) = 0; + + // Version 2.0 ? + if(!strcmp(aWordBuf, aVerStr2) || + !strcmp(aWordBuf, aVerStr5) ) + { + bSkip = TRUE; + // Sprache des Dictionaries + *pStream >> nLanguage; + if ((nErr = pStream->GetError())) + return nErr; + + if ( VERS2_NOLANGUAGE == nLanguage ) + nLanguage = LANGUAGE_NONE; + + // Negativ-Flag + sal_Char nTmp; + *pStream >> nTmp; + if ((nErr = pStream->GetError())) + return nErr; + bNegativ = (BOOL) nTmp; + eDicType = bNegativ ? DictionaryType_NEGATIVE : DictionaryType_POSITIVE; + + // Das erste Wort einlesen + if (!pStream->IsEof()) + { + *pStream >> nLen; + if ((nErr = pStream->GetError())) + return nErr; + if ( nLen < BUFSIZE ) + { + pStream->Read(aWordBuf, nLen); + if ((nErr = pStream->GetError())) + return nErr; + *(aWordBuf + nLen) = 0; + } + } + } + + nCount = 0; + + while(!pStream->IsEof()) + { + // Aus dem File einlesen + // Einfuegen ins Woerterbuch ohne Konvertierung + if(*aWordBuf) + { + ByteString aDummy( aWordBuf ); + String aText( aDummy, RTL_TEXTENCODING_MS_1252 ); + Reference< XDictionaryEntry > xEntry = + new DicEntry( aText, bNegativ ); + addEntry_Impl( xEntry , TRUE ); //! don't launch events here + } + + *pStream >> nLen; + if (pStream->IsEof()) // #75082# GPF in online-spelling + break; + if ((nErr = pStream->GetError())) + return nErr; +#ifdef LINGU_EXCEPTIONS + if ( nLen >= BUFSIZE ) + throw io::IOException() ; +// break; // Woerterbuch defekt? +#endif + + if( nLen < BUFSIZE ) + { + pStream->Read(aWordBuf, nLen); + if ((nErr = pStream->GetError())) + return nErr; + } + else + return SVSTREAM_READ_ERROR; + *(aWordBuf + nLen) = 0; + } + + DBG_ASSERT(isSorted(), "lng : dictionary is not sorted"); + + // since this routine should be called only initialy (prior to any + // modification to be saved) we reset the bIsModified flag here that + // was implicitly set by addEntry_Impl + bIsModified = FALSE; + + return pStream->GetError(); +} + +ULONG DictionaryNeo::saveEntries(const OUString &rURL) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (rURL.getLength() == 0) + return 0; + + ULONG nErr = -1; + + DBG_ASSERT(!INetURLObject( rURL ).HasError(), "lng : invalid URL"); + SfxMedium aMedium( rURL, STREAM_WRITE | STREAM_TRUNC | STREAM_SHARE_DENYALL, + FALSE ); + aMedium.CreateTempFile(); // use temp file to write to... + SvStream *pStream = aMedium.GetOutStream(); + if (!pStream) + return nErr; + + sal_Char aWordBuf[BUFSIZE]; + + // write version + strcpy( aWordBuf, eDicType == DictionaryType_POSITIVE ? aVerStr2 : aVerStr5 ); + USHORT nLen = strlen( aWordBuf ); + *pStream << nLen; + if ((nErr = pStream->GetError())) + return nErr; + pStream->Write(aWordBuf, nLen); + if ((nErr = pStream->GetError())) + return nErr; + + *pStream << nLanguage; + if ((nErr = pStream->GetError())) + return nErr; + *pStream << (sal_Char) (eDicType == DictionaryType_NEGATIVE ? TRUE : FALSE); + if ((nErr = pStream->GetError())) + return nErr; + + const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray(); + for (INT32 i = 0; i < nCount; i++) + { + BOOL bIsNegativEntry = pEntry[i]->isNegative(); + rtl_TextEncoding eEnc = GetTextEncoding(); + ByteString aTmp1 ( pEntry[i]->getDictionaryWord().getStr(), eEnc ), + aTmp2 ( pEntry[i]->getReplacementText().getStr(), eEnc ); + if (bIsNegativEntry) + aTmp1 += "=="; + xub_StrLen nLen1 = aTmp1.Len(), + nLen2 = aTmp2.Len(); + if ((nLen = nLen1) < BUFSIZE) + { + strncpy( aWordBuf, aTmp1.GetBuffer(), nLen1 ); + if (bIsNegativEntry && (nLen = nLen1 + nLen2) < BUFSIZE) + strncpy( aWordBuf + nLen1, aTmp2.GetBuffer(), nLen2); + *pStream << nLen; + if ((nErr = pStream->GetError())) + return nErr; + pStream->Write(aWordBuf, nLen); + if ((nErr = pStream->GetError())) + return nErr; + } + } + + //! get return value before Stream is destroyed + ULONG nError = pStream->GetError(); + + // flush file, close it and release any lock + aMedium.Close(); + BOOL bSucc = aMedium.Commit(); + DBG_ASSERT(bSucc == TRUE, "lng : SfxMedium::Commit failed"); + + return nError; +} + +void DictionaryNeo::launchEvent(INT16 nEvent, + Reference< XDictionaryEntry > xEntry) +{ + MutexGuard aGuard( GetLinguMutex() ); + + DictionaryEvent aEvt; + aEvt.Source = Reference< XDictionary >( this ); + aEvt.nEvent = nEvent; + aEvt.xDictionaryEntry = xEntry; + + cppu::OInterfaceIteratorHelper aIt( aDicEvtListeners ); + while (aIt.hasMoreElements()) + { + Reference< XDictionaryEventListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->processDictionaryEvent( aEvt ); + } +} + +int DictionaryNeo::cmpDicEntry(const OUString& rWord1, + const OUString &rWord2, + BOOL bSimilarOnly) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // returns 0 if rWord1 is equal to rWord2 + // " a value < 0 if rWord1 is less than rWord2 + // " a value > 0 if rWord1 is greater than rWord2 + + int nRes = 0; + + OUString aWord1( rWord1 ), + aWord2( rWord2 ); + xub_StrLen nLen1 = aWord1.getLength(), + nLen2 = aWord2.getLength(); + if (bSimilarOnly) + { + const sal_Unicode cChar = '.'; + if (nLen1 && cChar == aWord1[ nLen1 - 1 ]) + nLen1--; + if (nLen2 && cChar == aWord2[ nLen2 - 1 ]) + nLen2--; + } + + const sal_Unicode cIgnChar = '='; + xub_StrLen nIdx1 = 0, + nIdx2 = 0, + nNumIgnChar1 = 0, + nNumIgnChar2 = 0; + + sal_Int32 nDiff = 0; + sal_Unicode cChar1, cChar2; + do + { + // skip chars to be ignored + while (nIdx1 < nLen1 && (cChar1 = aWord1[ nIdx1 ]) == cIgnChar) + { + nIdx1++; + nNumIgnChar1++; + } + while (nIdx2 < nLen2 && (cChar2 = aWord2[ nIdx2 ]) == cIgnChar) + { + nIdx2++; + nNumIgnChar2++; + } + + if (nIdx1 < nLen1 && nIdx2 < nLen2) + { + nDiff = cChar1 - cChar2; + if (nDiff) + break; + nIdx1++; + nIdx2++; + } + } while (nIdx1 < nLen1 && nIdx2 < nLen2); + + + if (nDiff) + nRes = nDiff; + else + { // the string with the smallest count of not ignored chars is the + // shorter one + + // count remaining IgnChars + while (nIdx1 < nLen1 ) + { + if (aWord1[ nIdx1++ ] == cIgnChar) + nNumIgnChar1++; + } + while (nIdx2 < nLen2 ) + { + if (aWord1[ nIdx2++ ] == cIgnChar) + nNumIgnChar2++; + } + + nRes = ((INT32) nLen1 - nNumIgnChar1) - ((INT32) nLen2 - nNumIgnChar2); + } + + return nRes; +} + +BOOL DictionaryNeo::seekEntry(const OUString &rWord, + INT32 *pPos, BOOL bSimilarOnly) +{ + // look for entry with binary search. + // return TRUE if found FALSE else. + // if pPos != NULL it will become the position of the found entry, or + // if that was not found the position where it has to be inserted + // to keep the entries sorted + + MutexGuard aGuard( GetLinguMutex() ); + + const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray(); + INT32 nUpperIdx = getCount(), + nMidIdx, + nLowerIdx = 0; + if( nUpperIdx > 0 ) + { + nUpperIdx--; + while( nLowerIdx <= nUpperIdx ) + { + nMidIdx = (nLowerIdx + nUpperIdx) / 2; + DBG_ASSERT(pEntry[nMidIdx].is(), "lng : empty entry encountered"); + + int nCmp = - cmpDicEntry( pEntry[nMidIdx]->getDictionaryWord(), + rWord, bSimilarOnly ); + if(nCmp == 0) + { + if( pPos ) *pPos = nMidIdx; + return TRUE; + } + else if(nCmp > 0) + nLowerIdx = nMidIdx + 1; + else if( nMidIdx == 0 ) + { + if( pPos ) *pPos = nLowerIdx; + return FALSE; + } + else + nUpperIdx = nMidIdx - 1; + } + } + if( pPos ) *pPos = nLowerIdx; + return FALSE; +} + +BOOL DictionaryNeo::isSorted() +{ + BOOL bRes = TRUE; + + const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray(); + INT32 nEntries = getCount(); + INT32 i; + for (i = 1; i < nEntries; i++) + { + if (cmpDicEntry( pEntry[i-1]->getDictionaryWord(), + pEntry[i]->getDictionaryWord() ) > 0) + { + bRes = FALSE; + break; + } + } + return bRes; +} + +BOOL DictionaryNeo::addEntry_Impl(const Reference< XDictionaryEntry > xDicEntry, + BOOL bIsLoadEntries) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + + if ( bIsLoadEntries || (!bIsReadonly && xDicEntry.is()) ) + { + BOOL bIsNegEntry = xDicEntry->isNegative(); + BOOL bAddEntry = !isFull() && + ( ( eDicType == DictionaryType_POSITIVE && !bIsNegEntry ) + || ( eDicType == DictionaryType_NEGATIVE && bIsNegEntry ) + || ( eDicType == DictionaryType_MIXED ) ); + + // look for position to insert entry at + // if there is already an entry do not insert the new one + INT32 nPos = 0; + BOOL bFound = FALSE; + if (bAddEntry) + { + bFound = seekEntry( xDicEntry->getDictionaryWord(), &nPos ); + if (bFound) + bAddEntry = FALSE; + } + + if (bAddEntry) + { + DBG_ASSERT(!bNeedEntries, "lng : entries still not loaded") + + if (nCount >= aEntries.getLength()) + aEntries.realloc( Max(2 * nCount, nCount + 32) ); + Reference< XDictionaryEntry > *pEntry = aEntries.getArray(); + + // shift old entries right + INT32 i; + for (i = nCount - 1; i >= nPos; i--) + pEntry[ i+1 ] = pEntry[ i ]; + // insert new entry at specified position + pEntry[ nPos ] = xDicEntry; + DBG_ASSERT(isSorted(), "lng : dictionary entries unsorted"); + + nCount++; + + bIsModified = TRUE; + bRes = TRUE; + + if (!bIsLoadEntries) + launchEvent( DictionaryEventFlags::ADD_ENTRY, xDicEntry ); + } + } + + return bRes; +} + + +Reference< XInterface > SAL_CALL DictionaryNeo_CreateInstance( + const Reference< XMultiServiceFactory > & rSMgr ) + throw(Exception) +{ + Reference< XInterface > xService = + (cppu::OWeakObject*) new DictionaryNeo; + return xService; +} + +OUString SAL_CALL DictionaryNeo::getName( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aDicName; +} + +void SAL_CALL DictionaryNeo::setName( const OUString& aName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (aDicName != aName) + { + aDicName = aName; + launchEvent(DictionaryEventFlags::CHG_NAME, NULL); + } +} + +DictionaryType SAL_CALL DictionaryNeo::getDictionaryType( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + return eDicType; +} + +void SAL_CALL DictionaryNeo::setActive( sal_Bool bActivate ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bIsActive != bActivate) + { + bIsActive = bActivate != 0; + INT16 nEvent = bIsActive ? + DictionaryEventFlags::ACTIVATE_DIC : DictionaryEventFlags::DEACTIVATE_DIC; + + // remove entries from memory if dictionary is deactivated + if (bIsActive == FALSE) + { + BOOL bIsEmpty = nCount == 0; + + // save entries first if necessary + if (bIsModified && hasLocation() && !isReadonly()) + { + store(); + + aEntries.realloc( 0 ); + nCount = 0; + bNeedEntries = !bIsEmpty; + } + DBG_ASSERT( !bIsModified || !hasLocation() || isReadonly(), + "lng : dictionary is still modified" ); + } + + launchEvent(nEvent, NULL); + } +} + +sal_Bool SAL_CALL DictionaryNeo::isActive( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return bIsActive; +} + +sal_Int16 SAL_CALL DictionaryNeo::getCount( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bNeedEntries) + loadEntries( aMainURL ); + return nCount; +} + +Locale SAL_CALL DictionaryNeo::getLocale( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + Locale aRes; + return LanguageToLocale( aRes, nLanguage ); +} + +void SAL_CALL DictionaryNeo::setLocale( const Locale& aLocale ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + setLanguage( LocaleToLanguage( aLocale ) ); +} + +sal_Int16 SAL_CALL DictionaryNeo::getLanguage( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return nLanguage; +} + +void SAL_CALL DictionaryNeo::setLanguage( sal_Int16 nLanguageP ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bIsReadonly && nLanguage != nLanguageP) + { + nLanguage = nLanguageP; + bIsModified = TRUE; // new language needs to be saved with dictionary + + launchEvent( DictionaryEventFlags::CHG_LANGUAGE, NULL ); + } +} + + +Reference< XDictionaryEntry > SAL_CALL DictionaryNeo::getEntry( + const OUString& aWord ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bNeedEntries) + loadEntries( aMainURL ); + + INT32 nPos; + BOOL bFound = seekEntry( aWord, &nPos, TRUE ); + DBG_ASSERT( nCount <= aEntries.getLength(), "lng : wrong number of entries"); + DBG_ASSERT(!bFound || nPos < nCount, "lng : index out of range"); + + return bFound ? aEntries.getConstArray()[ nPos ] + : Reference< XDictionaryEntry >(); +} + +sal_Bool SAL_CALL DictionaryNeo::addEntry( + const Reference< XDictionaryEntry >& xDicEntry ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + + if (!bIsReadonly) + { + if (bNeedEntries) + loadEntries( aMainURL ); + bRes = addEntry_Impl( xDicEntry ); + } + + return bRes; +} + +sal_Bool SAL_CALL + DictionaryNeo::add( const OUString& rWord, sal_Bool bIsNegative, + const OUString& rRplcText ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + + if (!bIsReadonly) + { + Reference< XDictionaryEntry > xEntry = + new DicEntry( rWord, bIsNegative, rRplcText ); + bRes = addEntry_Impl( xEntry ); + } + + return bRes; +} + +void lcl_SequenceRemoveElementAt( + uno::Sequence< Reference< XDictionaryEntry > >& rEntries, int nPos ) +{ + //TODO: helper for SequenceRemoveElementAt available? + if(nPos >= rEntries.getLength()) + return; + uno::Sequence< Reference< XDictionaryEntry > > aTmp(rEntries.getLength() - 1); + Reference< XDictionaryEntry > * pOrig = rEntries.getArray(); + Reference< XDictionaryEntry > * pTemp = aTmp.getArray(); + int nOffset = 0; + for(int i = 0; i < aTmp.getLength(); i++) + { + if(nPos == i) + nOffset++; + pTemp[i] = pOrig[i + nOffset]; + } + + rEntries = aTmp; +} + +sal_Bool SAL_CALL DictionaryNeo::remove( const OUString& aWord ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRemoved = FALSE; + + if (!bIsReadonly) + { + if (bNeedEntries) + loadEntries( aMainURL ); + + INT32 nPos; + BOOL bFound = seekEntry( aWord, &nPos ); + DBG_ASSERT( nCount < aEntries.getLength(), + "lng : wrong number of entries"); + DBG_ASSERT(!bFound || nPos < nCount, "lng : index out of range"); + + // remove element if found + if (bFound) + { + // entry to be removed + Reference< XDictionaryEntry > + xDicEntry( aEntries.getConstArray()[ nPos ] ); + DBG_ASSERT(xDicEntry.is(), "lng : dictionary entry is NULL") + + nCount--; + + //! the following call reduces the length of the sequence by 1 also + lcl_SequenceRemoveElementAt( aEntries, nPos ); + bRemoved = bIsModified = TRUE; + + launchEvent( DictionaryEventFlags::DEL_ENTRY, xDicEntry ); + } + } + + return bRemoved; +} + +sal_Bool SAL_CALL DictionaryNeo::isFull( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bNeedEntries) + loadEntries( aMainURL ); + return nCount >= DIC_MAX_ENTRIES; +} + +uno::Sequence< Reference< XDictionaryEntry > > + SAL_CALL DictionaryNeo::getEntries( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bNeedEntries) + loadEntries( aMainURL ); + //! return sequence with length equal to the number of dictionary entries + //! (internal used sequence may have additional unused elements.) + return uno::Sequence< Reference< XDictionaryEntry > > + (aEntries.getConstArray(), nCount); +} + + +void SAL_CALL DictionaryNeo::clear( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bIsReadonly && nCount) + { + // release all references to old entries and provide space for new ones + aEntries = uno::Sequence< Reference< XDictionaryEntry > > ( 32 ); + + nCount = 0; + bNeedEntries = FALSE; + bIsModified = TRUE; + + launchEvent( DictionaryEventFlags::ENTRIES_CLEARED , NULL ); + } +} + +sal_Bool SAL_CALL DictionaryNeo::addDictionaryEventListener( + const Reference< XDictionaryEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + if (xListener.is()) + { + INT32 nCount = aDicEvtListeners.getLength(); + bRes = aDicEvtListeners.addInterface( xListener ) != nCount; + } + return bRes; +} + +sal_Bool SAL_CALL DictionaryNeo::removeDictionaryEventListener( + const Reference< XDictionaryEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + if (xListener.is()) + { + INT32 nCount = aDicEvtListeners.getLength(); + bRes = aDicEvtListeners.removeInterface( xListener ) != nCount; + } + return bRes; +} + + +sal_Bool SAL_CALL DictionaryNeo::hasLocation() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aMainURL.getLength() > 0; +} + +OUString SAL_CALL DictionaryNeo::getLocation() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aMainURL; +} + +BOOL DictionaryNeo::isReadonly_Impl() +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + + if (hasLocation()) + { + try + { + Reference< com::sun::star::ucb::XCommandEnvironment > xCmdEnv; + ::ucb::Content aContent( getLocation(), xCmdEnv ); + Any aAny( aContent.getPropertyValue( A2OU( "IsReadOnly" ) ) ); + aAny >>= bRes; + } + catch (::ucb::ContentCreationException &) + { + bRes = TRUE; + } + } + + return bRes; +} + +sal_Bool SAL_CALL DictionaryNeo::isReadonly() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + return bIsReadonly; +} + +void SAL_CALL DictionaryNeo::store() + throw(io::IOException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bIsModified && hasLocation() && !isReadonly()) + { + if (saveEntries( aMainURL )) + { +#ifdef LINGU_EXCEPTIONS + throw io::IOException(); +#endif + } + else + bIsModified = FALSE; + } +} + +void SAL_CALL DictionaryNeo::storeAsURL( + const OUString& aURL, + const uno::Sequence< beans::PropertyValue >& aArgs ) + throw(io::IOException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (saveEntries( aURL )) + { +#ifdef LINGU_EXCEPTIONS + throw io::IOException(); +#endif + } + else + { + aMainURL = aURL; + bIsModified = FALSE; + bIsReadonly = isReadonly_Impl(); + } +} + +void SAL_CALL DictionaryNeo::storeToURL( + const OUString& aURL, + const uno::Sequence< beans::PropertyValue >& aArgs ) + throw(io::IOException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (saveEntries( aURL )) + { +#ifdef LINGU_EXCEPTIONS + throw io::IOException(); +#endif + } +} + +/////////////////////////////////////////////////////////////////////////// + +DicEntry::DicEntry() +{ + bIsNegativ = FALSE; +} + +DicEntry::DicEntry(const OUString &rDicFileWord, + BOOL bIsNegativWord) +{ + if (rDicFileWord.getLength()) + splitDicFileWord( rDicFileWord, aDicWord, aReplacement ); + bIsNegativ = bIsNegativWord; +} + +DicEntry::DicEntry(const OUString &rDicWord, BOOL bNegativ, + const OUString &rRplcText) : + aDicWord (rDicWord), + bIsNegativ (bNegativ), + aReplacement (rRplcText) +{ +} + +DicEntry::~DicEntry() +{ +} + +void DicEntry::splitDicFileWord(const OUString &rDicFileWord, + OUString &rDicWord, + OUString &rReplacement) +{ + MutexGuard aGuard( GetLinguMutex() ); + + static const OUString aDelim( A2OU( "==" ) ); + + sal_Int32 nDelimPos = rDicFileWord.indexOf( aDelim ); + if (-1 != nDelimPos) + { + xub_StrLen nTriplePos = nDelimPos + 2; + if ( nTriplePos < rDicFileWord.getLength() + && rDicFileWord[ nTriplePos ] == '=' ) + ++nDelimPos; + rDicWord = rDicFileWord.copy( 0, nDelimPos ); + rReplacement = rDicFileWord.copy( nDelimPos + 2 ); + } + else + { + rDicWord = rDicFileWord; + rReplacement = OUString(); + } +} + +OUString SAL_CALL DicEntry::getDictionaryWord( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aDicWord; +} + +sal_Bool SAL_CALL DicEntry::isNegative( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return bIsNegativ; +} + +OUString SAL_CALL DicEntry::getReplacementText( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aReplacement; +} + + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/dicimp.hxx b/linguistic/source/dicimp.hxx new file mode 100644 index 000000000000..04988b3bc606 --- /dev/null +++ b/linguistic/source/dicimp.hxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * $RCSfile: dicimp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:32 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_DICIMP_HXX_ +#define _LINGUISTIC_DICIMP_HXX_ + +#include <com/sun/star/linguistic2/XDictionary1.hpp> +#include <com/sun/star/linguistic2/XDictionary.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase3.hxx> // helper for implementations + +#ifndef _CPPUHELPER_INTERFACECONTAINER_H_ +#include <cppuhelper/interfacecontainer.h> +#endif + +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif + +#include "misc.hxx" + + +/////////////////////////////////////////////////////////////////////////// + +#define DIC_MAX_ENTRIES 2000 + +/////////////////////////////////////////////////////////////////////////// + +class DictionaryNeo : + public ::cppu::WeakImplHelper3 + < + ::com::sun::star::linguistic2::XDictionary1, + ::com::sun::star::linguistic2::XDictionary, + ::com::sun::star::frame::XStorable + > +{ + + ::cppu::OInterfaceContainerHelper aDicEvtListeners; + ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > > aEntries; + ::rtl::OUString aDicName; + ::rtl::OUString aMainURL; + ::com::sun::star::linguistic2::DictionaryType eDicType; + INT16 nCount; + INT16 nLanguage; + BOOL bNeedEntries; + BOOL bIsModified; + BOOL bIsActive; + BOOL bIsReadonly; + + // disallow copy-constructor and assignment-operator for now + DictionaryNeo(const DictionaryNeo &); + DictionaryNeo & operator = (const DictionaryNeo &); + + void launchEvent(INT16 nEvent, + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > xEntry); + + ULONG loadEntries(const ::rtl::OUString &rMainURL); + ULONG saveEntries(const ::rtl::OUString &rMainURL); + int cmpDicEntry(const ::rtl::OUString &rWord1, + const ::rtl::OUString &rWord2, + BOOL bSimilarOnly = FALSE); + BOOL seekEntry(const ::rtl::OUString &rWord, INT32 *pPos, + BOOL bSimilarOnly = FALSE); + BOOL isSorted(); + + BOOL addEntry_Impl(const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > xDicEntry, + BOOL bIsLoadEntries = FALSE); + BOOL isReadonly_Impl(); + +public: + DictionaryNeo(); + DictionaryNeo(const ::rtl::OUString &rName, INT16 nLang, + ::com::sun::star::linguistic2::DictionaryType eType, + const ::rtl::OUString &rMainURL); + virtual ~DictionaryNeo(); + + // XNamed + virtual ::rtl::OUString SAL_CALL + getName() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setName( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + // XDictionary1 (same as XDictionary but for sal_Int16 as language) + // only the different ones are listed + virtual sal_Int16 SAL_CALL + getLanguage() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setLanguage( sal_Int16 nLang ) + throw(::com::sun::star::uno::RuntimeException); + + // XDictionary + virtual ::com::sun::star::linguistic2::DictionaryType SAL_CALL + getDictionaryType() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setActive( sal_Bool bActivate ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + isActive() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL + getCount() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL + getLocale() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setLocale( const ::com::sun::star::lang::Locale& aLocale ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > SAL_CALL + getEntry( const ::rtl::OUString& aWord ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + addEntry( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry >& xDicEntry ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + add( const ::rtl::OUString& aWord, sal_Bool bIsNegative, + const ::rtl::OUString& aRplcText ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + remove( const ::rtl::OUString& aWord ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + isFull() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > > SAL_CALL + getEntries() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + clear() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + addDictionaryEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + removeDictionaryEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + + // XStorable + virtual sal_Bool SAL_CALL + hasLocation() + throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL + getLocation() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + isReadonly() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + store() + throw(::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + storeAsURL( const ::rtl::OUString& aURL, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& aArgs ) + throw(::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + storeToURL( const ::rtl::OUString& aURL, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& aArgs ) + throw(::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException); +}; + + +/////////////////////////////////////////////////////////////////////////// + +class DicEntry : + public cppu::WeakImplHelper1 + < + ::com::sun::star::linguistic2::XDictionaryEntry + > +{ + ::rtl::OUString aDicWord, // including hyphen positions represented by "=" + aReplacement; // including hyphen positions represented by "=" + BOOL bIsNegativ; + + // disallow copy-constructor and assignment-operator for now + DicEntry(const DicEntry &); + DicEntry & operator = (const DicEntry &); + + void splitDicFileWord(const ::rtl::OUString &rDicFileWord, + ::rtl::OUString &rDicWord, + ::rtl::OUString &rReplacement); + +public: + DicEntry(); + DicEntry(const ::rtl::OUString &rDicFileWord, BOOL bIsNegativ); + DicEntry(const ::rtl::OUString &rDicWord, BOOL bIsNegativ, + const ::rtl::OUString &rRplcText); + virtual ~DicEntry(); + + // XDictionaryEntry + virtual ::rtl::OUString SAL_CALL + getDictionaryWord() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + isNegative() throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL + getReplacementText() throw(::com::sun::star::uno::RuntimeException); +}; + + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/source/dlistimp.cxx b/linguistic/source/dlistimp.cxx new file mode 100644 index 000000000000..b2dc0cf0bb8a --- /dev/null +++ b/linguistic/source/dlistimp.cxx @@ -0,0 +1,980 @@ +/************************************************************************* + * + * $RCSfile: dlistimp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "dlistimp.hxx" +#include "dicimp.hxx" + +#ifndef _FSYS_HXX +#include <tools/fsys.hxx> +#endif +#ifndef _TOOLS_INTN_HXX +#include <tools/intn.hxx> +#endif +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif +#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX +#include <svtools/pathoptions.hxx> +#endif +#ifndef INCLUDED_SVTOOLS_USEROPTIONS_HXX +#include <svtools/useroptions.hxx> +#endif +#ifndef _SFXDOCFILE_HXX +#include <sfx2/docfile.hxx> +#endif +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif +#include <cppuhelper/factory.hxx> // helper for factories + +#ifndef _COM_SUN_STAR_FRAME_XSTORABLE_HPP_ +#include <com/sun/star/frame/XStorable.hpp> +#endif +#include <com/sun/star/lang/Locale.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/registry/XRegistryKey.hpp> + +//using namespace utl; +using namespace osl; +using namespace rtl; +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; + +/////////////////////////////////////////////////////////////////////////// + +SV_IMPL_OBJARR(ActDicArray, ActDic); + +/////////////////////////////////////////////////////////////////////////// + +#define BUFSIZE 256 +#define VERS2_NOLANGUAGE 1024 + +static sal_Char aBuf[ BUFSIZE ]; +static const sal_Char* aDicExt = "dic"; +static const sal_Char* aVerStr2 = "WBSWG2"; +static const sal_Char* aVerStr5 = "WBSWG5"; + + +// forward dedclarations + +static BOOL IsVers2( const DirEntry& rPathName, USHORT& nLng, BOOL& bNeg, + sal_Char* pWordBuf); + +static void AddInternal( Reference< XDictionary > &rDic, + const OUString& rNew ); +static void AddUserData( const Reference< XDictionary > &rDic ); + +/////////////////////////////////////////////////////////////////////////// + +class DicEvtListenerHelper : + public cppu::WeakImplHelper1 + < + XDictionaryEventListener + > +{ + cppu::OInterfaceContainerHelper aDicListEvtListeners; + Sequence< DictionaryEvent > aCollectDicEvt; + Reference< XDictionaryList > xMyDicList; + + INT16 nCondensedEvt; + INT16 nNumCollectEvtListeners, + nNumVerboseListeners; + +public: + DicEvtListenerHelper( const Reference< XDictionaryList > &rxDicList ); + virtual ~DicEvtListenerHelper(); + + // XEventListener + virtual void SAL_CALL + disposing( const EventObject& rSource ) + throw(RuntimeException); + + // XDictionaryEventListener + virtual void SAL_CALL + processDictionaryEvent( const DictionaryEvent& rDicEvent ) + throw(RuntimeException); + + // non-UNO functions + void DisposeAndClear( const EventObject &rEvtObj ); + + BOOL AddDicListEvtListener( + const Reference< XDictionaryListEventListener >& rxListener, + BOOL bReceiveVerbose ); + BOOL RemoveDicListEvtListener( + const Reference< XDictionaryListEventListener >& rxListener ); + INT16 BeginCollectEvents(); + INT16 EndCollectEvents(); + INT16 FlushEvents(); +}; + + +DicEvtListenerHelper::DicEvtListenerHelper( + const Reference< XDictionaryList > &rxDicList ) : + aDicListEvtListeners ( GetLinguMutex() ), + xMyDicList ( rxDicList ) +{ + nCondensedEvt = 0; + nNumCollectEvtListeners = nNumVerboseListeners = 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 ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XInterface > xSrc( rSource.Source ); + + // 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. + Reference< XDictionary > xDic( xSrc, UNO_QUERY ); + if (xDic.is()) + { + xMyDicList->removeDictionary( xDic ); + } +} + + +void SAL_CALL DicEvtListenerHelper::processDictionaryEvent( + const DictionaryEvent& rDicEvent ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + 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 + Reference< XDictionaryEntry > xDicEntry( rDicEvent.xDictionaryEntry, UNO_QUERY ); + DBG_ASSERT( !(rDicEvent.nEvent & + (DictionaryEventFlags::ADD_ENTRY | DictionaryEventFlags::DEL_ENTRY)) + || xDicEntry.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 |= xDicEntry->isNegative() ? + DictionaryListEventFlags::ADD_NEG_ENTRY : + DictionaryListEventFlags::ADD_POS_ENTRY; + if ((rDicEvent.nEvent & DictionaryEventFlags::DEL_ENTRY) && xDic->isActive()) + nCondensedEvt |= xDicEntry->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; + + // update list of collected events if needs to be + if (nNumVerboseListeners > 0) + { + INT32 nColEvts = aCollectDicEvt.getLength(); + aCollectDicEvt.realloc( nColEvts + 1 ); + aCollectDicEvt.getArray()[ nColEvts ] = rDicEvent; + } + + if (nNumCollectEvtListeners == 0 && nCondensedEvt != 0) + FlushEvents(); +} + + +BOOL DicEvtListenerHelper::AddDicListEvtListener( + const Reference< XDictionaryListEventListener >& xListener, + BOOL bReceiveVerbose ) +{ + DBG_ASSERT( xListener.is(), "empty reference" ); + INT32 nCount = aDicListEvtListeners.getLength(); + return aDicListEvtListeners.addInterface( xListener ) != nCount; +} + + +BOOL DicEvtListenerHelper::RemoveDicListEvtListener( + const Reference< XDictionaryListEventListener >& xListener ) +{ + DBG_ASSERT( xListener.is(), "empty reference" ); + INT32 nCount = aDicListEvtListeners.getLength(); + return aDicListEvtListeners.removeInterface( xListener ) != nCount; +} + + +INT16 DicEvtListenerHelper::BeginCollectEvents() +{ + return ++nNumCollectEvtListeners; +} + + +INT16 DicEvtListenerHelper::EndCollectEvents() +{ + DBG_ASSERT(nNumCollectEvtListeners > 0, "lng: mismatched function call"); + if (nNumCollectEvtListeners > 0) + { + FlushEvents(); + nNumCollectEvtListeners--; + } + + return nNumCollectEvtListeners; +} + + +INT16 DicEvtListenerHelper::FlushEvents() +{ + // build DictionaryListEvent to pass on to listeners + uno::Sequence< DictionaryEvent > aDicEvents; + if (nNumVerboseListeners > 0) + aDicEvents = aCollectDicEvt; + DictionaryListEvent aEvent( xMyDicList, nCondensedEvt, aDicEvents ); + + // pass on event + cppu::OInterfaceIteratorHelper aIt( aDicListEvtListeners ); + while (aIt.hasMoreElements()) + { + Reference< XDictionaryListEventListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->processDictionaryListEvent( aEvent ); + } + + // clear "list" of events + nCondensedEvt = 0; + aCollectDicEvt.realloc( 0 ); + + return nNumCollectEvtListeners; +} + + +/////////////////////////////////////////////////////////////////////////// + + +void DicList::MyAppExitListener::AtExit() +{ + // save (modified) dictionaries + Sequence< Reference< XDictionary > > aDics( rMyDicList.getDictionaries() ); + Reference< XDictionary > *pDic = aDics.getArray(); + INT32 nCount = aDics.getLength(); + for (INT32 i = 0; i < nCount; i++) + { + // save (modified) dictionaries + Reference< frame::XStorable > xStor( pDic[i] , UNO_QUERY ); + if (xStor.is()) + { + try + { + if (!xStor->isReadonly() && xStor->hasLocation()) + xStor->store(); + } + catch(...) + { + } + } + } +} + + +DicList::DicList() : + aEvtListeners ( GetLinguMutex() ) +{ + pDicEvtLstnrHelper = new DicEvtListenerHelper( this ); + xDicEvtLstnrHelper = pDicEvtLstnrHelper; + bDisposing = FALSE; + + // look for dictionaries + SvtPathOptions aPathOpt; + searchForDictionaries( aDicList, aPathOpt.GetUserDictionaryPath() ); + searchForDictionaries( aDicList, aPathOpt.GetDictionaryPath() ); + + // create IgnoreAllList dictionary with empty URL (non persistent) + // and add it to list + OUString aDicName( A2OU( "IgnoreAllList" ) ); + Reference< XDictionary > xIgnAll( + createDictionary( aDicName, CreateLocale( LANGUAGE_NONE ), + DictionaryType_POSITIVE, OUString() ) ); + if (xIgnAll.is()) + { + AddUserData( xIgnAll ); + xIgnAll->setActive( TRUE ); + addDictionary( xIgnAll ); + } + + pExitListener = new MyAppExitListener( *this ); + xExitListener = pExitListener; + pExitListener->Activate(); + + // evaluate list of dictionaries to be activated from configuration + const Sequence< OUString > aActiveDics( aOpt.GetCfgActiveDictionaries() ); + const OUString *pActiveDic = aActiveDics.getConstArray(); + INT32 nLen = aActiveDics.getLength(); + for (INT32 i = 0; i < nLen; ++i) + { + if (pActiveDic[i].getLength()) + { + Reference< XDictionary > xDic( getDictionaryByName( pActiveDic[i] ) ); + if (xDic.is()) + xDic->setActive( TRUE ); + } + } +} + +DicList::~DicList() +{ + pExitListener->Deactivate(); +} + + +void DicList::searchForDictionaries( ActDicArray &rDicList, + const String &rDicDir ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // get DirEntry for dictionaries directory + DirEntry aDicDir( rDicDir ); + aDicDir.ToAbs(); + + // Alle auf Platte stehenden Dictionary-Names einlesen + String aDirTmp( String::CreateFromAscii( "*.*" ) ); + aDicDir += DirEntry( aDirTmp ); + Dir aDir(aDicDir, FSYS_KIND_FILE, FSYS_SORT_END); + + String aDCN( String::CreateFromAscii( "dcn" ) ); + String aDCP( String::CreateFromAscii( "dcp" ) ); + INetURLObject aURLObject; + aURLObject.SetSmartProtocol( INET_PROT_FILE ); + for (USHORT i=0; i < aDir.Count(); ++i) + { + String aName(aDir[i].GetName()); + USHORT nLang = LANGUAGE_NONE; + BOOL bNeg = FALSE; + + if(!::IsVers2(aDir[i], nLang, bNeg, aBuf)) + { + // Wenn kein + xub_StrLen nPos = aName.Search('.'); + String aExt(aName.Copy(nPos + 1)); + aExt.ToLowerAscii(); + + if(aExt == aDCN) // negativ + bNeg = TRUE; + else if(aExt == aDCP) // positiv + bNeg = FALSE; + else + continue; // andere Files + } + + // Aufnehmen in die Liste der Dictionaries + // Wenn existent nicht aufnehmen + // + INT16 nSystemLanguage = ::GetSystemLanguage(); + String aTmp1 = ToLower( aName, nSystemLanguage ); + String aTmp2; + INT32 j; + INT32 nCount = rDicList.Count(); + for(j = 0; j < nCount; j++) + { + aTmp2 = rDicList.GetObject( j ).xDic->getName().getStr(); + aTmp2 = ToLower( aTmp2, nSystemLanguage ); + if(aTmp1 == aTmp2) + break; + } + if(j >= nCount) // dictionary not yet in DicList + { + String aFileName (rDicDir); + aFileName += DirEntry::GetAccessDelimiter(); + aFileName += aName; + aURLObject.SetSmartURL( aFileName ); + DBG_ASSERT(!aURLObject.HasError(), "lng : invalid URL"); + + DictionaryType eType = bNeg ? DictionaryType_NEGATIVE : DictionaryType_POSITIVE; + Reference< XDictionary > xDic = + new DictionaryNeo( aName, nLang, eType, + aURLObject.GetMainURL() ); + + addDictionary( xDic ); + nCount++; + } + } +} + + +INT32 DicList::getDicPos(const Reference< XDictionary > &xDic) +{ + MutexGuard aGuard( GetLinguMutex() ); + + INT32 nPos = -1; + INT32 n = aDicList.Count(); + for (INT32 i = 0; i < n; i++) + { + if (aDicList.GetObject(i).xDic == xDic) + return i; + } + return nPos; +} + + +Reference< XInterface > SAL_CALL + DicList_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) + throw(Exception) +{ + Reference< XInterface > xService = (cppu::OWeakObject *) new DicList; + return xService; +} + +sal_Int16 SAL_CALL DicList::getCount() throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aDicList.Count(); +} + +uno::Sequence< Reference< XDictionary > > SAL_CALL + DicList::getDictionaries() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< Reference< XDictionary > > aDics( aDicList.Count() ); + Reference< XDictionary > *pDic = aDics.getArray(); + + INT32 n = aDics.getLength(); + for (INT32 i = 0; i < n; i++) + pDic[i] = aDicList.GetObject(i).xDic; + + return aDics; +} + +Reference< XDictionary > SAL_CALL + DicList::getDictionaryByName( const OUString& aDictionaryName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XDictionary > xDic; + INT32 nCount = aDicList.Count(); + for (INT32 i = 0; i < nCount; i++) + { + const Reference< XDictionary > &rDic = aDicList.GetObject(i).xDic; + if (rDic.is() && rDic->getName() == aDictionaryName) + { + xDic = rDic; + break; + } + } + + return xDic; +} + +sal_Bool SAL_CALL DicList::addDictionary( + const Reference< XDictionary >& xDictionary ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bDisposing) + return FALSE; + + BOOL bRes = FALSE; + if (xDictionary.is()) + { + aDicList.Insert( ActDic(xDictionary), aDicList.Count() ); + bRes = TRUE; + + // add listener helper to the dictionaries listener lists + xDictionary->addDictionaryEventListener( xDicEvtLstnrHelper ); + } + return bRes; +} + +sal_Bool SAL_CALL + DicList::removeDictionary( const Reference< XDictionary >& xDictionary ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bDisposing) + return FALSE; + + BOOL bRes = FALSE; + INT32 nPos = getDicPos( xDictionary ); + if (nPos >= 0) + { + // remove dictionary list from the dictionaries listener lists + Reference< XDictionary > xDic( aDicList.GetObject( nPos ).xDic ); + DBG_ASSERT(xDic.is(), "lng : empty reference"); + if (xDic.is()) + { + // deactivate dictionary if not already done + xDic->setActive( FALSE ); + + xDic->removeDictionaryEventListener( xDicEvtLstnrHelper ); + } + + aDicList.Remove(nPos); + bRes = TRUE; + } + return bRes; +} + +sal_Bool SAL_CALL DicList::addDictionaryListEventListener( + const Reference< XDictionaryListEventListener >& xListener, + sal_Bool bReceiveVerbose ) + throw(RuntimeException) +{ + 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 = pDicEvtLstnrHelper-> + AddDicListEvtListener( xListener, bReceiveVerbose ); + } + return bRes; +} + +sal_Bool SAL_CALL DicList::removeDictionaryListEventListener( + const Reference< XDictionaryListEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (bDisposing) + return FALSE; + + BOOL bRes = FALSE; + if(xListener.is()) + { + bRes = pDicEvtLstnrHelper->RemoveDicListEvtListener( xListener ); + } + return bRes; +} + +sal_Int16 SAL_CALL DicList::beginCollectEvents() throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return pDicEvtLstnrHelper->BeginCollectEvents(); +} + +sal_Int16 SAL_CALL DicList::endCollectEvents() throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return pDicEvtLstnrHelper->EndCollectEvents(); +} + +sal_Int16 SAL_CALL DicList::flushEvents() throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return pDicEvtLstnrHelper->FlushEvents(); +} + +Reference< XDictionary > SAL_CALL + DicList::createDictionary( const OUString& rName, const Locale& rLocale, + DictionaryType eDicType, const OUString& rURL ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + INT16 nLanguage = LocaleToLanguage( rLocale ); + return new DictionaryNeo( rName, nLanguage, eDicType, rURL ); +} + + +Reference< XDictionaryEntry > SAL_CALL + DicList::queryDictionaryEntry( const OUString& rWord, const Locale& rLocale, + sal_Bool bSearchPosDics, sal_Bool bSearchSpellEntry ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return SearchDicList( this, rWord, LocaleToLanguage( rLocale ), + bSearchPosDics, bSearchSpellEntry ); +} + + +void SAL_CALL + DicList::dispose() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing) + { + bDisposing = TRUE; + EventObject aEvtObj( (XDictionaryList *) this ); + + aEvtListeners.disposeAndClear( aEvtObj ); + if (pDicEvtLstnrHelper) + pDicEvtLstnrHelper->DisposeAndClear( aEvtObj ); + + INT16 nCount = aDicList.Count(); + for (INT16 i = 0; i < nCount; i++) + { + Reference< XDictionary > xDic( aDicList.GetObject(i).xDic , UNO_QUERY ); + + // save (modified) dictionaries + Reference< frame::XStorable > xStor( xDic , UNO_QUERY ); + if (xStor.is()) + { + try + { + if (!xStor->isReadonly() && xStor->hasLocation()) + xStor->store(); + } + catch(...) + { + } + } + + // release references to (members of) this object hold by + // dictionaries + if (xDic.is()) + xDic->removeDictionaryEventListener( xDicEvtLstnrHelper ); + } + + // set list of active dictionaries in configuration + aOpt.SetCfgActiveDictionaries( Reference< XDictionaryList >( this )); + } +} + +void SAL_CALL + DicList::addEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.addInterface( rxListener ); +} + +void SAL_CALL + DicList::removeEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.removeInterface( rxListener ); +} + + +/////////////////////////////////////////////////////////////////////////// +// Service specific part +// + +OUString SAL_CALL DicList::getImplementationName( ) throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getImplementationName_Static(); +} + + +sal_Bool SAL_CALL DicList::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( INT32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return TRUE; + return FALSE; +} + + +uno::Sequence< OUString > SAL_CALL DicList::getSupportedServiceNames( ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getSupportedServiceNames_Static(); +} + + +uno::Sequence< OUString > DicList::getSupportedServiceNames_Static() throw() +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich + aSNS.getArray()[0] = A2OU( SN_DICTIONARY_LIST ); + return aSNS; +} + + +sal_Bool SAL_CALL DicList_writeInfo( + void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey ) +{ + try + { + String aImpl( '/' ); + aImpl += DicList::getImplementationName_Static().getStr(); + aImpl.AppendAscii( "/UNO/SERVICES" ); + Reference< registry::XRegistryKey > xNewKey = + pRegistryKey->createKey(aImpl ); + uno::Sequence< OUString > aServices = + DicList::getSupportedServiceNames_Static(); + for( INT32 i = 0; i < aServices.getLength(); i++ ) + xNewKey->createKey( aServices.getConstArray()[i]); + + return sal_True; + } + catch(Exception &) + { + return sal_False; + } +} + + +void * SAL_CALL DicList_getFactory( const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, void * ) +{ + void * pRet = 0; + if ( !DicList::getImplementationName_Static().compareToAscii( pImplName ) ) + { + Reference< XSingleServiceFactory > xFactory = + cppu::createOneInstanceFactory( + pServiceManager, + DicList::getImplementationName_Static(), + DicList_CreateInstance, + DicList::getSupportedServiceNames_Static()); + // acquire, because we return an interface pointer instead of a reference + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + +/////////////////////////////////////////////////////////////////////////// + +xub_StrLen lcl_GetToken( String &rToken, + const String &rText, xub_StrLen nPos, const String &rDelim ) +{ + xub_StrLen nRes = STRING_LEN; + + if (rText.Len() == 0 || nPos >= rText.Len()) + rToken = String(); + else if (rDelim.Len() == 0) + { + rToken = rText; + if (rToken.Len()) + nRes = rText.Len(); + } + else + { + xub_StrLen i; + for (i = nPos; i < rText.Len(); ++i) + { + if (STRING_NOTFOUND != rDelim.Search( rText.GetChar(i) )) + break; + } + + if (i >= rText.Len()) // delimeter not found + rToken = rText.Copy( nPos ); + else + rToken = rText.Copy( nPos, (INT32) i - nPos ); + nRes = i + 1; // continue after found delimeter + } + + return nRes; +} + + +static void AddInternal( + const Reference<XDictionary> &rDic, + const OUString& rNew ) +{ + if (rDic.is()) + { + //! TL TODO: word iterator should be used to break up the text + static const char *pDefWordDelim = + "!\"#$%&'()*+,-./:;<=>?[]\\_^`{|}~\t \n"; + ByteString aDummy( pDefWordDelim ); + String aDelim( aDummy , RTL_TEXTENCODING_MS_1252 ); + aDelim.EraseAllChars( '.' ); + + String aToken; + xub_StrLen nPos = 0; + while (STRING_LEN != + (nPos = lcl_GetToken( aToken, rNew, nPos, aDelim ))) + { + if( aToken.Len() && !IsNumeric( aToken ) ) + { + rDic->add( aToken, FALSE, OUString() ); + } + } + } +} + +static void AddUserData( const 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() ); + } +} + +/////////////////////////////////////////////////////////////////////////// + +#pragma optimize("ge",off) + +static BOOL IsVers2( const DirEntry& rPathName, USHORT& nLng, BOOL& bNeg, + sal_Char* pWordBuf) +{ + String aDIC( String::CreateFromAscii( aDicExt ) ); + String aExt(rPathName.GetExtension()); + aExt.ToLowerAscii(); + + if(aExt != aDIC) + return FALSE; + + // get binary files URL + INetURLObject aURLObj; + aURLObj.SetSmartProtocol( INET_PROT_FILE ); + aURLObj.SetSmartURL( rPathName.GetFull() ); + String aFileURL( aURLObj.GetMainURL() ); + + // get stream to be used + SfxMedium aMedium( aFileURL, + STREAM_READ | STREAM_SHARE_DENYWRITE, FALSE ); + aMedium.SetTransferPriority( SFX_TFPRIO_SYNCHRON ); + SvStream *pStream = aMedium.GetInStream(); + if (!pStream || pStream->GetError()) + return FALSE; + + // Header einlesen + USHORT nLen; + sal_Char nTmp; + + *pStream >> nLen; + if( nLen >= BUFSIZE ) + return FALSE; + pStream->Read( pWordBuf, nLen); + *( pWordBuf + nLen ) = 0; + // Version 2.0 oder Version 5.0 ? + if( !strcmp( pWordBuf, aVerStr2 ) || !strcmp( pWordBuf, aVerStr5 ) ) + { + // Sprache des Dictionaries + *pStream >> nLng; + + if ( VERS2_NOLANGUAGE == nLng ) + nLng = LANGUAGE_NONE; + + // Negativ-Flag + *pStream >> nTmp; + bNeg = (BOOL)nTmp; + + return TRUE; + } + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/dlistimp.hxx b/linguistic/source/dlistimp.hxx new file mode 100644 index 000000000000..dc55c67ace29 --- /dev/null +++ b/linguistic/source/dlistimp.hxx @@ -0,0 +1,253 @@ +/************************************************************************* + * + * $RCSfile: dlistimp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_DLISTIMP_HXX_ +#define _LINGUISTIC_DLISTIMP_HXX_ + +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_ +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations +#include <cppuhelper/implbase3.hxx> // helper for implementations +#include <cppuhelper/interfacecontainer.h> + +#ifndef _SVARRAY_HXX +#include <svtools/svarray.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif + +#include "misc.hxx" +#include "lngopt.hxx" + +class DicEvtListenerHelper; + +/////////////////////////////////////////////////////////////////////////// + +class ActDic +{ +public: + const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary > xDic; + + ActDic() {} + ActDic(const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary > &rDic) : xDic(rDic) {} +}; +SV_DECL_OBJARR(ActDicArray, ActDic, 16, 16); + +class DicList : + public cppu::WeakImplHelper3 + < + ::com::sun::star::linguistic2::XSearchableDictionaryList, + ::com::sun::star::lang::XComponent, + ::com::sun::star::lang::XServiceInfo + > +{ + class MyAppExitListener : public linguistic::AppExitListener + { + DicList & rMyDicList; + + public: + MyAppExitListener( DicList &rDicList ) : rMyDicList( rDicList ) {} + virtual void AtExit(); + }; + + LinguOptions aOpt; + + ::cppu::OInterfaceContainerHelper aEvtListeners; + ActDicArray aDicList; + + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEventListener > xDicEvtLstnrHelper; + DicEvtListenerHelper *pDicEvtLstnrHelper; + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XTerminateListener > xExitListener; + MyAppExitListener *pExitListener; + + BOOL bDisposing; + + // disallow copy-constructor and assignment-operator for now + DicList(const DicList &); + DicList & operator = (const DicList &); + + void launchEvent(INT16 nEvent, com::sun::star::uno::Sequence< + ::com::sun::star::linguistic2::XDictionary > xDic); + void searchForDictionaries( ActDicArray &rDicList, + const String &rDicDir ); + INT32 getDicPos(const com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary > &xDic); + +public: + DicList(); + virtual ~DicList(); + + // XDictionaryList + virtual sal_Int16 SAL_CALL + getCount() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary > > SAL_CALL + getDictionaries() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary > SAL_CALL + getDictionaryByName( const ::rtl::OUString& aDictionaryName ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + addDictionary( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary >& xDictionary ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + removeDictionary( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary >& xDictionary ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + addDictionaryListEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryListEventListener >& xListener, + sal_Bool bReceiveVerbose ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + removeDictionaryListEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryListEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL + beginCollectEvents() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL + endCollectEvents() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL + flushEvents() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionary > SAL_CALL + createDictionary( const ::rtl::OUString& aName, + const ::com::sun::star::lang::Locale& aLocale, + ::com::sun::star::linguistic2::DictionaryType eDicType, + const ::rtl::OUString& aURL ) + throw(::com::sun::star::uno::RuntimeException); + + // XSearchableDictionaryList + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > SAL_CALL + queryDictionaryEntry( const ::rtl::OUString& aWord, + const ::com::sun::star::lang::Locale& aLocale, + sal_Bool bSearchPosDics, sal_Bool bSpellEntry ) + throw(::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL + dispose() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + addEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + removeEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& aListener ) + throw(::com::sun::star::uno::RuntimeException); + + + //////////////////////////////////////////////////////////// + // Service specific part + // + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL + getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); + + + static inline ::rtl::OUString + getImplementationName_Static() throw(); + static com::sun::star::uno::Sequence< ::rtl::OUString > + getSupportedServiceNames_Static() throw(); +}; + +inline ::rtl::OUString DicList::getImplementationName_Static() throw() +{ + return A2OU( "com.sun.star.lingu2.DicList" ); +} + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/source/hyphdsp.cxx b/linguistic/source/hyphdsp.cxx new file mode 100644 index 000000000000..9616928daf4a --- /dev/null +++ b/linguistic/source/hyphdsp.cxx @@ -0,0 +1,624 @@ +/************************************************************************* + * + * $RCSfile: hyphdsp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#include <cppuhelper/factory.hxx> // helper for factories +#include <com/sun/star/registry/XRegistryKey.hpp> + +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_ +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_XHYPHENATEDWORD_HPP_ +#include <com/sun/star/linguistic2/XHyphenatedWord.hpp> +#endif + +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif +#ifndef _LANG_HXX //autogen wg. LANGUAGE_ENGLISH_US +#include <tools/lang.hxx> +#endif +#ifndef _ISOLANG_HXX +#include <tools/isolang.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#include "hyphdsp.hxx" +#include "hyphdta.hxx" +#include "lngprops.hxx" +#include "lngsvcmgr.hxx" + + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + +/////////////////////////////////////////////////////////////////////////// + +LangSvcEntry_Hyph::~LangSvcEntry_Hyph() +{ +} + + +LangSvcEntry_Hyph::LangSvcEntry_Hyph( const ::rtl::OUString &rSvcImplName ) : + aSvcImplName( rSvcImplName ) +{ +} + +/////////////////////////////////////////////////////////////////////////// + +HyphenatorDispatcher::HyphenatorDispatcher( LngSvcMgr &rLngSvcMgr ) : + rMgr (rLngSvcMgr) +{ +} + + +HyphenatorDispatcher::~HyphenatorDispatcher() +{ + ClearSvcList(); +} + + +void HyphenatorDispatcher::ClearSvcList() +{ + // release memory for each table entry + LangSvcEntry_Hyph *pItem = aSvcList.First(); + while (pItem) + { + LangSvcEntry_Hyph *pTmp = pItem; + pItem = aSvcList.Next(); + delete pTmp; + } +} + + +Reference<XHyphenatedWord> HyphenatorDispatcher::buildHyphWord( + const Reference<XDictionaryEntry> &xEntry, + INT16 nLang, INT16 nMaxLeading ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XHyphenatedWord > xRes; + + if (xEntry.is()) + { + OUString aText( xEntry->getDictionaryWord() ); + INT32 nTextLen = aText.getLength(); + + // trailing '=' means "hyphenation should not be possible" + if (nTextLen > 0 && aText[ nTextLen - 1 ] != '=') + { + INT16 nHyphenationPos = -1; + + OUStringBuffer aTmp( nTextLen ); + BOOL bSkip = FALSE; + INT32 nHyphIdx = -1; + INT32 nLeading = 0; + for (INT32 i = 0; i < nTextLen; i++) + { + sal_Unicode cTmp = aText[i]; + if (cTmp != '=') + { + aTmp.append( cTmp ); + nLeading++; + bSkip = FALSE; + nHyphIdx++; + } + else + { + if (!bSkip && nHyphIdx >= 0) + { + if (nLeading <= nMaxLeading) + nHyphenationPos = nHyphIdx; + } + bSkip = TRUE; //! multiple '=' should count as one only + } + } + + if (nHyphenationPos > 0) + { + aText = aTmp.makeStringAndClear(); + xRes = new HyphenatedWord( aText, nLang, nHyphenationPos, + aText, nHyphenationPos ); + } + } + } + + return xRes; +} + + +Reference< XPossibleHyphens > HyphenatorDispatcher::buildPossHyphens( + const Reference< XDictionaryEntry > &xEntry, INT16 nLanguage ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference<XPossibleHyphens> xRes; + + if (xEntry.is()) + { + // text with hyphenation info + OUString aText( xEntry->getDictionaryWord() ); + INT32 nTextLen = aText.getLength(); + + // trailing '=' means "hyphenation should not be possible" + if (nTextLen > 0 && aText[ nTextLen - 1 ] != '=') + { + // sequence to hold hyphenation positions + Sequence< INT16 > aHyphPos( nTextLen ); + INT16 *pPos = aHyphPos.getArray(); + INT32 nHyphCount = 0; + + OUStringBuffer aTmp( nTextLen ); + BOOL bSkip = FALSE; + INT32 nHyphIdx = -1; + for (INT32 i = 0; i < nTextLen; i++) + { + sal_Unicode cTmp = aText[i]; + if (cTmp != '=') + { + aTmp.append( cTmp ); + bSkip = FALSE; + nHyphIdx++; + } + else + { + if (!bSkip && nHyphIdx >= 0) + pPos[ nHyphCount++ ] = nHyphIdx; + bSkip = TRUE; //! multiple '=' should count as one only + } + } + + // ignore (multiple) trailing '=' + if (bSkip && nHyphIdx >= 0) + { + nHyphCount--; + } + DBG_ASSERT( nHyphCount >= 0, "lng : invalid hyphenation count"); + + if (nHyphCount > 0) + { + aHyphPos.realloc( nHyphCount ); + xRes = new PossibleHyphens( aTmp.makeStringAndClear(), nLanguage, + aText, aHyphPos ); + } + } + } + + return xRes; +} + + +Sequence< Locale > SAL_CALL HyphenatorDispatcher::getLocales() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + ULONG nCnt = aSvcList.Count(); + Sequence< Locale > aLocales( nCnt ); + Locale *pItem = aLocales.getArray(); + LangSvcEntry_Hyph *pEntry = aSvcList.First(); + for (ULONG i = 0; i < nCnt; i++) + { + DBG_ASSERT( pEntry, "lng : pEntry is NULL pointer" ); + pItem[i] = CreateLocale( aSvcList.GetKey( pEntry ) ); + pEntry = aSvcList.Next(); + } + return aLocales; +} + + +BOOL SAL_CALL HyphenatorDispatcher::hasLocale(const Locale& rLocale) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return 0 != aSvcList.Seek( LocaleToLanguage( rLocale ) ); +} + + +Reference< XHyphenatedWord > SAL_CALL + HyphenatorDispatcher::hyphenate( + const OUString& rWord, const Locale& rLocale, sal_Int16 nMaxLeading, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XHyphenatedWord > xRes; + + INT16 nLanguage = LocaleToLanguage( rLocale ); + if (nLanguage == LANGUAGE_NONE || !rWord.getLength()) + return xRes; + + // search for entry with that language + LangSvcEntry_Hyph *pEntry = aSvcList.Seek( nLanguage ); + + if (!pEntry) + { +#ifdef LINGU_EXCEPTIONS + throw IllegalArgumentException(); +#endif + } + else + { + // check for results from (positive) dictionaries which have precedence! + Reference< XDictionaryEntry > xEntry; + + if (GetDicList().is() && IsUseDicList( rProperties, GetPropSet() )) + { + xEntry = GetDicList()->queryDictionaryEntry( rWord, rLocale, + TRUE, FALSE ); + } + + if (xEntry.is()) + { + xRes = buildHyphWord( xEntry, nLanguage, nMaxLeading ); + } + else + { + INT32 nLen = pEntry->aSvcImplName.getLength() ? 1 : 0; + DBG_ASSERT( pEntry->aFlags.nLastTriedSvcIndex < nLen, + "lng : index out of range"); + + INT32 i = 0; + Reference< XHyphenator > &rHyph = pEntry->aSvcRef; + + // try already instantiated service + if (i <= pEntry->aFlags.nLastTriedSvcIndex) + { + if (rHyph.is()) + xRes = rHyph->hyphenate( rWord, rLocale, nMaxLeading, + rProperties ); + ++i; + } + else if (pEntry->aFlags.nLastTriedSvcIndex < nLen - 1) + // instantiate services and try it + { + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + // build service initialization argument + Sequence< Any > aArgs(2); + aArgs.getArray()[0] <<= GetPropSet(); + //! The dispatcher searches the dictionary-list + //! thus the service needs not to now about it + //aArgs.getArray()[1] <<= GetDicList(); + + // create specific service via it's implementation name + Reference< XHyphenator > xHyph( + xMgr->createInstanceWithArguments( + pEntry->aSvcImplName, aArgs ), + UNO_QUERY ); + rHyph = xHyph; + + Reference< XLinguServiceEventBroadcaster > + xBroadcaster( xHyph, UNO_QUERY ); + if (xBroadcaster.is()) + rMgr.AddLngSvcEvtBroadcaster( xBroadcaster ); + + if (rHyph.is()) + xRes = rHyph->hyphenate( rWord, rLocale, nMaxLeading, + rProperties ); + + pEntry->aFlags.nLastTriedSvcIndex = i; + ++i; + } + } + } // if (xEntry.is()) + } + + return xRes; +} + + +Reference< XHyphenatedWord > SAL_CALL + HyphenatorDispatcher::queryAlternativeSpelling( + const OUString& rWord, const Locale& rLocale, sal_Int16 nIndex, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XHyphenatedWord > xRes; + + INT16 nLanguage = LocaleToLanguage( rLocale ); + if (nLanguage == LANGUAGE_NONE || !rWord.getLength()) + return xRes; + + // search for entry with that language + LangSvcEntry_Hyph *pEntry = aSvcList.Seek( nLanguage ); + + if (!pEntry) + { +#ifdef LINGU_EXCEPTIONS + throw IllegalArgumentException(); +#endif + } + else + { + // check for results from (positive) dictionaries which have precedence! + Reference< XDictionaryEntry > xEntry; + + if (GetDicList().is() && IsUseDicList( rProperties, GetPropSet() )) + { + xEntry = GetDicList()->queryDictionaryEntry( rWord, rLocale, + TRUE, FALSE ); + } + + if (xEntry.is()) + { + //! alternative spellings not yet supported by dictionaries + } + else + { + INT32 nLen = pEntry->aSvcImplName.getLength() ? 1 : 0; + DBG_ASSERT( pEntry->aFlags.nLastTriedSvcIndex < nLen, + "lng : index out of range"); + + INT32 i = 0; + Reference< XHyphenator > &rHyph = pEntry->aSvcRef; + + // try already instantiated service + if (i <= pEntry->aFlags.nLastTriedSvcIndex) + { + if (rHyph.is()) + xRes = rHyph->queryAlternativeSpelling( rWord, rLocale, + nIndex, rProperties ); + ++i; + } + else if (pEntry->aFlags.nLastTriedSvcIndex < nLen - 1) + // instantiate services and try it + { + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + // build service initialization argument + Sequence< Any > aArgs(2); + aArgs.getArray()[0] <<= GetPropSet(); + //! The dispatcher searches the dictionary-list + //! thus the service needs not to now about it + //aArgs.getArray()[1] <<= GetDicList(); + + // create specific service via it's implementation name + Reference< XHyphenator > xHyph( + xMgr->createInstanceWithArguments( + pEntry->aSvcImplName, aArgs ), + UNO_QUERY ); + rHyph = xHyph; + + Reference< XLinguServiceEventBroadcaster > + xBroadcaster( xHyph, UNO_QUERY ); + if (xBroadcaster.is()) + rMgr.AddLngSvcEvtBroadcaster( xBroadcaster ); + + if (rHyph.is()) + xRes = rHyph->queryAlternativeSpelling( rWord, rLocale, + nIndex, rProperties ); + + pEntry->aFlags.nLastTriedSvcIndex = i; + ++i; + } + } + } // if (xEntry.is()) + } + + return xRes; +} + + +Reference< XPossibleHyphens > SAL_CALL + HyphenatorDispatcher::createPossibleHyphens( + const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XPossibleHyphens > xRes; + + INT16 nLanguage = LocaleToLanguage( rLocale ); + if (nLanguage == LANGUAGE_NONE || !rWord.getLength()) + return xRes; + + // search for entry with that language + LangSvcEntry_Hyph *pEntry = aSvcList.Seek( nLanguage ); + + if (!pEntry) + { +#ifdef LINGU_EXCEPTIONS + throw IllegalArgumentException(); +#endif + } + else + { + // check for results from (positive) dictionaries which have precedence! + Reference< XDictionaryEntry > xEntry; + + if (GetDicList().is() && IsUseDicList( rProperties, GetPropSet() )) + { + xEntry = GetDicList()->queryDictionaryEntry( rWord, rLocale, + TRUE, FALSE ); + } + + if (xEntry.is()) + { + xRes = buildPossHyphens( xEntry, nLanguage ); + } + else + { + INT32 nLen = pEntry->aSvcImplName.getLength() ? 1 : 0; + DBG_ASSERT( pEntry->aFlags.nLastTriedSvcIndex < nLen, + "lng : index out of range"); + + INT32 i = 0; + Reference< XHyphenator > &rHyph = pEntry->aSvcRef; + + // try already instantiated service + if (i <= pEntry->aFlags.nLastTriedSvcIndex) + { + if (rHyph.is()) + xRes = rHyph->createPossibleHyphens( rWord, rLocale, + rProperties ); + ++i; + } + else if (pEntry->aFlags.nLastTriedSvcIndex < nLen - 1) + // instantiate services and try it + { + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + // build service initialization argument + Sequence< Any > aArgs(2); + aArgs.getArray()[0] <<= GetPropSet(); + //! The dispatcher searches the dictionary-list + //! thus the service needs not to now about it + //aArgs.getArray()[1] <<= GetDicList(); + + // create specific service via it's implementation name + Reference< XHyphenator > xHyph( + xMgr->createInstanceWithArguments( + pEntry->aSvcImplName, aArgs ), + UNO_QUERY ); + rHyph = xHyph; + + Reference< XLinguServiceEventBroadcaster > + xBroadcaster( xHyph, UNO_QUERY ); + if (xBroadcaster.is()) + rMgr.AddLngSvcEvtBroadcaster( xBroadcaster ); + + if (rHyph.is()) + xRes = rHyph->createPossibleHyphens( rWord, rLocale, + rProperties ); + + pEntry->aFlags.nLastTriedSvcIndex = i; + ++i; + } + } + } // if (xEntry.is()) + } + + return xRes; +} + + +void HyphenatorDispatcher::SetServiceList( const Locale &rLocale, + const Sequence< OUString > &rSvcImplNames ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + INT32 nLen = rSvcImplNames.getLength(); + DBG_ASSERT( 1 == nLen, "unexpected size of sequence" ); + OUString aSvcImplName( nLen ? rSvcImplNames.getConstArray()[0] : OUString() ); + + // search for entry with that language + INT16 nLanguage = LocaleToLanguage( rLocale ); + LangSvcEntry_Hyph *pEntry = aSvcList.Seek( nLanguage ); + + if (pEntry) + { + pEntry->aSvcImplName = aSvcImplName; + pEntry->aSvcRef = NULL; + pEntry->aFlags = SvcFlags(); + } + else + { + pEntry = new LangSvcEntry_Hyph( aSvcImplName ); + aSvcList.Insert( nLanguage, pEntry ); + DBG_ASSERT( aSvcList.Seek( nLanguage ), "lng : Insert failed" ); + } +} + + +Sequence< OUString > + HyphenatorDispatcher::GetServiceList( const Locale &rLocale ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aRes(1); + + // search for entry with that language and use data from that + INT16 nLanguage = LocaleToLanguage( rLocale ); + LangSvcEntry_Hyph *pEntry = aSvcList.Seek( nLanguage ); + if (pEntry) + aRes.getArray()[0] = pEntry->aSvcImplName; + else + aRes.realloc(0); + + return aRes; +} + + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/hyphdsp.hxx b/linguistic/source/hyphdsp.hxx new file mode 100644 index 000000000000..737890aaeca1 --- /dev/null +++ b/linguistic/source/hyphdsp.hxx @@ -0,0 +1,234 @@ +/************************************************************************* + * + * $RCSfile: hyphdsp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_HYPHDSP_HXX_ +#define _LINGUISTIC_HYPHDSP_HXX_ + + +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_ +#include <com/sun/star/lang/XInitialization.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_ +#include <com/sun/star/lang/XServiceDisplayName.hpp> +#endif +#include <com/sun/star/linguistic2/XHyphenator.hpp> +#include <com/sun/star/linguistic2/XPossibleHyphens.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp> + +#ifndef _TOOLS_TABLE_HXX +#include <tools/table.hxx> +#endif + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations + + +#include "lngopt.hxx" +#include "misc.hxx" +#include "defs.hxx" + +class LngSvcMgr; + +/////////////////////////////////////////////////////////////////////////// + +class LangSvcEntry_Hyph +{ + friend class HyphenatorDispatcher; + + ::rtl::OUString aSvcImplName; + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XHyphenator > aSvcRef; + +// INT16 nLang; //used as key in the table + SvcFlags aFlags; + +public: + LangSvcEntry_Hyph() {} + LangSvcEntry_Hyph( const ::rtl::OUString &rSvcImplName ); + ~LangSvcEntry_Hyph(); + + BOOL IsAlreadyWarned() const { return aFlags.bAlreadyWarned != 0; } + void SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; } + BOOL IsDoWarnAgain() const { return aFlags.bDoWarnAgain != 0; } + void SetDoWarnAgain(BOOL bVal) { aFlags.bDoWarnAgain = 0 != bVal; } +}; + +DECLARE_TABLE( HyphSvcList, LangSvcEntry_Hyph * ); + + +class HyphenatorDispatcher : + public cppu::WeakImplHelper1 + < + ::com::sun::star::linguistic2::XHyphenator + >, + public LinguDispatcher +{ + HyphSvcList aSvcList; + + ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > xPropSet; + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > xDicList; + + LngSvcMgr &rMgr; + + // disallow copy-constructor and assignment-operator for now + HyphenatorDispatcher(const HyphenatorDispatcher &); + HyphenatorDispatcher & operator = (const HyphenatorDispatcher &); + + inline ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + GetPropSet(); + inline ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > + GetDicList(); + + void ClearSvcList(); + + com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XHyphenatedWord> + buildHyphWord( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry> &xEntry, + INT16 nLang, INT16 nMaxLeading ); + + com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XPossibleHyphens > + buildPossHyphens( const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryEntry > &xEntry, + INT16 nLanguage ); + +public: + HyphenatorDispatcher( LngSvcMgr &rLngSvcMgr ); + virtual ~HyphenatorDispatcher(); + + // XSupportedLocales + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::lang::Locale > SAL_CALL + getLocales() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + hasLocale( const ::com::sun::star::lang::Locale& aLocale ) + throw(::com::sun::star::uno::RuntimeException); + + // XHyphenator + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL + hyphenate( const ::rtl::OUString& aWord, + const ::com::sun::star::lang::Locale& aLocale, + sal_Int16 nMaxLeading, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL + queryAlternativeSpelling( const ::rtl::OUString& aWord, + const ::com::sun::star::lang::Locale& aLocale, + sal_Int16 nIndex, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL + createPossibleHyphens( + const ::rtl::OUString& aWord, + const ::com::sun::star::lang::Locale& aLocale, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + + // LinguDispatcher + virtual void + SetServiceList( const ::com::sun::star::lang::Locale &rLocale, + const ::com::sun::star::uno::Sequence< + rtl::OUString > &rSvcImplNames ); + virtual ::com::sun::star::uno::Sequence< rtl::OUString > + GetServiceList( const ::com::sun::star::lang::Locale &rLocale ); +}; + + +inline ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + HyphenatorDispatcher::GetPropSet() +{ + return xPropSet.is() ? + xPropSet : xPropSet = ::linguistic::GetLinguProperties(); +} + + +inline ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > + HyphenatorDispatcher::GetDicList() +{ + return xDicList.is() ? + xDicList : xDicList = ::linguistic::GetSearchableDictionaryList(); +} + + +/////////////////////////////////////////////////////////////////////////// + + +#endif + diff --git a/linguistic/source/hyphdta.cxx b/linguistic/source/hyphdta.cxx new file mode 100644 index 000000000000..e3809db68581 --- /dev/null +++ b/linguistic/source/hyphdta.cxx @@ -0,0 +1,219 @@ +/************************************************************************* + * + * $RCSfile: hyphdta.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LANG_HXX //autogen wg. LANGUAGE_ENGLISH_US +#include <tools/lang.hxx> +#endif + +#include "hyphdta.hxx" +#include "lngprops.hxx" +#include "misc.hxx" + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + + +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif +#ifndef _ISOLANG_HXX +#include <tools/isolang.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif + +//using namespace utl; +using namespace osl; +using namespace rtl; +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; + +namespace linguistic +{ +/////////////////////////////////////////////////////////////////////////// + + +HyphenatedWord::HyphenatedWord(const OUString &rWord, INT16 nLang, INT16 nHPos, + const OUString &rHyphWord, INT16 nPos ) : + aWord (rWord), + nLanguage (nLang), + aHyphenatedWord (rHyphWord), + nHyphenationPos (nHPos), + nHyphPos (nPos) +{ + bIsAltSpelling = rWord != rHyphWord; +} + + +HyphenatedWord::~HyphenatedWord() +{ +} + + +OUString SAL_CALL HyphenatedWord::getWord() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aWord; +} + + +Locale SAL_CALL HyphenatedWord::getLocale() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Locale aRes; + return LanguageToLocale( aRes, nLanguage ); +} + + +sal_Int16 SAL_CALL HyphenatedWord::getHyphenationPos() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return nHyphenationPos; +} + + +OUString SAL_CALL HyphenatedWord::getHyphenatedWord() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aHyphenatedWord; +} + + +sal_Int16 SAL_CALL HyphenatedWord::getHyphenPos() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return nHyphPos; +} + + +sal_Bool SAL_CALL HyphenatedWord::isAlternativeSpelling() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return bIsAltSpelling; +} + + +/////////////////////////////////////////////////////////////////////////// + + +PossibleHyphens::PossibleHyphens(const OUString &rWord, INT16 nLang, + const OUString &rHyphWord, + const Sequence< INT16 > &rPositions) : + aWord (rWord), + aWordWithHyphens(rHyphWord), + aOrigHyphenPos (rPositions), + nLanguage (nLang) +{ +} + + +PossibleHyphens::~PossibleHyphens() +{ +} + + +OUString SAL_CALL PossibleHyphens::getWord() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aWord; +} + + +Locale SAL_CALL PossibleHyphens::getLocale() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return CreateLocale( nLanguage ); +} + + +OUString SAL_CALL PossibleHyphens::getPossibleHyphens() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aWordWithHyphens; +} + + +Sequence< sal_Int16 > SAL_CALL PossibleHyphens::getHyphenationPositions() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aOrigHyphenPos; +} + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + diff --git a/linguistic/source/iprcache.cxx b/linguistic/source/iprcache.cxx new file mode 100644 index 000000000000..ca1d97856af8 --- /dev/null +++ b/linguistic/source/iprcache.cxx @@ -0,0 +1,466 @@ +/************************************************************************* + * + * $RCSfile: iprcache.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <string.h> + +#include "iprcache.hxx" +#include "misc.hxx" + +#include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp> + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +//#define IPR_DEF_CACHE_SIZE 503 +#define IPR_DEF_CACHE_MAX 375 +#define IPR_DEF_CACHE_MAXINPUT 200 + +#ifdef DBG_STATISTIC + +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif + +//#define IPR_CACHE_SIZE nTblSize +#define IPR_CACHE_MAX nMax +#define IPR_CACHE_MAXINPUT nMaxInput + +#else + +//#define IPR_CACHE_SIZE IPR_DEF_CACHE_SIZE +#define IPR_CACHE_MAX IPR_DEF_CACHE_MAX +#define IPR_CACHE_MAXINPUT IPR_DEF_CACHE_MAXINPUT + +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif + +using namespace utl; +using namespace osl; +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::linguistic2; + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + +FlushListener::FlushListener( Flushable *pFO ) +{ + SetFlushObj( pFO ); +} + +FlushListener::~FlushListener() +{ +} + +void FlushListener::SetDicList( Reference<XDictionaryList> &xDL ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (xDicList != xDL) + { + if (xDicList.is()) + xDicList->removeDictionaryListEventListener( this ); + + xDicList = xDL; + if (xDicList.is()) + xDicList->addDictionaryListEventListener( this, FALSE ); + } +} + +void SAL_CALL FlushListener::disposing( const EventObject& rSource ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (xDicList.is() && rSource.Source == xDicList) + { + xDicList->removeDictionaryListEventListener( this ); + xDicList = NULL; //! release reference + } +} + +void SAL_CALL FlushListener::processDictionaryListEvent( + const DictionaryListEvent& rDicListEvent ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (rDicListEvent.Source == xDicList) + { + INT16 nEvt = rDicListEvent.nCondensedEvent; + BOOL bFlush = ( nEvt & DictionaryListEventFlags::ADD_NEG_ENTRY ) + || ( nEvt & DictionaryListEventFlags::DEL_POS_ENTRY ) + || ( nEvt & DictionaryListEventFlags::ACTIVATE_NEG_DIC ) + || ( nEvt & DictionaryListEventFlags::DEACTIVATE_POS_DIC ); + + DBG_ASSERT( pFlushObj, "lng : missing object (NULL pointer)" ); + if (bFlush && pFlushObj != NULL) + pFlushObj->Flush(); + } +} + +/////////////////////////////////////////////////////////////////////////// + +class IPRCachedWord +{ + String aWord; + IPRCachedWord *pNext; + IPRCachedWord *pPrev; + IPRCachedWord *pFollow; + INT16 nLanguage; + ULONG nFound; + + // don't allow to use copy-constructor and assignment-operator + IPRCachedWord(const IPRCachedWord &); + IPRCachedWord & operator = (const IPRCachedWord &); + +public: + IPRCachedWord( const String& rWord, IPRCachedWord* pFollow, INT16 nLang ) + : aWord( rWord ), pPrev( NULL ), pFollow( pFollow ), + nLanguage( nLang ), nFound( 0 ) {} + ~IPRCachedWord(){} + + const String& GetWord() { return aWord; } + void SetWord( const String& aNew ) { aWord = aNew; } + + USHORT GetLang() { return nLanguage; } + void SetLang( INT16 nNew ) { nLanguage = nNew; } + + IPRCachedWord* GetNext() { return pNext; } + void SetNext( IPRCachedWord* pNew ) { pNext = pNew; } + + IPRCachedWord* GetPrev() { return pPrev; } + void SetPrev( IPRCachedWord* pNew ) { pPrev = pNew; } + + IPRCachedWord* GetFollow() { return pFollow; } + void SetFollow( IPRCachedWord* pNew ){ pFollow = pNew; } + + void IncFound() { ++nFound; } + ULONG GetFound() { return nFound; } + void SetFound( ULONG nNew ) { nFound = nNew; } +}; + +/////////////////////////////////////////////////////////////////////////// + +IPRSpellCache::IPRSpellCache( ULONG nSize ) : + ppHash ( NULL ), + pFirst ( NULL ), + pLast ( NULL ), + nIndex ( 0 ), + nCount ( 0 ), + nInputPos ( 0 ), + nInputValue ( 0 ), + nTblSize ( nSize ) +#ifdef DBG_STATISTIC + ,nMax ( IPR_DEF_CACHE_MAX ), + nMaxInput ( IPR_DEF_CACHE_MAXINPUT ), + nFound ( 0 ), + nLost ( 0 ) +#endif +{ + xDicList = GetDictionaryList(); + + pFlushLstnr = new FlushListener( this ); + xFlushLstnr = pFlushLstnr; + pFlushLstnr->SetDicList( xDicList ); //! after reference is established +} + +IPRSpellCache::~IPRSpellCache() +{ + MutexGuard aGuard( GetLinguMutex() ); + + pFlushLstnr->SetDicList( Reference< XDictionaryList >() ); + +#ifdef DBG_STATISTIC + // Binary File oeffnen + String aOutTmp( String::CreateFromAscii( "iprcache.stk" ) ) + SvFileStream aOut( aOutTmp, STREAM_STD_WRITE ); + + if( aOut.IsOpen() && !aOut.GetError() && ppHash ) + { + ByteString aStr( "Gefunden: "); + aStr += nFound; + aStr += " Verloren: "; + aStr += nLost; + ULONG nSumSum = 0; + aOut << aStr.GetBuffer() << endl; + for( ULONG i = 0; i < nTblSize; ++i ) + { + aStr = "Index: "; + aStr += i; + aStr += " Tiefe: "; + ULONG nDeep = 0; + ULONG nSum = 0; + IPRCachedWord* pTmp = *( ppHash + i ); + while( pTmp ) + { + ++nDeep; + nSum += pTmp->GetFound(); + pTmp = pTmp->GetNext(); + } + aStr += nDeep; + aStr += " Anzahl: "; + aStr += nSum; + nSumSum += nSum; + aOut << aStr.GetBuffer() << endl; + pTmp = *( ppHash + i ); + aStr = " Found: "; + while( pTmp ) + { + aStr += pTmp->GetFound(); + aStr += " "; + pTmp = pTmp->GetNext(); + } + aOut << aStr.GetBuffer() << endl; + } + aStr = "Summe: "; + aStr += nSumSum; + aOut << aStr.GetBuffer() << endl; + } +#endif + + while( pFirst ) + { + pLast = pFirst->GetNext(); + delete pFirst; + pFirst = pLast; + } + delete ppHash; +} + +void IPRSpellCache::Flush() +{ + MutexGuard aGuard( GetLinguMutex() ); + + if( ppHash ) + { + while( pFirst ) + { + pLast = pFirst->GetNext(); + delete pFirst; + pFirst = pLast; + } + delete ppHash; + ppHash = NULL; + nIndex = 0; + nCount = 0; + nInputPos = 0; + nInputValue = 0; +#ifdef DBG_STATISTIC + nFound = 0; + nLost = 0; +#endif + } +} + +BOOL IPRSpellCache::CheckWord( const String& rWord, INT16 nLang, BOOL bAllLang ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRet = FALSE; + // Hash-Index-Berechnung + nIndex = 0; + const sal_Unicode* pp = rWord.GetBuffer(); + while( *pp ) + nIndex = nIndex << 1 ^ *pp++; + nIndex %= nTblSize; + + if( ppHash ) + { + pRun = *(ppHash + nIndex); + + if( pRun && !( bRet = (rWord == pRun->GetWord() && + (nLang == pRun->GetLang() || bAllLang)) ) ) + { + IPRCachedWord* pTmp = pRun->GetNext(); + while( pTmp && !( bRet = ( rWord == pTmp->GetWord() && + (nLang == pRun->GetLang() || bAllLang) ) ) ) + { + pRun = pTmp; + pTmp = pTmp->GetNext(); + } + if ( bRet ) + { // Gefunden: Umsortieren in der Hash-Liste + pRun->SetNext( pTmp->GetNext() ); + pTmp->SetNext( *( ppHash + nIndex ) ); + *( ppHash + nIndex ) = pTmp; + pRun = pTmp; + } + } + if( bRet ) + { + if ( pRun->GetPrev() ) + { // Wenn wir noch nicht erster sind, werden wir es jetzt: + if ( ( pRun->GetFound() <= nInputValue ) && + ( ++nInputPos > IPR_CACHE_MAXINPUT ) + || ( pInput == pRun ) && !( pInput = pRun->GetFollow() ) ) + + { // Wenn die Input-Stelle am Maximum anlangt, erhoehen + ++nInputValue; // wir den InputValue und gehen wieder + nInputPos = 0; // an den Anfang + pInput = pFirst; + } + IPRCachedWord* pTmp = pRun->GetFollow(); + pRun->GetPrev()->SetFollow( pTmp ); //Unser Ex-Prev -> Ex-Follow + pRun->SetFollow( pFirst ); // Wir selbst -> Ex-First + pFirst->SetPrev( pRun ); // Wir selbst <- Ex-First + if( pTmp ) + pTmp->SetPrev( pRun->GetPrev() ); // Ex-Prev <- Ex-Follow + else + pLast = pRun->GetPrev(); // falls wir letzter waren + pRun->SetPrev( NULL ); // Erste haben keinen Prev + pFirst = pRun; // Wir sind Erster! + } + pRun->IncFound(); // Mitzaehlen, wie oft wiedergefunden + } + } + return bRet; +} + +void IPRSpellCache::AddWord( const String& rWord, INT16 nLang ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if( !ppHash ) + { + ppHash = new IPRCachedWord* [ nTblSize ]; + memset( (void *)ppHash, 0, ( sizeof( IPRCachedWord* ) * nTblSize ) ); + } + IPRCachedWord* pTmp; + if( nCount == IPR_CACHE_MAX-1 ) + { + ULONG nDel = 0; + pRun = pLast; // Der letzte wird ueberschrieben + const sal_Unicode* pp = pRun->GetWord().GetBuffer(); + while( *pp ) + nDel = nDel << 1 ^ *pp++; + nDel %= nTblSize; // Hash-Index des letzten + // Der letzte wird aus seiner alten Hash-Liste entfernt + if( ( pTmp = *( ppHash + nDel ) ) == pRun ) + *( ppHash + nDel ) = pRun->GetNext(); + else + { + while( pTmp->GetNext() != pRun ) + pTmp = pTmp->GetNext(); + pTmp->SetNext( pRun->GetNext() ); + } + pRun->SetWord( rWord ); // Ueberschreiben des alten Inhalts + pRun->SetLang( nLang ); + pRun->SetFound( 0 ); + } + else + { + ++nCount; + pRun = new IPRCachedWord( rWord, pFirst, nLang ); + if( pFirst ) + pFirst->SetPrev( pRun ); + pFirst = pRun; // Ganz Neue kommen erstmal nach vorne + if ( !pLast ) + { + pLast = pRun; + pInput = pRun; + } + } + + pRun->SetNext( *( ppHash + nIndex ) ); // In der Hash-Liste + *(ppHash + nIndex ) = pRun; // vorne einsortieren + + // In der LRU-Kette umsortieren ... + if ( pRun != pInput && pRun != pInput->GetPrev() ) + { + pTmp = pRun->GetPrev(); + IPRCachedWord* pFoll = pRun->GetFollow(); + // Entfernen aus der alten Position + if( pTmp ) + pTmp->SetFollow( pFoll ); + else + pFirst = pFoll; // wir waren erster + if( pFoll ) + pFoll->SetPrev( pTmp ); + else + pLast = pTmp; // wir waren letzter + // Einfuegen vor pInput + if( pTmp = pInput->GetPrev() ) + pTmp->SetFollow( pRun ); + else + pFirst = pRun; // pInput war erster + pRun->SetPrev( pTmp ); + pRun->SetFollow( pInput ); + pInput->SetPrev( pRun ); + } + pInput = pRun; // pInput zeigt auf den zuletzt einsortierten +} + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + diff --git a/linguistic/source/lngopt.cxx b/linguistic/source/lngopt.cxx new file mode 100644 index 000000000000..854123275b1e --- /dev/null +++ b/linguistic/source/lngopt.cxx @@ -0,0 +1,1098 @@ +/************************************************************************* + * + * $RCSfile: lngopt.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "lngopt.hxx" +#include "lngprops.hxx" +#include "misc.hxx" + +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif +#ifndef _LANG_HXX +#include <tools/lang.hxx> +#endif + +#ifndef _TOOLS_INTN_HXX +#include <tools/intn.hxx> +#endif +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif +#ifndef _SV_SYSTEM_HXX +#include <vcl/system.hxx> +#endif + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations + +#include <cppuhelper/factory.hxx> // helper for factories +#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ +#include <com/sun/star/container/XNameAccess.hpp> +#endif +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/lang/Locale.hpp> + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif + +using namespace utl; +using namespace osl; +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::container; +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; + +using namespace com::sun::star::registry; + +/////////////////////////////////////////////////////////////////////////// + + +static const char cLocaleDelim = '-'; + +static INT16 CfgLocaleStrToLanguage( const OUString &rCfgLocaleStr ) +{ + INT16 nRes = LANGUAGE_NONE; + if (rCfgLocaleStr.getLength()) + { + INT32 nCount = rCfgLocaleStr.getTokenCount( cLocaleDelim ); + if (nCount <= 3) + { + OUString aPart[3]; + for (INT32 i = 0; i < nCount; ++i) + { + aPart[i] = rCfgLocaleStr.getToken( i, cLocaleDelim ); + } + nRes = LocaleToLanguage( Locale( aPart[0], aPart[1], aPart[2] ) ); + } + else + DBG_ERROR( "invalid Locale string" ); + } + return nRes; +} + + +static const OUString LanguageToCfgLocaleStr( INT16 nLanguage ) +{ + static const OUString aLocaleDelim( cLocaleDelim ); + OUString aRes; + if (LANGUAGE_NONE != nLanguage) + { + Locale aLocale( CreateLocale( nLanguage ) ); + if (aLocale.Language.getLength()) + aRes += aLocale.Language; + if (aLocale.Country.getLength()) + (aRes += aLocaleDelim) += aLocale.Country; + if (aLocale.Variant.getLength()) + (aRes += aLocaleDelim) += aLocale.Variant; + } + return aRes; +} + +/////////////////////////////////////////////////////////////////////////// + + +static void GetSeqLangSvcList( const Any &rVal ) +{ + Reference< XNameAccess > xNameAcc; + rVal >>= xNameAcc; + if (xNameAcc.is()) + { + const Sequence< OUString > aNames( xNameAcc->getElementNames() ); + INT32 nLen = aNames.getLength(); + if (nLen) + { + const OUString *pName = aNames.getConstArray(); + for (INT32 i = 0; i < nLen; ++i) + { + Any aTmp( xNameAcc->getByName( pName[i] ) ); + if (aTmp.hasValue()) + { + Sequence< OUString > aSvcNames; + aTmp >>= aSvcNames; + + INT32 nSvcs = aSvcNames.getLength(); + if (nSvcs) + { + const OUString *pSvcName = aSvcNames.getConstArray(); + for (INT32 j = 0; j < nSvcs; ++j) + { + OUString aImplName( pSvcName[i] ); + } + } + } + } + } + } +} + + +static void GetSeqLangSvc( const Any &rVal ) +{ +} + + +/////////////////////////////////////////////////////////////////////////// + + +LinguOptions::LinguOptionsData::LinguOptionsData() : + ConfigItem( A2OU("Office.Linguistic") ) +{ + // get initial language to use (in case that it is not set later) + nDefaultLanguage = ::GetSystemLanguage(); + if( nDefaultLanguage == LANGUAGE_SYSTEM ) + nDefaultLanguage = System::GetLanguage(); + + // general options + bIsGermanPreReform = FALSE; + bIsUseDictionaryList = + bIsIgnoreControlCharacters = TRUE; + + // spelling options + bIsSpellCapitalization = + bIsSpellSpecial = TRUE; + bIsSpellAuto = + bIsSpellInAllLanguages = + bIsSpellHideMarkings = + bIsSpellReverse = + bIsSpellWithDigits = + bIsSpellUpperCase = FALSE; + + // hyphenation options + bIsHyphSpecial = TRUE; + bIsHyphAuto = FALSE; + nHyphMinLeading = + nHyphMinTrailing = 2; + nHyphMinWordLength = 0; + + // OtherLingu options + nOtherIndex = -1; + bIsStdSpell = + bIsStdThes = + bIsStdHyph = FALSE; + + LoadConfig(); +} + + +Sequence< OUString > LinguOptions::LinguOptionsData::GetPropertyNames() +{ + static const char * aPropNames[] = + { + "General/DefaultLocale", // 0 + "General/DictionaryList/ActiveDictionaries", // 1 + "General/DictionaryList/IsUseDictionaryList", // 2 + "General/IsIgnoreControlCharacters", // 3 + "General/IsGermanPreReform", // 4 + "SpellChecking/IsSpellUpperCase", // 5 + "SpellChecking/IsSpellWithDigits", // 6 + "SpellChecking/IsSpellCapitalization", // 7 + "SpellChecking/IsSpellAuto", // 8 + "SpellChecking/IsSpellSpecial", // 9 + "SpellChecking/IsSpellInAllLocales", // 10 + "SpellChecking/IsHideMarkings", // 11 + "SpellChecking/IsReverseDirection", // 12 + "Hyphenation/MinLeading", // 13 + "Hyphenation/MinTrailing", // 14 + "Hyphenation/MinWordLength", // 15 + "Hyphenation/IsHyphSpecial", // 16 + "Hyphenation/IsHyphAuto", // 17 + "ExternalLinguistic/OtherLinguIndex", // 18 + "ExternalLinguistic/IsUseStandardSpellChecker", // 19 + "ExternalLinguistic/IsUseStandardHyphenator", // 20 + "ExternalLinguistic/IsUseStandardThesaurus", // 21 + "ServiceManager/SpellCheckerList", // 22 + "ServiceManager/ThesaurusList", // 23 + "ServiceManager/HyphenatorList" // 24 + }; + + INT32 nCount = sizeof(aPropNames) / sizeof(aPropNames[0]); + Sequence< OUString > aNames( nCount ); + OUString *pNames = aNames.getArray(); + for(INT32 i = 0; i < nCount; ++i) + { + pNames[i] = A2OU( aPropNames[i] ); + } + return aNames; +} + + +BOOL LinguOptions::LinguOptionsData::LoadConfig() +{ + BOOL bRes = FALSE; + + Sequence< OUString > aNames = GetPropertyNames(); + INT32 nProps = aNames.getLength(); + const Sequence< Any > aValues = GetProperties( aNames ); + EnableNotification( aNames ); + + if (nProps && aValues.getLength() == nProps) + { + const Any *pValue = aValues.getConstArray(); + for (INT32 i = 0; i < nProps; ++i) + { + const Any &rVal = pValue[i]; + if (rVal.hasValue()) + { + switch (i) + { + case 0: + { + OUString aTmp; + rVal >>= aTmp; + nDefaultLanguage = CfgLocaleStrToLanguage( aTmp ); + break; + } + case 1: rVal >>= aActiveDics; break; + case 2: rVal >>= bIsUseDictionaryList; break; + case 3: rVal >>= bIsIgnoreControlCharacters; break; + case 4: rVal >>= bIsGermanPreReform; break; + case 5: rVal >>= bIsSpellUpperCase; break; + case 6: rVal >>= bIsSpellWithDigits; break; + case 7: rVal >>= bIsSpellCapitalization; break; + case 8: rVal >>= bIsSpellAuto; break; + case 9: rVal >>= bIsSpellSpecial; break; + case 10: rVal >>= bIsSpellInAllLanguages; break; + case 11: rVal >>= bIsSpellHideMarkings; break; + case 12: rVal >>= bIsSpellReverse; break; + case 13: rVal >>= nHyphMinLeading; break; + case 14: rVal >>= nHyphMinTrailing; break; + case 15: rVal >>= nHyphMinWordLength; break; + case 16: rVal >>= bIsHyphSpecial; break; + case 17: rVal >>= bIsHyphAuto; break; + case 18: rVal >>= nOtherIndex; break; + case 19: rVal >>= bIsStdSpell; break; + case 20: rVal >>= bIsStdHyph; break; + case 21: rVal >>= bIsStdThes; break; + case 22: GetSeqLangSvcList( rVal ); break; + case 23: GetSeqLangSvcList( rVal ); break; + case 24: GetSeqLangSvc( rVal ); break; + default: + DBG_ERROR( "unexpected case" ); + } + } + } + + bRes = TRUE; + } + DBG_ASSERT( bRes, "LoadConfig failed" ); + + return bRes; +} + + +BOOL LinguOptions::LinguOptionsData::SaveConfig() +{ + const Sequence< OUString > aNames = GetPropertyNames(); + INT32 nProps = aNames.getLength(); + Sequence< Any > aValues( aNames.getLength() ); + Any *pValue = aValues.getArray(); + + const Type &rBOOL = ::getBooleanCppuType(); + const Type &rINT16 = ::getCppuType( (INT16 *) NULL ); + + for (INT32 i = 0; i < nProps; ++i) + { + Any &rVal = pValue[i]; + switch (i) + { + case 0: + { + OUString aTmp( LanguageToCfgLocaleStr( nDefaultLanguage ) ); + rVal = makeAny( aTmp ); + } + case 1: rVal = makeAny( aActiveDics ); break; + case 2: rVal.setValue( &bIsUseDictionaryList, rBOOL ); break; + case 3: rVal.setValue( &bIsIgnoreControlCharacters, rBOOL ); break; + case 4: rVal.setValue( &bIsGermanPreReform, rBOOL ); break; + case 5: rVal.setValue( &bIsSpellUpperCase, rBOOL ); break; + case 6: rVal.setValue( &bIsSpellWithDigits, rBOOL ); break; + case 7: rVal.setValue( &bIsSpellCapitalization, rBOOL ); break; + case 8: rVal.setValue( &bIsSpellAuto, rBOOL ); break; + case 9: rVal.setValue( &bIsSpellSpecial, rBOOL ); break; + case 10: rVal.setValue( &bIsSpellInAllLanguages, rBOOL ); break; + case 11: rVal.setValue( &bIsSpellHideMarkings, rBOOL ); break; + case 12: rVal.setValue( &bIsSpellReverse, rBOOL ); break; + case 13: rVal.setValue( &nHyphMinLeading, rINT16 ); break; + case 14: rVal.setValue( &nHyphMinTrailing, rINT16 ); break; + case 15: rVal.setValue( &nHyphMinWordLength, rINT16 ); break; + case 16: rVal.setValue( &bIsHyphSpecial, rBOOL ); break; + case 17: rVal.setValue( &bIsHyphAuto, rBOOL ); break; + case 18: rVal.setValue( &nOtherIndex, rINT16 ); break; + case 19: rVal.setValue( &bIsStdSpell, rBOOL ); break; + case 20: rVal.setValue( &bIsStdHyph, rBOOL ); break; + case 21: rVal.setValue( &bIsStdThes, rBOOL ); break; + case 22: break; + case 23: break; + case 24: break; + default: + DBG_ERROR( "unexpected case" ); + } + } + + return PutProperties( aNames, aValues ); +} + + +void LinguOptions::LinguOptionsData::Notify( const Sequence< OUString >& rPropertyNames ) +{ + DBG_ERROR("properties have been changed"); +} + + +void LinguOptions::LinguOptionsData::Commit() +{ + SaveConfig(); +} + + +/////////////////////////////////////////////////////////////////////////// + +// static member intialization +LinguOptions::LinguOptionsData * LinguOptions::pData = NULL; + + +LinguOptions::LinguOptions() +{ + if (!pData) + { + pData = new LinguOptionsData; + } + + ++pData->aRefCount; +} + + +LinguOptions::LinguOptions(const LinguOptions &rOpt) +{ + DBG_ASSERT( pData, "lng : data missing" ); + ++pData->aRefCount; +} + + +LinguOptions::~LinguOptions() +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (--pData->aRefCount == 0) + { + delete pData; pData = NULL; + } +} + + +BOOL LinguOptions::SetValue( Any &rOld, const Any &rVal, INT32 nWID ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + + INT16 *pnVal = 0; + BOOL *pbVal = 0; + + switch( nWID ) + { + case WID_IS_GERMAN_PRE_REFORM : pbVal = &pData->bIsGermanPreReform; break; + case WID_IS_USE_DICTIONARY_LIST : pbVal = &pData->bIsUseDictionaryList; break; + case WID_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &pData->bIsIgnoreControlCharacters; break; + case WID_IS_HYPH_AUTO : pbVal = &pData->bIsHyphAuto; break; + case WID_IS_HYPH_SPECIAL : pbVal = &pData->bIsHyphSpecial; break; + case WID_IS_SPELL_AUTO : pbVal = &pData->bIsSpellAuto; break; + case WID_IS_SPELL_HIDE : pbVal = &pData->bIsSpellHideMarkings; break; + case WID_IS_SPELL_IN_ALL_LANGUAGES :pbVal = &pData->bIsSpellInAllLanguages; break; + case WID_IS_SPELL_SPECIAL : pbVal = &pData->bIsSpellSpecial; break; + case WID_IS_WRAP_REVERSE : pbVal = &pData->bIsSpellReverse; break; + case WID_DEFAULT_LANGUAGE : pnVal = &pData->nDefaultLanguage; break; + case WID_IS_STANDARD_HYPHENATOR : pbVal = &pData->bIsStdHyph; break; + case WID_IS_STANDARD_SPELL_CHECKER :pbVal = &pData->bIsStdSpell; break; + case WID_IS_STANDARD_THESAURUS : pbVal = &pData->bIsStdThes; break; + case WID_OTHER_LINGU_INDEX : pnVal = &pData->nOtherIndex; break; + case WID_IS_SPELL_CAPITALIZATION : pbVal = &pData->bIsSpellCapitalization; break; + case WID_IS_SPELL_WITH_DIGITS : pbVal = &pData->bIsSpellWithDigits; break; + case WID_IS_SPELL_UPPER_CASE : pbVal = &pData->bIsSpellUpperCase; break; + case WID_HYPH_MIN_LEADING : pnVal = &pData->nHyphMinLeading; break; + case WID_HYPH_MIN_TRAILING : pnVal = &pData->nHyphMinTrailing; break; + case WID_HYPH_MIN_WORD_LENGTH : pnVal = &pData->nHyphMinWordLength; break; + case WID_DEFAULT_LOCALE : + { + Locale aNew; + rVal >>= aNew; + INT16 nNew = LocaleToLanguage( aNew ); + if (nNew != pData->nDefaultLanguage) + { + Locale aLocale( CreateLocale( pData->nDefaultLanguage ) ); + rOld.setValue( &aLocale, ::getCppuType((Locale*)0 )); + pData->nDefaultLanguage = nNew; + bRes = TRUE; + } + break; + } + default : + { + DBG_ERROR("lng : unknown WID"); + bRes = FALSE; + } + } + + if (pbVal) + { + BOOL bNew; + rVal >>= bNew; + if (bNew != *pbVal) + { + rOld <<= *pbVal; + *pbVal = bNew; + bRes = TRUE; + } + } + if (pnVal) + { + INT16 nNew; + rVal >>= nNew; + if (nNew != *pnVal) + { + rOld <<= *pnVal; + *pnVal = nNew; + bRes = TRUE; + } + } + + if (bRes) + pData->SetCfgItemModified(); + + return bRes; +} + +void LinguOptions::GetValue( Any &rVal, INT32 nWID ) const +{ + MutexGuard aGuard( GetLinguMutex() ); + + INT16 *pnVal = 0; + BOOL *pbVal = 0; + + switch( nWID ) + { + case WID_IS_GERMAN_PRE_REFORM : pbVal = &pData->bIsGermanPreReform; break; + case WID_IS_USE_DICTIONARY_LIST : pbVal = &pData->bIsUseDictionaryList; break; + case WID_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &pData->bIsIgnoreControlCharacters; break; + case WID_IS_HYPH_AUTO : pbVal = &pData->bIsHyphAuto; break; + case WID_IS_HYPH_SPECIAL : pbVal = &pData->bIsHyphSpecial; break; + case WID_IS_SPELL_AUTO : pbVal = &pData->bIsSpellAuto; break; + case WID_IS_SPELL_HIDE : pbVal = &pData->bIsSpellHideMarkings; break; + case WID_IS_SPELL_IN_ALL_LANGUAGES :pbVal = &pData->bIsSpellInAllLanguages; break; + case WID_IS_SPELL_SPECIAL : pbVal = &pData->bIsSpellSpecial; break; + case WID_IS_WRAP_REVERSE : pbVal = &pData->bIsSpellReverse; break; + case WID_DEFAULT_LANGUAGE : pnVal = &pData->nDefaultLanguage; break; + case WID_IS_STANDARD_HYPHENATOR : pbVal = &pData->bIsStdHyph; break; + case WID_IS_STANDARD_SPELL_CHECKER :pbVal = &pData->bIsStdSpell; break; + case WID_IS_STANDARD_THESAURUS : pbVal = &pData->bIsStdThes; break; + case WID_OTHER_LINGU_INDEX : pnVal = &pData->nOtherIndex; break; + case WID_IS_SPELL_CAPITALIZATION : pbVal = &pData->bIsSpellCapitalization; break; + case WID_IS_SPELL_WITH_DIGITS : pbVal = &pData->bIsSpellWithDigits; break; + case WID_IS_SPELL_UPPER_CASE : pbVal = &pData->bIsSpellUpperCase; break; + case WID_HYPH_MIN_LEADING : pnVal = &pData->nHyphMinLeading; break; + case WID_HYPH_MIN_TRAILING : pnVal = &pData->nHyphMinTrailing; break; + case WID_HYPH_MIN_WORD_LENGTH : pnVal = &pData->nHyphMinWordLength; break; + case WID_DEFAULT_LOCALE : + { + Locale aLocale( CreateLocale( pData->nDefaultLanguage ) ); + rVal.setValue( &aLocale, ::getCppuType((Locale*)0 )); + break; + } + default : + { + DBG_ERROR("lng : unknown WID"); + } + } + + if (pbVal) + rVal <<= *pbVal; + if (pnVal) + rVal <<= *pnVal; +} + + +struct WID_Name +{ + INT32 nWID; + const char *pPropertyName; +}; + +WID_Name aWID_Name[] = +{ + WID_IS_GERMAN_PRE_REFORM, UPN_IS_GERMAN_PRE_REFORM, + WID_IS_USE_DICTIONARY_LIST, UPN_IS_USE_DICTIONARY_LIST, + WID_IS_IGNORE_CONTROL_CHARACTERS, UPN_IS_IGNORE_CONTROL_CHARACTERS, + WID_IS_SPELL_UPPER_CASE, UPN_IS_SPELL_UPPER_CASE, + WID_IS_SPELL_WITH_DIGITS, UPN_IS_SPELL_WITH_DIGITS, + WID_IS_SPELL_CAPITALIZATION, UPN_IS_SPELL_CAPITALIZATION, + WID_HYPH_MIN_LEADING, UPN_HYPH_MIN_LEADING, + WID_HYPH_MIN_TRAILING, UPN_HYPH_MIN_TRAILING, + WID_HYPH_MIN_WORD_LENGTH, UPN_HYPH_MIN_WORD_LENGTH, + WID_DEFAULT_LOCALE, UPN_DEFAULT_LOCALE, + WID_IS_SPELL_AUTO, UPN_IS_SPELL_AUTO, + WID_IS_SPELL_HIDE, UPN_IS_SPELL_HIDE, + WID_IS_SPELL_IN_ALL_LANGUAGES, UPN_IS_SPELL_IN_ALL_LANGUAGES, + WID_IS_SPELL_SPECIAL, UPN_IS_SPELL_SPECIAL, + WID_IS_HYPH_AUTO, UPN_IS_HYPH_AUTO, + WID_IS_HYPH_SPECIAL, UPN_IS_HYPH_SPECIAL, + WID_IS_WRAP_REVERSE, UPN_IS_WRAP_REVERSE, + WID_IS_STANDARD_HYPHENATOR, UPN_IS_STANDARD_HYPHENATOR, + WID_IS_STANDARD_SPELL_CHECKER, UPN_IS_STANDARD_SPELL_CHECKER, + WID_IS_STANDARD_THESAURUS, UPN_IS_STANDARD_THESAURUS, + WID_OTHER_LINGU_INDEX, UPN_OTHER_LINGU_INDEX, + WID_DEFAULT_LANGUAGE, UPN_DEFAULT_LANGUAGE +}; + + +OUString LinguOptions::GetName( INT32 nWID ) const +{ + MutexGuard aGuard( GetLinguMutex() ); + + OUString aRes; + + INT32 nLen = sizeof( aWID_Name ) / sizeof( aWID_Name[0] ); + if (0 <= nWID && nWID < nLen + && aWID_Name[ nWID ].nWID == nWID) + { + aRes = OUString( RTL_CONSTASCII_USTRINGPARAM( + aWID_Name[ nWID ].pPropertyName ) ); + } + else + { + DBG_ERROR("lng : unknown WID"); + } + + return aRes; +} + + +void LinguOptions::SetCfgActiveDictionaries( + Reference< XDictionaryList > &rDicList ) +{ + if (rDicList.is()) + { + Sequence< Reference< XDictionary > > aDics( rDicList->getDictionaries() ); + const Reference< XDictionary > *pDic = aDics.getConstArray(); + INT32 nCount = aDics.getLength(); + + pData->aActiveDics.realloc( nCount ); + OUString *pActiveDic = pData->aActiveDics.getArray(); + INT32 nLen = 0; + for (INT32 i = 0; i < nCount; ++i) + { + const Reference< XDictionary > &rDic = pDic[i]; + if (rDic.is() && rDic->isActive()) + pActiveDic[ nLen++ ] = rDic->getName(); + } + pData->aActiveDics.realloc( nLen ); + + pData->SetCfgItemModified(); + } +} + + +BOOL LinguOptions::Load() +{ + BOOL bRes = FALSE; + DBG_ASSERT( pData, "NULL Pointer" ); + if (pData) + bRes = pData->LoadConfig(); + return bRes; +} + + +BOOL LinguOptions::Save() +{ + BOOL bRes = FALSE; + DBG_ASSERT( pData, "NULL Pointer" ); + if (pData) + bRes = pData->SaveConfig(); + return bRes; +} + +/////////////////////////////////////////////////////////////////////////// + +void LinguProps::MyAppExitListener::AtExit() +{ + // save PropertySet upon application exit + rMyOpt.Save(); +} + +//! map must be sorted by first entry in alphabetical increasing order. + +static SfxItemPropertyMap aLinguProps[] = +{ + { MAP_CHAR_LEN(UPN_DEFAULT_LANGUAGE), WID_DEFAULT_LANGUAGE, + &::getCppuType( (sal_Int16*)0 ), 0, 0 }, + { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE), WID_DEFAULT_LOCALE, + &::getCppuType( (Locale* )0), 0, 0 }, + { MAP_CHAR_LEN(UPN_HYPH_MIN_LEADING), WID_HYPH_MIN_LEADING, + &::getCppuType( (sal_Int16*)0 ), 0, 0 }, + { MAP_CHAR_LEN(UPN_HYPH_MIN_TRAILING), WID_HYPH_MIN_TRAILING, + &::getCppuType( (sal_Int16*)0 ), 0, 0 }, + { MAP_CHAR_LEN(UPN_HYPH_MIN_WORD_LENGTH), WID_HYPH_MIN_WORD_LENGTH, + &::getCppuType( (sal_Int16*)0 ), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_GERMAN_PRE_REFORM), WID_IS_GERMAN_PRE_REFORM, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_HYPH_AUTO), WID_IS_HYPH_AUTO, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_HYPH_SPECIAL), WID_IS_HYPH_SPECIAL, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_IGNORE_CONTROL_CHARACTERS), WID_IS_IGNORE_CONTROL_CHARACTERS, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_AUTO), WID_IS_SPELL_AUTO, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_CAPITALIZATION), WID_IS_SPELL_CAPITALIZATION, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_HIDE), WID_IS_SPELL_HIDE, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_IN_ALL_LANGUAGES), WID_IS_SPELL_IN_ALL_LANGUAGES, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_SPECIAL), WID_IS_SPELL_SPECIAL, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_UPPER_CASE), WID_IS_SPELL_UPPER_CASE, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_SPELL_WITH_DIGITS), WID_IS_SPELL_WITH_DIGITS, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_STANDARD_HYPHENATOR), WID_IS_STANDARD_HYPHENATOR, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_STANDARD_SPELL_CHECKER), WID_IS_STANDARD_SPELL_CHECKER, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_STANDARD_THESAURUS), WID_IS_STANDARD_THESAURUS, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_USE_DICTIONARY_LIST), WID_IS_USE_DICTIONARY_LIST, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_IS_WRAP_REVERSE), WID_IS_WRAP_REVERSE, + &::getBooleanCppuType(), 0, 0 }, + { MAP_CHAR_LEN(UPN_OTHER_LINGU_INDEX), WID_OTHER_LINGU_INDEX, + &::getCppuType( (sal_Int16*)0 ), 0, 0 }, + { 0,0,0,0 } +}; + +LinguProps::LinguProps() : + aEvtListeners (GetLinguMutex()), + aPropListeners (GetLinguMutex()), + pMap (aLinguProps) +{ + bDisposing = FALSE; + pExitListener = new MyAppExitListener( aOpt ); + xExitListener = pExitListener; + pExitListener->Activate(); +} + +LinguProps::~LinguProps() +{ + pExitListener->Deactivate(); +} + +void LinguProps::launchEvent( const PropertyChangeEvent &rEvt ) const +{ + cppu::OInterfaceContainerHelper *pContainer = + aPropListeners.getContainer( rEvt.PropertyHandle ); + if (pContainer) + { + cppu::OInterfaceIteratorHelper aIt( *pContainer ); + while (aIt.hasMoreElements()) + { + Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->propertyChange( rEvt ); + } + } +} + +Reference< XInterface > SAL_CALL LinguProps_CreateInstance( + const Reference< XMultiServiceFactory > & rSMgr ) + throw(Exception) +{ + Reference< XInterface > xService = (cppu::OWeakObject*)new LinguProps; + return xService; +} + +Reference< XPropertySetInfo > SAL_CALL LinguProps::getPropertySetInfo() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + static Reference< XPropertySetInfo > aRef = + new SfxItemPropertySetInfo( pMap ); + return aRef; +} + +void SAL_CALL LinguProps::setPropertyValue( + const OUString& rPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, + IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + const SfxItemPropertyMap* pCur = + SfxItemPropertyMap::GetByName(pMap, rPropertyName); + if (pCur) + { + Any aOld; + if (aOpt.SetValue( aOld, aValue, pCur->nWID )) + { + PropertyChangeEvent aChgEvt( (XPropertySet *) this, rPropertyName, + FALSE, pCur->nWID, aOld, aValue ); + launchEvent( aChgEvt ); + } + } +#ifdef LINGU_EXCEPTIONS + else + { + throw UnknownPropertyException(); + } +#endif +} + +Any SAL_CALL LinguProps::getPropertyValue( const OUString& rPropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Any aRet; + + const SfxItemPropertyMap* pCur = SfxItemPropertyMap::GetByName(pMap, rPropertyName); + if(pCur) + { + aOpt.GetValue( aRet, pCur->nWID ); + } +#ifdef LINGU_EXCEPTIONS + else + { + throw UnknownPropertyException(); + } +#endif + + return aRet; +} + +void SAL_CALL LinguProps::addPropertyChangeListener( + const OUString& rPropertyName, + const Reference< XPropertyChangeListener >& rxListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + { + const SfxItemPropertyMap* pCur = + SfxItemPropertyMap::GetByName( pMap, rPropertyName ); + if(pCur) + aPropListeners.addInterface( pCur->nWID, rxListener ); +#ifdef LINGU_EXCEPTIONS + else + { + throw UnknownPropertyException(); + } +#endif + } +} + +void SAL_CALL LinguProps::removePropertyChangeListener( + const OUString& rPropertyName, + const Reference< XPropertyChangeListener >& rxListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + { + const SfxItemPropertyMap* pCur = + SfxItemPropertyMap::GetByName( pMap, rPropertyName ); + if(pCur) + aPropListeners.removeInterface( pCur->nWID, rxListener ); +#ifdef LINGU_EXCEPTIONS + else + { + throw UnknownPropertyException(); + } +#endif + } +} + +void SAL_CALL LinguProps::addVetoableChangeListener( + const OUString& PropertyName, + const Reference< XVetoableChangeListener >& aListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ +// MutexGuard aGuard( GetLinguMutex() ); +} + +void SAL_CALL LinguProps::removeVetoableChangeListener( + const OUString& PropertyName, + const Reference< XVetoableChangeListener >& aListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ +// MutexGuard aGuard( GetLinguMutex() ); +} + + +void SAL_CALL LinguProps::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue ) + throw(UnknownPropertyException, PropertyVetoException, + IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Any aOld; + if (aOpt.SetValue( aOld, rValue, nHandle )) + { + PropertyChangeEvent aChgEvt( (XPropertySet *) this, + aOpt.GetName( nHandle ), FALSE, nHandle, aOld, rValue ); + launchEvent( aChgEvt ); + } +} + + +Any SAL_CALL LinguProps::getFastPropertyValue( sal_Int32 nHandle ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Any aRes; + aOpt.GetValue( aRes, nHandle ); + return aRes; +} + + +Sequence< PropertyValue > SAL_CALL + LinguProps::getPropertyValues() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + INT32 nLen = sizeof (aLinguProps) / sizeof aLinguProps[0] - 1; + Sequence< PropertyValue > aProps( nLen ); + PropertyValue *pProp = aProps.getArray(); + for (INT32 i = 0; i < nLen; i++) + { + PropertyValue &rVal = pProp[i]; + SfxItemPropertyMap &rItem = aLinguProps[i]; + Any aAny; + aOpt.GetValue( aAny, rItem.nWID ); + + rVal.Name = OUString( rItem.pName, rItem.nNameLen, GetTextEncoding() ); + rVal.Handle = rItem.nWID; + rVal.Value = aAny; + rVal.State = PropertyState_DIRECT_VALUE ; + } + return aProps; +} + +void SAL_CALL + LinguProps::setPropertyValues( const Sequence< PropertyValue >& rProps ) + throw(UnknownPropertyException, PropertyVetoException, + IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + INT32 nLen = rProps.getLength(); + const PropertyValue *pVal = rProps.getConstArray(); + for (INT32 i = 0; i < nLen; ++i) + { + Any aOld; + const PropertyValue &rVal = pVal[i]; + if (aOpt.SetValue( aOld, rVal.Value, rVal.Handle )) + { + PropertyChangeEvent aChgEvt( (XPropertySet *) this, + rVal.Name, FALSE, rVal.Handle, aOld, rVal.Value ); + launchEvent( aChgEvt ); + } + } +} + +void SAL_CALL + LinguProps::dispose() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing) + { + bDisposing = TRUE; + + //! its too late to save the options here! + // (see AppExitListener for saving) + //aOpt.Save(); // save (possible) changes before exiting + + EventObject aEvtObj( (XPropertySet *) this ); + aEvtListeners.disposeAndClear( aEvtObj ); + aPropListeners.disposeAndClear( aEvtObj ); + } +} + +void SAL_CALL + LinguProps::addEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.addInterface( rxListener ); +} + +void SAL_CALL + LinguProps::removeEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.removeInterface( rxListener ); +} + + +/////////////////////////////////////////////////////////////////////////// +// Service specific part +// + +// XServiceInfo +OUString SAL_CALL LinguProps::getImplementationName() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getImplementationName_Static(); +} + +// XServiceInfo +sal_Bool SAL_CALL LinguProps::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( INT32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return TRUE; + return FALSE; +} + +// XServiceInfo +uno::Sequence< OUString > SAL_CALL LinguProps::getSupportedServiceNames() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getSupportedServiceNames_Static(); +} + +// ORegistryServiceManager_Static +uno::Sequence< OUString > LinguProps::getSupportedServiceNames_Static() + throw() +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich + aSNS.getArray()[0] = A2OU( SN_LINGU_PROPERTIES ); + return aSNS; +} + + +sal_Bool SAL_CALL LinguProps_writeInfo( void * /*pServiceManager*/, + XRegistryKey * pRegistryKey ) +{ + try + { + String aImpl( '/' ); + aImpl += LinguProps::getImplementationName_Static().getStr(); + aImpl.AppendAscii( "/UNO/SERVICES" ); + Reference< XRegistryKey > xNewKey = + pRegistryKey->createKey(aImpl ); + uno::Sequence< OUString > aServices = LinguProps::getSupportedServiceNames_Static(); + for( INT32 i = 0; i < aServices.getLength(); i++ ) + xNewKey->createKey( aServices.getConstArray()[i]); + + return sal_True; + } + catch(Exception &) + { + return sal_False; + } +} + +void * SAL_CALL LinguProps_getFactory( const sal_Char * pImplName, + XMultiServiceFactory *pServiceManager, void * ) +{ + void * pRet = 0; + if ( !LinguProps::getImplementationName_Static().compareToAscii( pImplName ) ) + { + Reference< XSingleServiceFactory > xFactory = + cppu::createOneInstanceFactory( + pServiceManager, + LinguProps::getImplementationName_Static(), + LinguProps_CreateInstance, + LinguProps::getSupportedServiceNames_Static()); + // acquire, because we return an interface pointer instead of a reference + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/lngopt.hxx b/linguistic/source/lngopt.hxx new file mode 100644 index 000000000000..0b2847a172f2 --- /dev/null +++ b/linguistic/source/lngopt.hxx @@ -0,0 +1,399 @@ +/************************************************************************* + * + * $RCSfile: lngopt.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_LNGOPT_HHX_ +#define _LINGUISTIC_LNGOPT_HHX_ + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase5.hxx> // helper for implementations + +#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_ +#include <cppuhelper/interfacecontainer.hxx> +#endif + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XFASTPROPERTYSET_HPP_ +#include <com/sun/star/beans/XFastPropertySet.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYACCESS_HPP_ +#include <com/sun/star/beans/XPropertyAccess.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif + +#ifndef _SFX_ITEMPROP_HXX +#include <svtools/itemprop.hxx> +#endif +#ifndef _UTL_CONFIGITEM_HXX_ +#include <unotools/configitem.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_ANY_H_ +#include <com/sun/star/uno/Any.h> +#endif + +#ifndef _SOLAR_H //autogen wg. INT16 +#include <tools/solar.h> +#endif + +#include <svtools/itemprop.hxx> + +#include "misc.hxx" +#include "defs.hxx" + +namespace com { namespace sun { namespace star { + namespace beans { + struct PropertyChangeEvent; + } + namespace registry { + class XRegistryKey; + } +}}}; + +/////////////////////////////////////////////////////////////////////////// +// LinguOptions +// This class represents all Linguistik relevant options. +// + +class LinguOptions +{ + class LinguOptionsData : public utl::ConfigItem + { + com::sun::star::uno::Sequence< rtl::OUString > GetPropertyNames(); + + public: + ::vos::ORefCount aRefCount; // number of objects of this class + + ::com::sun::star::uno::Sequence< rtl::OUString > aActiveDics; + + // Hyphenator service specific options + INT16 nHyphMinLeading, + nHyphMinTrailing, + nHyphMinWordLength; + + // OtherLingu service specific option + INT16 nOtherIndex; // index of foreign Linguistik to use + + // misc options (non-service specific) + INT16 nDefaultLanguage; + + // spelling options (non-service specific) + BOOL bIsSpellSpecial; + BOOL bIsSpellInAllLanguages; + BOOL bIsSpellAuto; + BOOL bIsSpellHideMarkings; + BOOL bIsSpellReverse; + + // hyphenation options (non-service specific) + BOOL bIsHyphSpecial; + BOOL bIsHyphAuto; + + // common to SpellChecker, Hyphenator and Thesaurus service + BOOL bIsGermanPreReform; + BOOL bIsUseDictionaryList; + BOOL bIsIgnoreControlCharacters; + + // SpellChecker service specific options + BOOL bIsSpellWithDigits, + bIsSpellUpperCase, + bIsSpellCapitalization; + + // OtherLingu service specific options + BOOL bIsStdSpell; + BOOL bIsStdHyph; // TRUE if foreign Hyphenator should not be used + BOOL bIsStdThes; // TRUE if foreign SpellChecker should not be used + + LinguOptionsData(); + + BOOL LoadConfig(); + BOOL SaveConfig(); + + // ConfigItem + virtual void Notify( const com::sun::star::uno::Sequence< + rtl::OUString >& rPropertyNames ); + virtual void Commit(); + + inline void SetCfgItemModified() { SetModified(); } + }; + + static LinguOptionsData *pData; + + + //! uses default assignment-operator + +public: + LinguOptions(); + LinguOptions(const LinguOptions &rOpt); + ~LinguOptions(); + + BOOL SetValue( ::com::sun::star::uno::Any &rOld, + const ::com::sun::star::uno::Any &rVal, INT32 nWID ); + void GetValue( ::com::sun::star::uno::Any &rVal, INT32 nWID ) const; + ::rtl::OUString GetName( INT32 nWID ) const; + + BOOL IsSpellInAllLanguages() const { return pData->bIsSpellInAllLanguages; } + + const ::com::sun::star::uno::Sequence< rtl::OUString > + GetCfgActiveDictionaries() const { return pData->aActiveDics; } + void SetCfgActiveDictionaries( + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XDictionaryList > &rDicList ); + + // OtherLingu functions + INT16 GetOtherIndex() const { return pData->nOtherIndex; } + BOOL IsStandardSpell() const { return pData->bIsStdSpell; } + BOOL IsStandardHyph() const { return pData->bIsStdHyph; } + BOOL IsStandardThes() const { return pData->bIsStdThes; } + + BOOL Load(); + BOOL Save(); +}; + + +/////////////////////////////////////////////////////////////////////////// + +// uses templates from <cppuhelper/interfacecontainer.h> + + +// helper function call class +struct PropHashType_Impl +{ + size_t operator()(const INT32 &s) const { return s; } +}; + +typedef cppu::OMultiTypeInterfaceContainerHelperVar + < + INT32, + PropHashType_Impl, + std::equal_to< INT32 > + > OPropertyListenerContainerHelper; + +/////////////////////////////////////////////////////////////////////////// + + +class LinguProps : + public cppu::WeakImplHelper5 + < + com::sun::star::beans::XPropertySet, + com::sun::star::beans::XFastPropertySet, + com::sun::star::beans::XPropertyAccess, + com::sun::star::lang::XComponent, + com::sun::star::lang::XServiceInfo + > +{ + class MyAppExitListener : public linguistic::AppExitListener + { + LinguOptions & rMyOpt; + + public: + MyAppExitListener( LinguOptions &rOpt ) : rMyOpt( rOpt ) {} + virtual void AtExit(); + }; + + + ::cppu::OInterfaceContainerHelper aEvtListeners; + OPropertyListenerContainerHelper aPropListeners; + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XTerminateListener > xExitListener; + MyAppExitListener *pExitListener; + + SfxItemPropertyMap *pMap; + LinguOptions aOpt; + + BOOL bDisposing; + + // disallow copy-constructor and assignment-operator for now + LinguProps(const LinguProps &); + LinguProps & operator = (const LinguProps &); + + void launchEvent( const ::com::sun::star::beans::PropertyChangeEvent &rEvt ) const; + +public: + LinguProps(); + virtual ~LinguProps(); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setPropertyValue( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL + getPropertyValue( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + addPropertyChangeListener( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyChangeListener >& rxListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + removePropertyChangeListener( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyChangeListener >& rxListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + addVetoableChangeListener( const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XVetoableChangeListener >& rxListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + removeVetoableChangeListener( const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XVetoableChangeListener >& rxListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XFastPropertySet + virtual void SAL_CALL + setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL + getFastPropertyValue( sal_Int32 nHandle ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XPropertyAccess + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue > SAL_CALL + getPropertyValues() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setPropertyValues( const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& aProps ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL + dispose() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + addEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& rxListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + removeEventListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& rxListener ) + throw(::com::sun::star::uno::RuntimeException); + + + //////////////////////////////////////////////////////////// + // Service specific part + // + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL + getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); + + + static inline ::rtl::OUString + getImplementationName_Static() throw(); + static com::sun::star::uno::Sequence< ::rtl::OUString > + getSupportedServiceNames_Static() throw(); +}; + +inline ::rtl::OUString LinguProps::getImplementationName_Static() throw() +{ + return A2OU( "com.sun.star.lingu2.LinguProps" ); +} + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/source/lngreg.cxx b/linguistic/source/lngreg.cxx new file mode 100644 index 000000000000..e5388d4c4bb7 --- /dev/null +++ b/linguistic/source/lngreg.cxx @@ -0,0 +1,169 @@ +/************************************************************************* + * + * $RCSfile: lngreg.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#include <cppuhelper/factory.hxx> // helper for factories +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif + +#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 LngSvcMgr_writeInfo +( + void * /*pServiceManager*/, + XRegistryKey * pRegistryKey +); + +extern sal_Bool SAL_CALL DicList_writeInfo +( + void * /*pServiceManager*/, XRegistryKey * pRegistryKey +); + +extern sal_Bool SAL_CALL LinguProps_writeInfo +( + void * /*pServiceManager*/, + XRegistryKey * pRegistryKey +); + +extern void * SAL_CALL LngSvcMgr_getFactory +( + const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, + void * /*pRegistryKey*/ +); + +extern void * SAL_CALL DicList_getFactory +( + const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, + void * +); + +void * SAL_CALL LinguProps_getFactory +( + const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, + void * +); + +//////////////////////////////////////// +// definition of the two functions that are used to provide the services +// + +extern "C" +{ + +sal_Bool SAL_CALL component_writeInfo +( + void * pServiceManager, + XRegistryKey * pRegistryKey +) +{ + sal_Bool bRet = LngSvcMgr_writeInfo( pServiceManager, pRegistryKey ); + if(bRet) + bRet = LinguProps_writeInfo( pServiceManager, pRegistryKey ); + if(bRet) + bRet = DicList_writeInfo( pServiceManager, pRegistryKey ); + return bRet; +} + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = + LngSvcMgr_getFactory( + pImplName, + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + pRegistryKey ); + + if(!pRet) + pRet = LinguProps_getFactory( + pImplName, + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + pRegistryKey ); + + if(!pRet) + pRet = DicList_getFactory( + pImplName, + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + pRegistryKey ); + + return pRet; +} +} + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/lngsvcmgr.cxx b/linguistic/source/lngsvcmgr.cxx new file mode 100644 index 000000000000..b6b0fa0db761 --- /dev/null +++ b/linguistic/source/lngsvcmgr.cxx @@ -0,0 +1,1078 @@ +/************************************************************************* + * + * $RCSfile: lngsvcmgr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:40 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SOLAR_H +#include <tools/solar.h> +#endif + +#include <cppuhelper/factory.hxx> // helper for factories +#include <com/sun/star/registry/XRegistryKey.hpp> +#ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_ +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#endif +#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATION_HPP_ +#include <com/sun/star/container/XEnumeration.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSUPPORTEDLOCALES_HPP_ +#include <com/sun/star/linguistic2/XSupportedLocales.hpp> +#endif + +#include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp> +#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp> + +#include "lngsvcmgr.hxx" +#include "misc.hxx" +#include "spelldsp.hxx" +#include "hyphdsp.hxx" +#include "thesdsp.hxx" + +#include <cppuhelper/extract.hxx> +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _SVARRAY_HXX +#include <svtools/svarray.hxx> +#endif + + +using namespace utl; +using namespace osl; +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::container; +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; + + +SV_DECL_VARARR_SORT( SortedINT16Array, INT16, 32, 32); +SV_IMPL_VARARR_SORT( SortedINT16Array, INT16 ); + +/////////////////////////////////////////////////////////////////////////// + + +struct SvcInfo +{ + const ::rtl::OUString aSvcImplName; + const ::com::sun::star::uno::Sequence< INT16 > aSuppLanguages; + + SvcInfo( const ::rtl::OUString &rSvcImplName, + const ::com::sun::star::uno::Sequence< INT16 > &rSuppLanguages ) : + aSvcImplName (rSvcImplName), + aSuppLanguages (rSuppLanguages) + { + } + + BOOL HasLanguage( INT16 nLanguage ) const; +}; + + +BOOL SvcInfo::HasLanguage( INT16 nLanguage ) const +{ + INT32 nCnt = aSuppLanguages.getLength(); + const INT16 *pLang = aSuppLanguages.getConstArray(); + for (INT32 i = 0; i < nCnt; ++i) + { + if (nLanguage == pLang[i]) + break; + } + return i < nCnt; +} + + +typedef SvcInfo * PTR_SVCINFO; +SV_DECL_PTRARR_DEL( SvcInfoArray, PTR_SVCINFO, 16, 16 ); +SV_IMPL_PTRARR( SvcInfoArray, PTR_SVCINFO * ); + + +/////////////////////////////////////////////////////////////////////////// + + +void SetAvailableServiceLists( const SvcInfoArray &rInfoArray, + LinguDispatcher &rDispatcher ) +{ + USHORT nSvcs = rInfoArray.Count(); + + // build list of all available languages + SortedINT16Array aLanguages; + USHORT i; + for (i = 0; i < nSvcs; ++i) + { + const Sequence< INT16 > &rSuppLang = rInfoArray[i]->aSuppLanguages; + INT32 nLang = rSuppLang.getLength(); + const INT16 *pSuppLang = rSuppLang.getConstArray(); + for (INT32 j = 0; j < nLang; ++j) + { + // language not already added? + if (!aLanguages.Seek_Entry( pSuppLang[j] )) + aLanguages.Insert( pSuppLang[j] ); + } + } + + // set service list per language to all available services supporting + // that language + INT16 nLanguages = aLanguages.Count(); + for (i = 0; i < nLanguages; ++i) + { + INT16 nActLang = aLanguages[i]; + Sequence< OUString > aSvcImplNames( nSvcs ); + OUString *pSvcImplName = aSvcImplNames.getArray(); + INT32 nSeqCnt = 0; + for (USHORT j = 0; j < nSvcs; ++j) + { + const SvcInfo &rSvcInfo = *rInfoArray[j]; + if (rSvcInfo.HasLanguage( nActLang )) + pSvcImplName[ nSeqCnt++ ] = rSvcInfo.aSvcImplName; + } + aSvcImplNames.realloc( nSeqCnt ); + + rDispatcher.SetServiceList( CreateLocale( nActLang ), aSvcImplNames ); + } +} + + +/////////////////////////////////////////////////////////////////////////// + + +class LngSvcMgrListenerHelper : + public cppu::WeakImplHelper2 + < + XLinguServiceEventListener, + XDictionaryListEventListener + > +{ + //cppu::OMultiTypeInterfaceContainerHelper aListeners; + ::cppu::OInterfaceContainerHelper aLngSvcMgrListeners; + ::cppu::OInterfaceContainerHelper aLngSvcEvtBroadcasters; + Reference< XDictionaryList > xDicList; + Reference< XInterface > xMyEvtObj; + + // disallow copy-constructor and assignment-operator for now + LngSvcMgrListenerHelper(const LngSvcMgrListenerHelper &); + LngSvcMgrListenerHelper & operator = (const LngSvcMgrListenerHelper &); + + void LaunchEvent( INT16 nLngSvcEvtFlags ); + +public: + LngSvcMgrListenerHelper( const Reference< XInterface > &rxSource, + const Reference< XDictionaryList > &rxDicList ); + + // XEventListener + virtual void SAL_CALL + disposing( const EventObject& rSource ) + throw(RuntimeException); + + // XLinguServiceEventListener + virtual void SAL_CALL + processLinguServiceEvent( const LinguServiceEvent& aLngSvcEvent ) + throw(RuntimeException); + + // XDictionaryListEventListener + virtual void SAL_CALL + processDictionaryListEvent( + const DictionaryListEvent& rDicListEvent ) + throw(RuntimeException); + + inline BOOL AddLngSvcMgrListener( + const Reference< XEventListener >& rxListener ); + inline BOOL RemoveLngSvcMgrListener( + const Reference< XEventListener >& rxListener ); + void DisposeAndClear( const EventObject &rEvtObj ); + BOOL AddLngSvcEvtBroadcaster( + const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster ); + BOOL RemoveLngSvcEvtBroadcaster( + const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster ); +}; + + +LngSvcMgrListenerHelper::LngSvcMgrListenerHelper( + const Reference< XInterface > &rxSource, + const Reference< XDictionaryList > &rxDicList ) : + aLngSvcMgrListeners ( GetLinguMutex() ), + aLngSvcEvtBroadcasters ( GetLinguMutex() ), + xDicList ( rxDicList ), + xMyEvtObj ( rxSource ) +{ + if (xDicList.is()) + { + xDicList->addDictionaryListEventListener( + (XDictionaryListEventListener *) this, FALSE ); + } +} + + +void SAL_CALL LngSvcMgrListenerHelper::disposing( const EventObject& rSource ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XInterface > xRef( rSource.Source ); + if ( xRef.is() ) + { + aLngSvcMgrListeners .removeInterface( xRef ); + aLngSvcEvtBroadcasters.removeInterface( xRef ); + if (xDicList == xRef) + xDicList = 0; + } +} + + +void SAL_CALL + LngSvcMgrListenerHelper::processLinguServiceEvent( + const LinguServiceEvent& rLngSvcEvent ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // change event source to LinguServiceManager since the listeners + // probably do not know (and need not to know) about the specific + // SpellChecker's or Hyphenator's. + LinguServiceEvent aEvtObj( rLngSvcEvent ); + aEvtObj.Source = xMyEvtObj; + + // pass event on to XLinguServiceEventListener's + cppu::OInterfaceIteratorHelper aIt( aLngSvcMgrListeners ); + while (aIt.hasMoreElements()) + { + Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->processLinguServiceEvent( aEvtObj ); + } +} + + +void SAL_CALL + LngSvcMgrListenerHelper::processDictionaryListEvent( + const DictionaryListEvent& rDicListEvent ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // we do keep the original event source here though... + + // pass event on to XDictionaryListEventListener's + cppu::OInterfaceIteratorHelper aIt( aLngSvcMgrListeners ); + while (aIt.hasMoreElements()) + { + Reference< XDictionaryListEventListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->processDictionaryListEvent( rDicListEvent ); + } + + // "translate" DictionaryList event into LinguServiceEvent + INT16 nLngSvcEvt = 0; + INT16 nDlEvt = rDicListEvent.nCondensedEvent; + if ( (nDlEvt & DictionaryListEventFlags::ADD_NEG_ENTRY) || + (nDlEvt & DictionaryListEventFlags::DEL_POS_ENTRY) || + (nDlEvt & DictionaryListEventFlags::ACTIVATE_NEG_DIC) || + (nDlEvt & DictionaryListEventFlags::DEACTIVATE_POS_DIC) ) + nLngSvcEvt |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN; + if ( (nDlEvt & DictionaryListEventFlags::ADD_POS_ENTRY) || + (nDlEvt & DictionaryListEventFlags::DEL_NEG_ENTRY) || + (nDlEvt & DictionaryListEventFlags::ACTIVATE_POS_DIC) || + (nDlEvt & DictionaryListEventFlags::DEACTIVATE_NEG_DIC) ) + nLngSvcEvt |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN; + if ( (nDlEvt & DictionaryListEventFlags::ADD_POS_ENTRY) || + (nDlEvt & DictionaryListEventFlags::DEL_POS_ENTRY) || + (nDlEvt & DictionaryListEventFlags::ACTIVATE_POS_DIC) || + (nDlEvt & DictionaryListEventFlags::ACTIVATE_NEG_DIC) ) + nLngSvcEvt |= LinguServiceEventFlags::HYPHENATE_AGAIN; + if (nLngSvcEvt) + LaunchEvent( nLngSvcEvt ); +} + + +void LngSvcMgrListenerHelper::LaunchEvent( INT16 nLngSvcEvtFlags ) +{ + LinguServiceEvent aEvt( xMyEvtObj, nLngSvcEvtFlags ); + + // pass event on to XLinguServiceEventListener's + cppu::OInterfaceIteratorHelper aIt( aLngSvcMgrListeners ); + while (aIt.hasMoreElements()) + { + Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + xRef->processLinguServiceEvent( aEvt ); + } +} + + +inline BOOL LngSvcMgrListenerHelper::AddLngSvcMgrListener( + const Reference< XEventListener >& rxListener ) +{ + aLngSvcMgrListeners.addInterface( + /*::getCppuType((const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >*)0), */ + rxListener ); + return TRUE; +} + + +inline BOOL LngSvcMgrListenerHelper::RemoveLngSvcMgrListener( + const Reference< XEventListener >& rxListener ) +{ + aLngSvcMgrListeners.removeInterface( + /*::getCppuType((const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >*)0), */ + rxListener ); + return TRUE; +} + + +void LngSvcMgrListenerHelper::DisposeAndClear( const EventObject &rEvtObj ) +{ + // call "disposing" for all listeners and clear list + aLngSvcMgrListeners .disposeAndClear( rEvtObj ); + + // remove references to this object hold by the broadcasters + cppu::OInterfaceIteratorHelper aIt( aLngSvcEvtBroadcasters ); + while (aIt.hasMoreElements()) + { + Reference< XLinguServiceEventBroadcaster > xRef( aIt.next(), UNO_QUERY ); + if (xRef.is()) + RemoveLngSvcEvtBroadcaster( xRef ); + } + + // remove refernce to this object hold by the dictionary-list + if (xDicList.is()) + { + xDicList->removeDictionaryListEventListener( + (XDictionaryListEventListener *) this ); + xDicList = 0; + } +} + + +BOOL LngSvcMgrListenerHelper::AddLngSvcEvtBroadcaster( + const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster ) +{ + BOOL bRes = FALSE; + if (rxBroadcaster.is()) + { + aLngSvcEvtBroadcasters.addInterface( rxBroadcaster ); + rxBroadcaster->addLinguServiceEventListener( + (XLinguServiceEventListener *) this ); + } + return bRes; +} + + +BOOL LngSvcMgrListenerHelper::RemoveLngSvcEvtBroadcaster( + const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster ) +{ + BOOL bRes = FALSE; + if (rxBroadcaster.is()) + { + aLngSvcEvtBroadcasters.removeInterface( rxBroadcaster ); + rxBroadcaster->removeLinguServiceEventListener( + (XLinguServiceEventListener *) this ); + } + return bRes; +} + + +/////////////////////////////////////////////////////////////////////////// + + +LngSvcMgr::LngSvcMgr() : + aEvtListeners ( GetLinguMutex() ) +{ + bDisposing = FALSE; + + pSpellDsp = 0; + pHyphDsp = 0; + pThesDsp = 0; + + pSpellSvcs = 0; + pHyphSvcs = 0; + pThesSvcs = 0; + pListenerHelper = 0; +} + + +LngSvcMgr::~LngSvcMgr() +{ + // memory for pSpellDsp, pHyphDsp, pThesDsp, pListenerHelper + // will be freed in the destructor of the respective Reference's + // xSpellDsp, xHyphDsp, xThesDsp + + delete pSpellSvcs; + delete pHyphSvcs; + delete pThesSvcs; +} + + +void LngSvcMgr::GetListenerHelper_Impl() +{ + if (!pListenerHelper) + { + pListenerHelper = new LngSvcMgrListenerHelper( + (XLinguServiceManager *) this, linguistic::GetDictionaryList() ); + xListenerHelper = (XLinguServiceEventListener *) pListenerHelper; + } +} + + +void LngSvcMgr::GetSpellCheckerDsp_Impl() +{ + if (!pSpellDsp) + { + pSpellDsp = new SpellCheckerDispatcher( *this ); + xSpellDsp = pSpellDsp; + SetCfgServiceLists( *pSpellDsp ); + } +} + + +void LngSvcMgr::GetHyphenatorDsp_Impl() +{ + if (!pHyphDsp) + { + pHyphDsp = new HyphenatorDispatcher( *this ); + xHyphDsp = pHyphDsp; + SetCfgServiceLists( *pHyphDsp ); + } +} + + +void LngSvcMgr::GetThesaurusDsp_Impl() +{ + if (!pThesDsp) + { + pThesDsp = new ThesaurusDispatcher; + xThesDsp = pThesDsp; + SetCfgServiceLists( *pThesDsp ); + } +} + + +void LngSvcMgr::GetAvailableSpellSvcs_Impl() +{ + if (!pSpellSvcs) + { + pSpellSvcs = new SvcInfoArray; + + Reference< XMultiServiceFactory > xFac( getProcessServiceFactory() ); + if (xFac.is()) + { + Reference< XContentEnumerationAccess > xEnumAccess( xFac, UNO_QUERY ); + Reference< XEnumeration > xEnum; + if (xEnumAccess.is()) + xEnum = xEnumAccess->createContentEnumeration( + A2OU( SN_SPELLCHECKER ) ); + + if (xEnum.is()) + { + while (xEnum->hasMoreElements()) + { + Any aCurrent = xEnum->nextElement(); + Reference< XSingleServiceFactory > xFactory; + + if (!::cppu::extractInterface( xFactory, aCurrent )) + continue; + + Reference< XSpellChecker > xSvc( xFactory->createInstance(), + UNO_QUERY ); + if (xSvc.is()) + { + OUString aImplName; + Sequence< INT16 > aLanguages; + Reference< XServiceInfo > xInfo( xSvc, UNO_QUERY ); + if (xInfo.is()) + aImplName = xInfo->getImplementationName(); + DBG_ASSERT( aImplName.getLength(), + "empty implementation name" ); + Reference< XSupportedLocales > xSuppLoc( xSvc, UNO_QUERY ); + DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" ); + if (xSuppLoc.is()) + aLanguages = LocaleSeqToLangSeq( xSuppLoc->getLocales() ); + + pSpellSvcs->Insert( new SvcInfo( aImplName, aLanguages ), + pSpellSvcs->Count() ); + + // TL_TODO: + // when HRO has the functionality provided to unload + // the DLLs it should be done here! + } + } + } + } + } +} + + +void LngSvcMgr::GetAvailableHyphSvcs_Impl() +{ + if (!pHyphSvcs) + { + pHyphSvcs = new SvcInfoArray; + + Reference< XMultiServiceFactory > xFac( getProcessServiceFactory() ); + if (xFac.is()) + { + Reference< XContentEnumerationAccess > xEnumAccess( xFac, UNO_QUERY ); + Reference< XEnumeration > xEnum; + if (xEnumAccess.is()) + xEnum = xEnumAccess->createContentEnumeration( + A2OU( SN_HYPHENATOR ) ); + + if (xEnum.is()) + { + while (xEnum->hasMoreElements()) + { + Any aCurrent = xEnum->nextElement(); + Reference< XSingleServiceFactory > xFactory; + + if (!::cppu::extractInterface( xFactory, aCurrent )) + continue; + + Reference< XHyphenator > xSvc( xFactory->createInstance(), + UNO_QUERY ); + if (xSvc.is()) + { + OUString aImplName; + Sequence< INT16 > aLanguages; + Reference< XServiceInfo > xInfo( xSvc, UNO_QUERY ); + if (xInfo.is()) + aImplName = xInfo->getImplementationName(); + DBG_ASSERT( aImplName.getLength(), + "empty implementation name" ); + Reference< XSupportedLocales > xSuppLoc( xSvc, UNO_QUERY ); + DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" ); + if (xSuppLoc.is()) + aLanguages = LocaleSeqToLangSeq( xSuppLoc->getLocales() ); + + pHyphSvcs->Insert( new SvcInfo( aImplName, aLanguages ), + pHyphSvcs->Count() ); + + // TL_TODO: + // when HRO has the functionality provided to unload + // the DLLs it should be done here! + } + } + } + } + } +} + + +void LngSvcMgr::GetAvailableThesSvcs_Impl() +{ + if (!pThesSvcs) + { + pThesSvcs = new SvcInfoArray; + + Reference< XMultiServiceFactory > xFac( getProcessServiceFactory() ); + if (xFac.is()) + { + Reference< XContentEnumerationAccess > xEnumAccess( xFac, UNO_QUERY ); + Reference< XEnumeration > xEnum; + if (xEnumAccess.is()) + xEnum = xEnumAccess->createContentEnumeration( + A2OU( SN_THESAURUS ) ); + + if (xEnum.is()) + { + while (xEnum->hasMoreElements()) + { + Any aCurrent = xEnum->nextElement(); + Reference< XSingleServiceFactory > xFactory; + + if (!::cppu::extractInterface( xFactory, aCurrent )) + continue; + + Reference< XThesaurus > xSvc( xFactory->createInstance(), + UNO_QUERY ); + if (xSvc.is()) + { + OUString aImplName; + Sequence< INT16 > aLanguages; + Reference< XServiceInfo > xInfo( xSvc, UNO_QUERY ); + if (xInfo.is()) + aImplName = xInfo->getImplementationName(); + DBG_ASSERT( aImplName.getLength(), + "empty implementation name" ); + Reference< XSupportedLocales > xSuppLoc( xSvc, UNO_QUERY ); + DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" ); + if (xSuppLoc.is()) + aLanguages = LocaleSeqToLangSeq( xSuppLoc->getLocales() ); + + pThesSvcs->Insert( new SvcInfo( aImplName, aLanguages ), + pThesSvcs->Count() ); + + // TL_TODO: + // when HRO has the functionality provided to unload + // the DLLs it should be done here! + } + } + } + } + } +} + + +void LngSvcMgr::SetCfgServiceLists( SpellCheckerDispatcher &rSpellDsp ) +{ + // TL_TODO: + // the services obtained from the configuration should be set here + + if (!pSpellSvcs) + GetAvailableSpellSvcs_Impl(); + SetAvailableServiceLists( *pSpellSvcs, rSpellDsp ); +} + + +void LngSvcMgr::SetCfgServiceLists( HyphenatorDispatcher &rHyphDsp ) +{ + // TL_TODO: + // the services obtained from the configuration should be set here + + if (!pHyphSvcs) + GetAvailableHyphSvcs_Impl(); + SetAvailableServiceLists( *pHyphSvcs, rHyphDsp ); +} + + +void LngSvcMgr::SetCfgServiceLists( ThesaurusDispatcher &rThesDsp ) +{ + // TL_TODO: + // the services obtained from the configuration should be set here + + if (!pThesSvcs) + GetAvailableThesSvcs_Impl(); + SetAvailableServiceLists( *pThesSvcs, rThesDsp ); +} + + +Reference< XSpellChecker > SAL_CALL + LngSvcMgr::getSpellChecker() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XSpellChecker > xRes; + if (!bDisposing) + { + if (!xSpellDsp.is()) + GetSpellCheckerDsp_Impl(); + xRes = xSpellDsp; + } + return xRes; +} + + +Reference< XHyphenator > SAL_CALL + LngSvcMgr::getHyphenator() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XHyphenator > xRes; + if (!bDisposing) + { + if (!xHyphDsp.is()) + GetHyphenatorDsp_Impl(); + xRes = xHyphDsp; + } + return xRes; +} + + +Reference< XThesaurus > SAL_CALL + LngSvcMgr::getThesaurus() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XThesaurus > xRes; + if (!bDisposing) + { + if (!xThesDsp.is()) + GetThesaurusDsp_Impl(); + xRes = xThesDsp; + } + return xRes; +} + + +sal_Bool SAL_CALL + LngSvcMgr::addLinguServiceManagerListener( + const Reference< XEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + if (!bDisposing && xListener.is()) + { + if (!pListenerHelper) + GetListenerHelper_Impl(); + bRes = pListenerHelper->AddLngSvcMgrListener( xListener ); + } + return bRes; +} + + +sal_Bool SAL_CALL + LngSvcMgr::removeLinguServiceManagerListener( + const Reference< XEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + if (!bDisposing && xListener.is()) + { + DBG_ASSERT( pListenerHelper, "listener removed without being added" ); + if (!pListenerHelper) + GetListenerHelper_Impl(); + bRes = pListenerHelper->RemoveLngSvcMgrListener( xListener ); + } + return bRes; +} + + +Sequence< OUString > SAL_CALL + LngSvcMgr::getAvailableServices( + const OUString& rServiceName, + const Locale& rLocale ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aRes; + const SvcInfoArray *pInfoArray = 0; + + if (0 == rServiceName.compareToAscii( SN_SPELLCHECKER )) + { + if (!pSpellSvcs) + GetAvailableSpellSvcs_Impl(); + pInfoArray = pSpellSvcs; + } + else if (0 == rServiceName.compareToAscii( SN_HYPHENATOR )) + { + if (!pHyphSvcs) + GetAvailableHyphSvcs_Impl(); + pInfoArray = pHyphSvcs; + } + else if (0 == rServiceName.compareToAscii( SN_THESAURUS )) + { + if (!pThesSvcs) + GetAvailableThesSvcs_Impl(); + pInfoArray = pThesSvcs; + } + + if (pInfoArray) + { + // resize to max number of entries + INT32 nMaxCnt = pInfoArray->Count(); + aRes.realloc( nMaxCnt ); + OUString *pImplName = aRes.getArray(); + + INT32 nCnt = 0; + INT16 nLanguage = LocaleToLanguage( rLocale ); + for (INT32 i = 0; i < nMaxCnt; ++i) + { + const SvcInfo *pInfo = pInfoArray->GetObject(i); + if (LANGUAGE_NONE == nLanguage + || (pInfo && pInfo->HasLanguage( nLanguage ))) + { + pImplName[ nCnt++ ] = pInfo->aSvcImplName; + } + } + + // resize to actual number of entries + if (nCnt && nCnt != nMaxCnt) + aRes.realloc( nCnt ); + } + + return aRes; +} + + +void SAL_CALL + LngSvcMgr::setConfiguredServices( + const OUString& rServiceName, + const Locale& rLocale, + const Sequence< OUString >& rServiceImplNames ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // TL_TODO: + // write code to access the configuration and set the following + // variable accordingly + BOOL bCfgChgSuccess = TRUE; + INT16 nLanguage = LocaleToLanguage( rLocale ); + + if (bCfgChgSuccess && LANGUAGE_NONE != nLanguage) + { + if (0 == rServiceName.compareToAscii( SN_SPELLCHECKER )) + pSpellDsp->SetServiceList( rLocale, rServiceImplNames ); + else if (0 == rServiceName.compareToAscii( SN_HYPHENATOR )) + pHyphDsp->SetServiceList( rLocale, rServiceImplNames ); + else if (0 == rServiceName.compareToAscii( SN_THESAURUS )) + pThesDsp->SetServiceList( rLocale, rServiceImplNames ); + } +} + + +Sequence< OUString > SAL_CALL + LngSvcMgr::getConfiguredServices( + const OUString& rServiceName, + const Locale& rLocale ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return Sequence< OUString > (); +} + + +void SAL_CALL + LngSvcMgr::dispose() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing) + { + bDisposing = TRUE; + + // require listeners to release this object + EventObject aEvtObj( (XLinguServiceManager *) this ); + aEvtListeners.disposeAndClear( aEvtObj ); + + if (pListenerHelper) + pListenerHelper->DisposeAndClear( aEvtObj ); + } +} + + +void SAL_CALL + LngSvcMgr::addEventListener( + const Reference< XEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && xListener.is()) + { + aEvtListeners.addInterface( + /*::getCppuType((const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >*)0), */ + xListener ); + } +} + + +void SAL_CALL + LngSvcMgr::removeEventListener( + const Reference< XEventListener >& xListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (xListener.is()) + { + aEvtListeners.removeInterface( + /*::getCppuType((const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >*)0), */ + xListener ); + } +} + + +BOOL LngSvcMgr::AddLngSvcEvtBroadcaster( + const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster ) +{ + BOOL bRes = FALSE; + if (rxBroadcaster.is()) + { + if (!pListenerHelper) + GetListenerHelper_Impl(); + bRes = pListenerHelper->AddLngSvcEvtBroadcaster( rxBroadcaster ); + } + return bRes; +} + + +BOOL LngSvcMgr::RemoveLngSvcEvtBroadcaster( + const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster ) +{ + BOOL bRes = FALSE; + if (rxBroadcaster.is()) + { + DBG_ASSERT( pListenerHelper, "pListenerHelper non existent" ); + if (!pListenerHelper) + GetListenerHelper_Impl(); + bRes = pListenerHelper->RemoveLngSvcEvtBroadcaster( rxBroadcaster ); + } + return bRes; +} + + +OUString SAL_CALL + LngSvcMgr::getImplementationName() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getImplementationName_Static(); +} + + +sal_Bool SAL_CALL + LngSvcMgr::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( INT32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return TRUE; + return FALSE; +} + + +Sequence< OUString > SAL_CALL + LngSvcMgr::getSupportedServiceNames() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getSupportedServiceNames_Static(); +} + + +uno::Sequence< OUString > LngSvcMgr::getSupportedServiceNames_Static() + throw() +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich + aSNS.getArray()[0] = A2OU( SN_LINGU_SERVCICE_MANAGER ); + return aSNS; +} + + +Reference< XInterface > SAL_CALL LngSvcMgr_CreateInstance( + const Reference< XMultiServiceFactory > & rSMgr ) + throw(Exception) +{ + Reference< XInterface > xService = (cppu::OWeakObject*) new LngSvcMgr; + return xService; +} + + + +sal_Bool SAL_CALL LngSvcMgr_writeInfo( + void * /*pServiceManager*/, + registry::XRegistryKey * pRegistryKey ) +{ + try + { + String aImpl( '/' ); + aImpl += LngSvcMgr::getImplementationName_Static().getStr(); + aImpl.AppendAscii( "/UNO/SERVICES" ); + Reference< registry::XRegistryKey > xNewKey = + pRegistryKey->createKey( aImpl ); + uno::Sequence< OUString > aServices = LngSvcMgr::getSupportedServiceNames_Static(); + for( INT32 i = 0; i < aServices.getLength(); i++ ) + xNewKey->createKey( aServices.getConstArray()[i] ); + + return sal_True; + } + catch(Exception &) + { + return sal_False; + } +} + +void * SAL_CALL LngSvcMgr_getFactory( + const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, + void * /*pRegistryKey*/ ) +{ + + void * pRet = 0; + if ( !LngSvcMgr::getImplementationName_Static().compareToAscii( pImplName ) ) + { + Reference< XSingleServiceFactory > xFactory = + cppu::createOneInstanceFactory( + pServiceManager, + LngSvcMgr::getImplementationName_Static(), + LngSvcMgr_CreateInstance, + LngSvcMgr::getSupportedServiceNames_Static()); + // acquire, because we return an interface pointer instead of a reference + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/lngsvcmgr.hxx b/linguistic/source/lngsvcmgr.hxx new file mode 100644 index 000000000000..78e627054a08 --- /dev/null +++ b/linguistic/source/lngsvcmgr.hxx @@ -0,0 +1,249 @@ +/************************************************************************* + * + * $RCSfile: lngsvcmgr.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:40 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_LNGSVCMGR_HXX_ +#define _LINGUISTIC_LNGSVCMGR_HXX_ + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase3.hxx> // helper for implementations + +#ifndef _CPPUHELPER_INTERFACECONTAINER_H_ +#include <cppuhelper/interfacecontainer.h> //OMultiTypeInterfaceContainerHelper +#endif + + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif + +#ifndef _COM_SUN_STAR_LINGUISTIC2_XLINGUSERVICEMANAGER_HPP_ +#include <com/sun/star/linguistic2/XLinguServiceManager.hpp> +#endif + +#include "misc.hxx" +#include "defs.hxx" + +class SpellCheckerDispatcher; +class HyphenatorDispatcher; +class ThesaurusDispatcher; +class SvcInfoArray; +class LngSvcMgrListenerHelper; + +namespace com { namespace sun { namespace star { namespace linguistic2 { + class XLinguServiceEventBroadcaster; + class XSpellChecker; + class XHyphenator; + class XThesaurus; +} } } } + +/////////////////////////////////////////////////////////////////////////// + + +class LngSvcMgr : + public cppu::WeakImplHelper3 + < + com::sun::star::linguistic2::XLinguServiceManager, + com::sun::star::lang::XComponent, + com::sun::star::lang::XServiceInfo + > +{ + ::cppu::OInterfaceContainerHelper aEvtListeners; + + com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellChecker > xSpellDsp; + com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XHyphenator > xHyphDsp; + com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XThesaurus > xThesDsp; + + com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener > xListenerHelper; + + SpellCheckerDispatcher * pSpellDsp; + HyphenatorDispatcher * pHyphDsp; + ThesaurusDispatcher * pThesDsp; + + LngSvcMgrListenerHelper * pListenerHelper; + + SvcInfoArray * pSpellSvcs; + SvcInfoArray * pHyphSvcs; + SvcInfoArray * pThesSvcs; + + BOOL bDisposing; + + // disallow copy-constructor and assignment-operator for now + LngSvcMgr(const LngSvcMgr &); + LngSvcMgr & operator = (const LngSvcMgr &); + + void GetAvailableSpellSvcs_Impl(); + void GetAvailableHyphSvcs_Impl(); + void GetAvailableThesSvcs_Impl(); + void GetListenerHelper_Impl(); + void GetSpellCheckerDsp_Impl(); + void GetHyphenatorDsp_Impl(); + void GetThesaurusDsp_Impl(); + + void SetCfgServiceLists( SpellCheckerDispatcher &rSpellDsp ); + void SetCfgServiceLists( HyphenatorDispatcher &rHyphDsp ); + void SetCfgServiceLists( ThesaurusDispatcher &rThesDsp ); + +public: + LngSvcMgr(); + virtual ~LngSvcMgr(); + + // XLinguServiceManager + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellChecker > SAL_CALL + getSpellChecker() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XHyphenator > SAL_CALL + getHyphenator() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XThesaurus > SAL_CALL + getThesaurus() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + addLinguServiceManagerListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + removeLinguServiceManagerListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getAvailableServices( + const ::rtl::OUString& rServiceName, + const ::com::sun::star::lang::Locale& rLocale ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setConfiguredServices( + const ::rtl::OUString& rServiceName, + const ::com::sun::star::lang::Locale& rLocale, + const ::com::sun::star::uno::Sequence< + ::rtl::OUString >& rServiceImplNames ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getConfiguredServices( + const ::rtl::OUString& rServiceName, + const ::com::sun::star::lang::Locale& rLocale ) + throw(::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL + dispose() + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL + getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); + + + static inline ::rtl::OUString + getImplementationName_Static(); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > + getSupportedServiceNames_Static() throw(); + + BOOL AddLngSvcEvtBroadcaster( + const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster ); + BOOL RemoveLngSvcEvtBroadcaster( + const ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster ); +}; + + +inline ::rtl::OUString LngSvcMgr::getImplementationName_Static() +{ + return A2OU( "com.sun.star.lingu2.LngSvcMgr" ); +} + + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/source/makefile.mk b/linguistic/source/makefile.mk new file mode 100644 index 000000000000..41e6a708fcbf --- /dev/null +++ b/linguistic/source/makefile.mk @@ -0,0 +1,171 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-11-17 12:37:40 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ = .. + +PRJNAME = linguistic +TARGET = lng +ENABLE_EXCEPTIONS=TRUE + +#----- Settings --------------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +UNOUCRDEP= $(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB= $(SOLARBINDIR)$/applicat.rdb + +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.XOtherLingu\ + com.sun.star.linguistic2.XPossibleHyphens\ + com.sun.star.linguistic2.XSearchableDictionaryList\ + com.sun.star.linguistic2.XSpellAlternatives\ + com.sun.star.linguistic2.XSpellChecker\ + com.sun.star.linguistic2.XSpellChecker1\ + com.sun.star.linguistic2.XSupportedLanguages\ + com.sun.star.linguistic2.XSupportedLocales\ + com.sun.star.linguistic2.XThesaurus + + +.IF "$(header)" == "" + +EXCEPTIONSFILES=\ + $(SLO)$/dicimp.obj\ + $(SLO)$/dlistimp.obj\ + $(SLO)$/hyphdsp.obj\ + $(SLO)$/lngopt.obj\ + $(SLO)$/lngreg.obj\ + $(SLO)$/lngsvcmgr.obj\ + $(SLO)$/misc.obj\ + $(SLO)$/spelldsp.obj\ + $(SLO)$/thesdsp.obj + +SLOFILES= \ + $(SLO)$/dicimp.obj\ + $(SLO)$/dlistimp.obj\ + $(SLO)$/hyphdsp.obj\ + $(SLO)$/hyphdta.obj\ + $(SLO)$/iprcache.obj\ + $(SLO)$/lngopt.obj\ + $(SLO)$/lngreg.obj\ + $(SLO)$/lngsvcmgr.obj\ + $(SLO)$/misc.obj\ + $(SLO)$/spelldsp.obj\ + $(SLO)$/spelldta.obj\ + $(SLO)$/thesdsp.obj +# $(SLO)$/thesdta.obj + +SHL1TARGET= $(TARGET)$(UPD)$(DLLPOSTFIX) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(UNOLIB) \ + $(VOSLIB) \ + $(TOOLSLIB) \ + $(SVTOOLLIB) \ + $(SVLLIB) \ + $(VCLLIB) \ + $(SFXLIB) \ + $(SALLIB) \ + $(UCBHELPERLIB) \ + $(UNOTOOLSLIB) + + +# build DLL +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1IMPLIB= i$(TARGET) +SHL1DEPN= $(SHL1LIBS) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +# build DEF file +DEF1NAME =$(SHL1TARGET) +#DEF1DEPN =$(MISC)$/$(SHL1TARGET).flt +#DEFLIB1NAME =$(TARGET) +#DEF1DES =Linguistic main DLL + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/linguistic/source/misc.cxx b/linguistic/source/misc.cxx new file mode 100644 index 000000000000..5b99068ef022 --- /dev/null +++ b/linguistic/source/misc.cxx @@ -0,0 +1,477 @@ +/************************************************************************* + * + * $RCSfile: misc.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:41 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif +#ifndef _FSYS_HXX +#include <tools/fsys.hxx> +#endif +#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX +#include <svtools/pathoptions.hxx> +#endif +#ifndef _SFX_INIMGR_HXX +#include <sfx2/inimgr.hxx> +#endif + +#include "misc.hxx" +#include "defs.hxx" +#include "lngprops.hxx" + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XFASTPROPERTYSET_HPP_ +#include <com/sun/star/beans/XFastPropertySet.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_ +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_XTERMINATELISTENER_HPP_ +#include <com/sun/star/frame/XTerminateListener.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_XDESKTOP_HPP_ +#include <com/sun/star/frame/XDesktop.hpp> +#endif + +#include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/linguistic2/XDictionary1.hpp> +#include <com/sun/star/linguistic2/DictionaryType.hpp> +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + +osl::Mutex & GetLinguMutex() +{ + static osl::Mutex aMutex; + return aMutex; +} + +/////////////////////////////////////////////////////////////////////////// + +BOOL IsUseDicList( const PropertyValues &rProperties, + const Reference< XPropertySet > &rxProp ) +{ + BOOL bRes = TRUE; + + INT32 nLen = rProperties.getLength(); + const PropertyValue *pVal = rProperties.getConstArray(); + for (INT32 i = 0; i < nLen; ++i) + { + if (UPH_IS_USE_DICTIONARY_LIST == pVal[i].Handle) + { + pVal[i].Value >>= bRes; + break; + } + } + if (i >= nLen) // no temporary value found in 'rProperties' + { + Reference< XFastPropertySet > xFast( rxProp, UNO_QUERY ); + if (xFast.is()) + xFast->getFastPropertyValue( UPH_IS_USE_DICTIONARY_LIST ) >>= bRes; + } + + return bRes; +} + + +static BOOL lcl_HasHyphInfo( const Reference<XDictionaryEntry> &xEntry ) +{ + BOOL bRes = FALSE; + if (xEntry.is()) + { + // there has to be (at least one) '=' denoting a hyphenation position + // and it must not be before any character of the word + sal_Int32 nIdx = xEntry->getDictionaryWord().indexOf( '=' ); + bRes = nIdx != -1 && nIdx != 0; + } + return bRes; +} + + +Reference< XDictionaryEntry > SearchDicList( + const Reference< XDictionaryList > &xDicList, + const OUString &rWord, INT16 nLanguage, + BOOL bSearchPosDics, BOOL bSearchSpellEntry ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XDictionaryEntry > xEntry; + + if (!xDicList.is()) + return xEntry; + + const uno::Sequence< Reference< XDictionary > > + aDics( xDicList->getDictionaries() ); + const Reference< XDictionary > + *pDic = aDics.getConstArray(); + INT32 nDics = xDicList->getCount(); + + INT32 i; + for (i = 0; i < nDics; i++) + { + Reference< XDictionary1 > axDic( pDic[i], UNO_QUERY ); + + DictionaryType eType = axDic->getDictionaryType(); + INT16 nLang = axDic->getLanguage(); + + if ( axDic.is() && axDic->isActive() + && (nLang == nLanguage || nLang == LANGUAGE_NONE) ) + { + DBG_ASSERT( eType != DictionaryType_MIXED, + "lng : unexpected dictionary type" ); + + if ( (!bSearchPosDics && eType == DictionaryType_NEGATIVE) + || ( bSearchPosDics && eType == DictionaryType_POSITIVE)) + { + if ( (xEntry = axDic->getEntry( rWord )).is() ) + { + if (bSearchSpellEntry || lcl_HasHyphInfo( xEntry )) + break; + } + } + } + } + + return xEntry; +} + + +/////////////////////////////////////////////////////////////////////////// + +Locale CreateLocale( LanguageType eLang ) +{ + if ( eLang == LANGUAGE_NONE ) + eLang = LANGUAGE_SYSTEM; + String aLangStr, aCtryStr; + ConvertLanguageToIsoNames( eLang, aLangStr, aCtryStr ); + + return Locale( aLangStr, aCtryStr, OUString() ); +} + +LanguageType LocaleToLanguage( const Locale& rLocale ) +{ + // empty language -> LANGUAGE_NONE + if ( rLocale.Language.getLength() == 0 ) + return LANGUAGE_NONE; + + // Variant of Locale is ignored + LanguageType eRet = + ConvertIsoNamesToLanguage( rLocale.Language, rLocale.Country ); + if ( eRet == LANGUAGE_SYSTEM ) + eRet = LANGUAGE_NONE; + + return eRet; +} + + +Locale& LanguageToLocale( Locale& rLocale, LanguageType eLang ) +{ + String aLangStr, aCtryStr; + if ( eLang == LANGUAGE_NONE ) + eLang = LANGUAGE_SYSTEM; + ConvertLanguageToIsoNames( eLang, aLangStr, aCtryStr ); + rLocale.Language = aLangStr; + rLocale.Country = aCtryStr; + + return rLocale; +} + +uno::Sequence< Locale > LangSeqToLocaleSeq( const uno::Sequence< INT16 > &rLangSeq ) +{ + const INT16 *pLang = rLangSeq.getConstArray(); + INT32 nCount = rLangSeq.getLength(); + + uno::Sequence< Locale > aLocales( nCount ); + Locale *pLocale = aLocales.getArray(); + for (INT32 i = 0; i < nCount; ++i) + { + LanguageToLocale( pLocale[i], pLang[ i ] ); + } + + return aLocales; +} + +uno::Sequence< INT16 > + LocaleSeqToLangSeq( uno::Sequence< Locale > &rLocaleSeq ) +{ + const Locale *pLocale = rLocaleSeq.getConstArray(); + INT32 nCount = rLocaleSeq.getLength(); + + uno::Sequence< INT16 > aLangs( nCount ); + INT16 *pLang = aLangs.getArray(); + for (INT32 i = 0; i < nCount; ++i) + { + pLang[i] = LocaleToLanguage( pLocale[i] ); + + } + + return aLangs; +} + +/////////////////////////////////////////////////////////////////////////// + +// TL_TODO: +// replace this non performant implementations with better ones +// + +BOOL IsUpper( const String &rText, INT16 nLanguage ) +{ + sal_Int32 bUpperFlags = + ::com::sun::star::i18n::KCharacterType::UPPER | + ::com::sun::star::i18n::KCharacterType::LETTER | + ::com::sun::star::i18n::KCharacterType::DIGIT; + return bUpperFlags == CharClass( CreateLocale( nLanguage ) ). + getStringType( rText, 0, rText.Len() ); +} + + +BOOL IsLower( const String &rText, INT16 nLanguage ) +{ + sal_Int32 bUpperFlags = + ::com::sun::star::i18n::KCharacterType::LOWER | + ::com::sun::star::i18n::KCharacterType::LETTER | + ::com::sun::star::i18n::KCharacterType::DIGIT; + return bUpperFlags == CharClass( CreateLocale( nLanguage ) ). + getStringType( rText, 0, rText.Len() ); +} + + +String ToLower( const String &rText, INT16 nLanguage ) +{ + return CharClass( CreateLocale( nLanguage ) ).lower( rText ); +} + + +sal_Unicode ToLower( const sal_Unicode cChar, INT16 nLanguage ) +{ + return CharClass( CreateLocale( nLanguage ) ).lower( cChar ).GetChar(0); +} + + +sal_Unicode ToUpper( const sal_Unicode cChar, INT16 nLanguage ) +{ + return CharClass( CreateLocale( nLanguage ) ).upper( cChar ).GetChar(0); +} + + +BOOL HasDigits( const String &rText ) +{ + xub_StrLen nLen = rText.Len(); + + xub_StrLen i = 0; + while (i < nLen) + { + sal_Unicode cChar = rText.GetChar( i++ ); + if ((sal_Unicode)'0' <= cChar && cChar <= (sal_Unicode)'9') + return TRUE; + } + return FALSE; +} + + +BOOL IsNumeric( const String &rText ) +{ + BOOL bRes = FALSE; + xub_StrLen nLen = rText.Len(); + if (nLen) + { + bRes = TRUE; + xub_StrLen i = 0; + while (i < nLen) + { + sal_Unicode cChar = rText.GetChar( i++ ); + if ( !((sal_Unicode)'0' <= cChar && cChar <= (sal_Unicode)'9') ) + { + bRes = FALSE; + break; + } + } + } + return bRes; +} + + +/////////////////////////////////////////////////////////////////////////// + +Reference< XInterface > GetOneInstanceService( const char *pServiceName ) +{ + Reference< XInterface > xRef; + + if (pServiceName) + { + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + xRef = xMgr->createInstance( A2OU( pServiceName ) ); + } + } + + return xRef; +} + +Reference< XPropertySet > GetLinguProperties() +{ + return Reference< XPropertySet > ( + GetOneInstanceService( SN_LINGU_PROPERTIES ), UNO_QUERY ); +} + +Reference< XSearchableDictionaryList > GetSearchableDictionaryList() +{ + return Reference< XSearchableDictionaryList > ( + GetOneInstanceService( SN_DICTIONARY_LIST ), UNO_QUERY ); +} + +Reference< XDictionaryList > GetDictionaryList() +{ + return Reference< XDictionaryList > ( + GetOneInstanceService( SN_DICTIONARY_LIST ), UNO_QUERY ); +} + +/////////////////////////////////////////////////////////////////////////// + +AppExitListener::AppExitListener() +{ + // add object to Desktop EventListeners in order to properly call + // the AtExit function at appliction exit. + Reference< XMultiServiceFactory > + xMgr = getProcessServiceFactory(); + + if (xMgr.is()) + { + xDesktop = Reference< frame::XDesktop >( + xMgr->createInstance( A2OU( SN_DESKTOP ) ), UNO_QUERY ); + } +} + +AppExitListener::~AppExitListener() +{ +} + + +void AppExitListener::Activate() +{ + if (xDesktop.is()) + xDesktop->addTerminateListener( this ); +} + + +void AppExitListener::Deactivate() +{ + if (xDesktop.is()) + xDesktop->removeTerminateListener( this ); +} + + +void SAL_CALL + AppExitListener::disposing( const EventObject& rEvtSource ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (xDesktop.is() && rEvtSource.Source == xDesktop) + { + xDesktop = NULL; //! release reference to desktop + } +} + + +void SAL_CALL + AppExitListener::queryTermination( const EventObject& rEvtSource ) + throw(frame::TerminationVetoException, RuntimeException) +{ + //MutexGuard aGuard( GetLinguMutex() ); +} + + +void SAL_CALL + AppExitListener::notifyTermination( const EventObject& rEvtSource ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (xDesktop.is() && rEvtSource.Source == xDesktop) + { + AtExit(); + } +} + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + diff --git a/linguistic/source/spelldsp.cxx b/linguistic/source/spelldsp.cxx new file mode 100644 index 000000000000..729d224f1793 --- /dev/null +++ b/linguistic/source/spelldsp.cxx @@ -0,0 +1,733 @@ +/************************************************************************* + * + * $RCSfile: spelldsp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:42 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_ +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#endif + +#include <com/sun/star/linguistic2/SpellFailure.hpp> +#include <cppuhelper/factory.hxx> // helper for factories +#include <com/sun/star/registry/XRegistryKey.hpp> + +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif + +#ifndef _SPELLIMP_HXX +#include <spelldsp.hxx> +#endif +#ifndef _LNGPROPS_HXX +#include <lngprops.hxx> +#endif + +#include "spelldsp.hxx" +#include "spelldta.hxx" +#include "lngsvcmgr.hxx" + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + + +/////////////////////////////////////////////////////////////////////////// + + +SeqLangSvcEntry_Spell::~SeqLangSvcEntry_Spell() +{ +} + + +SeqLangSvcEntry_Spell::SeqLangSvcEntry_Spell( + const Sequence< OUString > &rSvcImplNames ) : + aSvcImplNames ( rSvcImplNames ), + aSvcRefs ( rSvcImplNames.getLength() ), + aSvc1Refs ( rSvcImplNames.getLength() ) +{ +} + +/////////////////////////////////////////////////////////////////////////// + +SpellCheckerDispatcher::SpellCheckerDispatcher( LngSvcMgr &rLngSvcMgr ) : + rMgr (rLngSvcMgr) +{ + pExtCache = NULL; +} + + +SpellCheckerDispatcher::~SpellCheckerDispatcher() +{ + ClearSvcList(); + delete pExtCache; +} + + +void SpellCheckerDispatcher::ClearSvcList() +{ + // release memory for each table entry + SeqLangSvcEntry_Spell *pItem = aSvcList.First(); + while (pItem) + { + SeqLangSvcEntry_Spell *pTmp = pItem; + pItem = aSvcList.Next(); + delete pTmp; + } +} + + +Sequence< Locale > SAL_CALL SpellCheckerDispatcher::getLocales() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return LangSeqToLocaleSeq( getLanguages() ); +} + + +sal_Bool SAL_CALL SpellCheckerDispatcher::hasLocale( const Locale& rLocale ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return hasLanguage( LocaleToLanguage(rLocale) ); +} + + +sal_Bool SAL_CALL + SpellCheckerDispatcher::isValid( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return isValid( rWord, LocaleToLanguage(rLocale), rProperties ); +} + + +Reference< XSpellAlternatives > SAL_CALL + SpellCheckerDispatcher::spell( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return spell( rWord, LocaleToLanguage(rLocale), rProperties ); +} + + +Sequence< sal_Int16 > SAL_CALL SpellCheckerDispatcher::getLanguages() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + ULONG nCnt = aSvcList.Count(); + Sequence< INT16 > aLanguages( nCnt ); + INT16 *pLang = aLanguages.getArray(); + SeqLangSvcEntry_Spell *pEntry = aSvcList.First(); + for (ULONG i = 0; i < nCnt; i++) + { + DBG_ASSERT( pEntry, "lng : pEntry is NULL pointer" ); + pLang[i] = aSvcList.GetKey( pEntry ); + pEntry = aSvcList.Next(); + } + return aLanguages; +} + + +sal_Bool SAL_CALL SpellCheckerDispatcher::hasLanguage( sal_Int16 nLanguage ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return 0 != aSvcList.Seek( nLanguage ); +} + + +sal_Bool SAL_CALL + SpellCheckerDispatcher::isValid( const OUString& rWord, sal_Int16 nLanguage, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = TRUE; + if (LANGUAGE_NONE != nLanguage && rWord.getLength()) + { + if (aOpt.IsSpellInAllLanguages()) + bRes = isValidInAny( rWord, getLanguages(), rProperties ); + else + bRes = isValid_Impl( rWord, nLanguage, rProperties, TRUE ); + } + return bRes; +} + + +BOOL SpellCheckerDispatcher::isValidInAny( + const OUString& rWord, + const Sequence< INT16 >& aLanguages, + const PropertyValues& rProperties ) + throw( RuntimeException, IllegalArgumentException ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = TRUE; + + INT32 nNumLang = aLanguages.getLength(); + const INT16 *pLang = aLanguages.getConstArray(); + BOOL bCheckDics = TRUE; + for (int i = 0; i < nNumLang; i++) + { + // Bug 71632 + if( LANGUAGE_NONE != pLang[i] ) + { + if ((bRes = isValid_Impl( rWord, pLang[i], rProperties, bCheckDics ))) + break; + bCheckDics = FALSE; + } + } + + return bRes; +} + + +BOOL SpellCheckerDispatcher::isValid_Impl( + const OUString& rWord, + INT16 nLanguage, + const PropertyValues& rProperties, + BOOL bCheckDics) + throw( RuntimeException, IllegalArgumentException ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = TRUE; + + if (nLanguage == LANGUAGE_NONE || !rWord.getLength()) + return bRes; + + // search for entry with that language + SeqLangSvcEntry_Spell *pEntry = aSvcList.Seek( nLanguage ); + + if (!pEntry) + { +#ifdef LINGU_EXCEPTIONS + throw IllegalArgumentException(); +#endif + } + else + { + INT32 nLen = pEntry->aSvcRefs.getLength(); + DBG_ASSERT( nLen = pEntry->aSvcImplNames.getLength(), + "lng : sequence length mismatch"); + DBG_ASSERT( pEntry->aFlags.nLastTriedSvcIndex < nLen, + "lng : index out of range"); + + INT32 i = 0; + BOOL bTmpRes = TRUE; + BOOL bTmpResValid = FALSE; + + // try already instantiated services first + { + const Reference< XSpellChecker1 > *pRef1 = + pEntry->aSvc1Refs.getConstArray(); + const Reference< XSpellChecker > *pRef = + pEntry->aSvcRefs.getConstArray(); + while (i <= pEntry->aFlags.nLastTriedSvcIndex + && (!bTmpResValid || FALSE == bTmpRes)) + { + bTmpResValid = TRUE; + if (pRef1[i].is()) + bTmpRes = pRef1[i]->isValid( rWord, nLanguage, rProperties ); + else if (pRef[i].is()) + { + bTmpRes = GetExtCache().CheckWord( rWord, nLanguage, FALSE ); + if (!bTmpRes) + { + bTmpRes = pRef[i]->isValid( rWord, + CreateLocale( nLanguage ), rProperties ); + + // Add correct words to the cache. + // But not those that are correct only because of + // the temporary supplied settings. + if (bTmpRes && 0 == rProperties.getLength()) + GetExtCache().AddWord( rWord, nLanguage ); + } + } + else + bTmpResValid = FALSE; + + if (bTmpResValid) + bRes = bTmpRes; + + ++i; + } + } + + // if still no result instantiate new services and try those + if ((!bTmpResValid || FALSE == bTmpRes) + && pEntry->aFlags.nLastTriedSvcIndex < nLen - 1) + { + const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray(); + Reference< XSpellChecker1 > *pRef1 = pEntry->aSvc1Refs.getArray(); + Reference< XSpellChecker > *pRef = pEntry->aSvcRefs .getArray(); + + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + // build service initialization argument + Sequence< Any > aArgs(2); + aArgs.getArray()[0] <<= GetPropSet(); + //! The dispatcher searches the dictionary-list + //! thus the service needs not to now about it + //aArgs.getArray()[1] <<= GetDicList(); + + while (i < nLen && (!bTmpResValid || FALSE == bTmpRes)) + { + // create specific service via it's implementation name + Reference< XSpellChecker > xSpell( + xMgr->createInstanceWithArguments( + pImplNames[i], aArgs ), + UNO_QUERY ); + Reference< XSpellChecker1 > xSpell1( xSpell, UNO_QUERY ); + pRef [i] = xSpell; + pRef1[i] = xSpell1; + + Reference< XLinguServiceEventBroadcaster > + xBroadcaster( xSpell, UNO_QUERY ); + if (xBroadcaster.is()) + rMgr.AddLngSvcEvtBroadcaster( xBroadcaster ); + + bTmpResValid = TRUE; + if (xSpell1.is()) + bTmpRes = xSpell1->isValid( rWord, nLanguage, rProperties ); + else if (xSpell.is()) + { + bTmpRes = GetExtCache().CheckWord( rWord, nLanguage, FALSE ); + if (!bTmpRes) + { + bTmpRes = xSpell->isValid( rWord, + CreateLocale( nLanguage ), rProperties ); + + // Add correct words to the cache. + // But not those that are correct only because of + // the temporary supplied settings. + if (bTmpRes && 0 == rProperties.getLength()) + GetExtCache().AddWord( rWord, nLanguage ); + } + } + else + bTmpResValid = FALSE; + + if (bTmpResValid) + bRes = bTmpRes; + + pEntry->aFlags.nLastTriedSvcIndex = i; + ++i; + } + } + } + } + + // countercheck against results from dictionary which have precedence! + if (bCheckDics && + GetDicList().is() && IsUseDicList( rProperties, GetPropSet() )) + { + BOOL bIsWordOk = bRes; + + Reference< XDictionaryList > xDicList( GetDicList(), UNO_QUERY ); + Reference< XDictionaryEntry > xEntry( SearchDicList( xDicList, + rWord, nLanguage, !bIsWordOk, TRUE ) ); + if (xEntry.is()) + bRes = !bIsWordOk; + } + + return bRes; +} + + +Reference< XSpellAlternatives > SAL_CALL + SpellCheckerDispatcher::spell( const OUString& rWord, sal_Int16 nLanguage, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XSpellAlternatives > xAlt; + if (LANGUAGE_NONE != nLanguage && rWord.getLength()) + { + if (aOpt.IsSpellInAllLanguages()) + xAlt = spellInAny( rWord, getLanguages(), rProperties, nLanguage ); + else + xAlt = spell_Impl( rWord, nLanguage, rProperties, TRUE ); + } + return xAlt; +} + + +Reference< XSpellAlternatives > SpellCheckerDispatcher::spellInAny( + const OUString& aWord, + const Sequence< INT16 >& aLanguages, + const PropertyValues& rProperties, + INT16 nPreferredResultLang) + throw( RuntimeException, IllegalArgumentException ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XSpellAlternatives > xAlt; + + // check preferred language first + BOOL bPrefLangChecked = FALSE; + if ( LANGUAGE_NONE != nPreferredResultLang + && hasLanguage( nPreferredResultLang ) ) + { + xAlt = spell_Impl( aWord, nPreferredResultLang, rProperties, TRUE ); + bPrefLangChecked = TRUE; + } + + // if word is incorrect (or not checked) try the other languages + if (xAlt.is() || !bPrefLangChecked) + { + INT32 nNumLang = aLanguages.getLength(); + const INT16 *pLang = aLanguages.getConstArray(); + for (int i = 0; i < nNumLang; ++i, ++pLang ) + { + if (pLang[i] == nPreferredResultLang) // already checked! + continue; + + // Bug 71632 + if( LANGUAGE_NONE != pLang[i] && hasLanguage( pLang[i] ) ) + { + Reference< XSpellAlternatives > + xLast( spell_Impl( aWord, pLang[i], rProperties, TRUE )); + + // remember first spelling alternatives found + if (xLast.is() && !xAlt.is()) + xAlt = xLast; + + // did we finally find a language in which the word is correct? + if (!xLast.is()) + { + xAlt = NULL; // don't return any spelling alternatives + break; + } + } + } + } + + return xAlt; +} + + +Reference< XSpellAlternatives > SpellCheckerDispatcher::spell_Impl( + const OUString& rWord, + sal_Int16 nLanguage, + const PropertyValues& rProperties, + BOOL bCheckDics ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Reference< XSpellAlternatives > xRes; + + if (nLanguage == LANGUAGE_NONE || !rWord.getLength()) + return xRes; + + // search for entry with that language + SeqLangSvcEntry_Spell *pEntry = aSvcList.Seek( nLanguage ); + + if (!pEntry) + { +#ifdef LINGU_EXCEPTIONS + throw IllegalArgumentException(); +#endif + } + else + { + INT32 nLen = pEntry->aSvcRefs.getLength(); + DBG_ASSERT( nLen = pEntry->aSvcImplNames.getLength(), + "lng : sequence length mismatch"); + DBG_ASSERT( pEntry->aFlags.nLastTriedSvcIndex < nLen, + "lng : index out of range"); + + INT32 i = 0; + Reference< XSpellAlternatives > xTmpRes; + BOOL bTmpResValid = FALSE; + + // try already instantiated services first + { + const Reference< XSpellChecker1 > *pRef1 = + pEntry->aSvc1Refs.getConstArray(); + const Reference< XSpellChecker > *pRef = + pEntry->aSvcRefs.getConstArray(); + while (i <= pEntry->aFlags.nLastTriedSvcIndex + && (!bTmpResValid || xTmpRes.is()) ) + { + bTmpResValid = TRUE; + if (pRef1[i].is()) + xTmpRes = pRef1[i]->spell( rWord, nLanguage, rProperties ); + else if (pRef[i].is()) + { + BOOL bOK = GetExtCache().CheckWord( rWord, nLanguage, FALSE ); + if (bOK) + xTmpRes = NULL; + else + { + xTmpRes = pRef[i]->spell( rWord, + CreateLocale( nLanguage ), rProperties ); + + // Add correct words to the cache. + // But not those that are correct only because of + // the temporary supplied settings. + if (!xTmpRes.is() && 0 == rProperties.getLength()) + GetExtCache().AddWord( rWord, nLanguage ); + } + } + else + bTmpResValid = FALSE; + + // remember first found alternatives only + if (!xRes.is() && bTmpResValid) + xRes = xTmpRes; + + ++i; + } + } + + // if still no result instantiate new services and try those + if ((!bTmpResValid || xTmpRes.is()) + && pEntry->aFlags.nLastTriedSvcIndex < nLen - 1) + { + const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray(); + Reference< XSpellChecker1 > *pRef1 = pEntry->aSvc1Refs.getArray(); + Reference< XSpellChecker > *pRef = pEntry->aSvcRefs .getArray(); + + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + // build service initialization argument + Sequence< Any > aArgs(2); + aArgs.getArray()[0] <<= GetPropSet(); + //! The dispatcher searches the dictionary-list + //! thus the service needs not to now about it + //aArgs.getArray()[1] <<= GetDicList(); + + while (i < nLen && (!bTmpResValid || xTmpRes.is())) + { + // create specific service via it's implementation name + Reference< XSpellChecker > xSpell( + xMgr->createInstanceWithArguments( + pImplNames[i], aArgs ), + UNO_QUERY ); + Reference< XSpellChecker1 > xSpell1( xSpell, UNO_QUERY ); + pRef [i] = xSpell; + pRef1[i] = xSpell1; + + Reference< XLinguServiceEventBroadcaster > + xBroadcaster( xSpell, UNO_QUERY ); + if (xBroadcaster.is()) + rMgr.AddLngSvcEvtBroadcaster( xBroadcaster ); + + bTmpResValid = TRUE; + if (xSpell1.is()) + xTmpRes = xSpell1->spell( rWord, nLanguage, rProperties ); + else if (xSpell.is()) + { + BOOL bOK = GetExtCache().CheckWord( rWord, nLanguage, FALSE ); + if (bOK) + xTmpRes = NULL; + else + { + xTmpRes = xSpell->spell( rWord, + CreateLocale( nLanguage ), rProperties ); + + // Add correct words to the cache. + // But not those that are correct only because of + // the temporary supplied settings. + if (!xTmpRes.is() && 0 == rProperties.getLength()) + GetExtCache().AddWord( rWord, nLanguage ); + } + } + else + bTmpResValid = FALSE; + + // remember first found alternatives only + if (!xRes.is() && bTmpResValid) + xRes = xTmpRes; + + pEntry->aFlags.nLastTriedSvcIndex = i; + ++i; + } + } + } + + // if word is finally found to be correct + // clear previously remembered alternatives + if (bTmpResValid && !xTmpRes.is()) + xRes = NULL; + } + + // countercheck against results from dictionary which have precedence! + if (bCheckDics && + GetDicList().is() && IsUseDicList( rProperties, GetPropSet() )) + { + BOOL bIsWordOk = !xRes.is(); + + Reference< XDictionaryList > xDicList( GetDicList(), UNO_QUERY ); + Reference< XDictionaryEntry > xEntry( SearchDicList( xDicList, + rWord, nLanguage, !bIsWordOk, TRUE ) ); + + OUString aRplcTxt; + BOOL bAddAlternative = FALSE; + + if (bIsWordOk && xEntry.is()) // negative entry found + { + aRplcTxt = xEntry->getReplacementText(); + bAddAlternative = TRUE; + } + else if (!bIsWordOk) + { + if (xEntry.is()) // positive entry found + xRes = NULL; + else + { + // search for negative entry to provide additional alternative + xEntry = SearchDicList( xDicList, + rWord, nLanguage, FALSE, TRUE ); + if (xEntry.is()) + { + aRplcTxt = xEntry->getReplacementText(); + bAddAlternative = TRUE; + } + } + } + + // (additional) alternative found? + if (bAddAlternative) + { + Reference< XSpellAlternatives > xAlt( + new SpellAlternatives( rWord, nLanguage, + SpellFailure::IS_NEGATIVE_WORD, aRplcTxt ) ); + xRes = MergeProposals( xAlt, xRes ); + } + } + + return xRes; +} + + +void SpellCheckerDispatcher::SetServiceList( const Locale &rLocale, + const Sequence< OUString > &rSvcImplNames ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (pExtCache) + pExtCache->Flush(); // new services may spell differently... + + // search for entry with that language + INT16 nLanguage = LocaleToLanguage( rLocale ); + SeqLangSvcEntry_Spell *pEntry = aSvcList.Seek( nLanguage ); + + if (pEntry) + { + INT32 nLen = rSvcImplNames.getLength(); + pEntry->aSvcImplNames = rSvcImplNames; + pEntry->aSvcRefs = Sequence< Reference < XSpellChecker > > ( nLen ); + pEntry->aSvc1Refs = Sequence< Reference < XSpellChecker1 > >( nLen ); + pEntry->aFlags = SvcFlags(); + } + else + { + pEntry = new SeqLangSvcEntry_Spell( rSvcImplNames ); + aSvcList.Insert( nLanguage, pEntry ); + DBG_ASSERT( aSvcList.Seek( nLanguage ), "lng : Insert failed" ); + } +} + + +Sequence< OUString > + SpellCheckerDispatcher::GetServiceList( const Locale &rLocale ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aRes; + + // search for entry with that language and use data from that + INT16 nLanguage = LocaleToLanguage( rLocale ); + SeqLangSvcEntry_Spell *pEntry = aSvcList.Seek( nLanguage ); + if (pEntry) + aRes = pEntry->aSvcImplNames; + + return aRes; +} + + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/spelldsp.hxx b/linguistic/source/spelldsp.hxx new file mode 100644 index 000000000000..d8e99f2b3f71 --- /dev/null +++ b/linguistic/source/spelldsp.hxx @@ -0,0 +1,277 @@ +/************************************************************************* + * + * $RCSfile: spelldsp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:42 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_SPELLDSP_HXX_ +#define _LINGUISTIC_SPELLDSP_HXX_ + +#include "lngopt.hxx" +#include "misc.hxx" +#include "iprcache.hxx" + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations +#include <cppuhelper/implbase2.hxx> // helper for implementations +#include <cppuhelper/implbase7.hxx> // helper for implementations + +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_ +#include <com/sun/star/lang/XInitialization.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_ +#include <com/sun/star/lang/XServiceDisplayName.hpp> +#endif +#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/XSpellChecker1.hpp> +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp> + +#ifndef _TOOLS_TABLE_HXX +#include <tools/table.hxx> +#endif + + +class LngSvcMgr; + +/////////////////////////////////////////////////////////////////////////// + +class SeqLangSvcEntry_Spell +{ + friend class SpellCheckerDispatcher; + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aSvcImplNames; + ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellChecker > > aSvcRefs; + ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellChecker1 > > aSvc1Refs; + +// INT16 nLang; //used as key in the table + SvcFlags aFlags; + +public: + SeqLangSvcEntry_Spell() {} + SeqLangSvcEntry_Spell( const ::com::sun::star::uno::Sequence< + ::rtl::OUString > &rSvcImplNames ); + ~SeqLangSvcEntry_Spell(); + + BOOL IsAlreadyWarned() const { return aFlags.bAlreadyWarned != 0; } + void SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; } + BOOL IsDoWarnAgain() const { return aFlags.bDoWarnAgain != 0; } + void SetDoWarnAgain(BOOL bVal) { aFlags.bDoWarnAgain = 0 != bVal; } +}; + +DECLARE_TABLE( SpellSvcList, SeqLangSvcEntry_Spell * ); + + +class SpellCheckerDispatcher : + public cppu::WeakImplHelper2 + < + ::com::sun::star::linguistic2::XSpellChecker, + ::com::sun::star::linguistic2::XSpellChecker1 + >, + public LinguDispatcher +{ + SpellSvcList aSvcList; + LinguOptions aOpt; + + ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > xPropSet; + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > xDicList; + + LngSvcMgr &rMgr; + linguistic::IPRSpellCache *pExtCache; // SpellCache for external SpellCheckers + // (usually those not called via XSpellChecker1) + // One for all of them. + + // disallow copy-constructor and assignment-operator for now + SpellCheckerDispatcher(const SpellCheckerDispatcher &); + SpellCheckerDispatcher & operator = (const SpellCheckerDispatcher &); + + inline linguistic::IPRSpellCache & GetExtCache() const; + + inline ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + GetPropSet(); + inline ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > + GetDicList(); + + void ClearSvcList(); + + BOOL isValid_Impl(const ::rtl::OUString& aWord, INT16 nLanguage, + const ::com::sun::star::beans::PropertyValues& aProperties, + BOOL bCheckDics) + throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException ); + + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > + spell_Impl(const ::rtl::OUString& aWord, INT16 nLanguage, + const ::com::sun::star::beans::PropertyValues& aProperties, + BOOL bCheckDics) + throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException ); + + BOOL isValidInAny(const ::rtl::OUString& aWord, + const ::com::sun::star::uno::Sequence< INT16 >& aLanguages, + const ::com::sun::star::beans::PropertyValues& aProperties) + throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException ); + + com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > + spellInAny(const ::rtl::OUString& aWord, + const ::com::sun::star::uno::Sequence< INT16 >& aLanguages, + const ::com::sun::star::beans::PropertyValues& aProperties, + INT16 nPreferredResultLang) + throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException ); + +public: + SpellCheckerDispatcher( LngSvcMgr &rLngSvcMgr ); + virtual ~SpellCheckerDispatcher(); + + // XSupportedLocales (for XSpellChecker) + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::lang::Locale > SAL_CALL + getLocales() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + hasLocale( const ::com::sun::star::lang::Locale& aLocale ) + throw(::com::sun::star::uno::RuntimeException); + + // XSpellChecker + virtual sal_Bool SAL_CALL + isValid( const ::rtl::OUString& aWord, + const ::com::sun::star::lang::Locale& aLocale, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL + spell( const ::rtl::OUString& aWord, + const ::com::sun::star::lang::Locale& aLocale, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + + // XSupportedLanguages (for XSpellChecker1) + virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL + getLanguages() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + hasLanguage( sal_Int16 nLanguage ) + throw(::com::sun::star::uno::RuntimeException); + + // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language) + virtual sal_Bool SAL_CALL + isValid( const ::rtl::OUString& aWord, sal_Int16 nLanguage, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL + spell( const ::rtl::OUString& aWord, sal_Int16 nLanguage, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + + // LinguDispatcher + virtual void + SetServiceList( const ::com::sun::star::lang::Locale &rLocale, + const ::com::sun::star::uno::Sequence< + rtl::OUString > &rSvcImplNames ); + virtual ::com::sun::star::uno::Sequence< rtl::OUString > + GetServiceList( const ::com::sun::star::lang::Locale &rLocale ); +}; + + +inline linguistic::IPRSpellCache & SpellCheckerDispatcher::GetExtCache() const +{ + return pExtCache ? *pExtCache : * new linguistic::IPRSpellCache( 997 ); +} + + +inline ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + SpellCheckerDispatcher::GetPropSet() +{ + return xPropSet.is() ? + xPropSet : xPropSet = linguistic::GetLinguProperties(); +} + + +inline ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XSearchableDictionaryList > + SpellCheckerDispatcher::GetDicList() +{ + return xDicList.is() ? + xDicList : xDicList = linguistic::GetSearchableDictionaryList(); +} + + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/source/spelldta.cxx b/linguistic/source/spelldta.cxx new file mode 100644 index 000000000000..43d403d18c8c --- /dev/null +++ b/linguistic/source/spelldta.cxx @@ -0,0 +1,244 @@ +/************************************************************************* + * + * $RCSfile: spelldta.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:42 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif + +#include <com/sun/star/linguistic2/SpellFailure.hpp> + +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#include "spelldta.hxx" +#include "lngsvcmgr.hxx" + + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + + +#define MAX_PROPOSALS 40 + +Reference< XSpellAlternatives > MergeProposals( + Reference< XSpellAlternatives > &rxAlt1, + Reference< XSpellAlternatives > &rxAlt2) +{ + Reference< XSpellAlternatives > xMerged; + + if (!rxAlt1.is()) + xMerged = rxAlt2; + else if (!rxAlt2.is()) + xMerged = rxAlt1; + else + { + INT32 nAltCount1 = rxAlt1->getAlternativesCount(); + Sequence< OUString > aAlt1( rxAlt1->getAlternatives() ); + const OUString *pAlt1 = aAlt1.getConstArray(); + + INT32 nAltCount2 = rxAlt2->getAlternativesCount(); + Sequence< OUString > aAlt2( rxAlt2->getAlternatives() ); + const OUString *pAlt2 = aAlt2.getConstArray(); + + INT32 nCountNew = Min( nAltCount1 + nAltCount2, (INT32) MAX_PROPOSALS ); + Sequence< OUString > aAltNew( nCountNew ); + OUString *pAltNew = aAltNew.getArray(); + + INT32 nIndex = 0; + INT32 i = 0; + for (int j = 0; j < 2; j++) + { + INT32 nCount = j == 0 ? nAltCount1 : nAltCount2; + const OUString *pAlt = j == 0 ? pAlt1 : pAlt2; + for (i = 0; i < nCount && nIndex < MAX_PROPOSALS; i++) + { + if (pAlt[i].getLength()) + pAltNew[ nIndex++ ] = pAlt[ i ]; + } + } + DBG_ASSERT(nIndex == nCountNew, "lng : wrong number of proposals"); + + SpellAlternatives *pSpellAlt = new SpellAlternatives; + pSpellAlt->SetWordLanguage( rxAlt1->getWord(), + LocaleToLanguage( rxAlt1->getLocale() ) ); + pSpellAlt->SetFailureType( rxAlt1->getFailureType() ); + pSpellAlt->SetAlternatives( aAltNew ); + xMerged = pSpellAlt; + } + + return xMerged; +} + + +/////////////////////////////////////////////////////////////////////////// + + +SpellAlternatives::SpellAlternatives() +{ + nLanguage = LANGUAGE_NONE; + nType = SpellFailure::IS_NEGATIVE_WORD; +} + + +SpellAlternatives::SpellAlternatives( + const OUString &rWord, INT16 nLang, + INT16 nFailureType, const OUString &rRplcWord ) : + aWord (rWord), + nLanguage (nLang), + nType (nFailureType), + aAlt ( Sequence< OUString >(1) ) +{ + if (rRplcWord.getLength()) + aAlt.getArray()[ 0 ] = rRplcWord; + else + aAlt.realloc( 0 ); +} + + +SpellAlternatives::~SpellAlternatives() +{ +} + + +OUString SAL_CALL SpellAlternatives::getWord() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aWord; +} + + +Locale SAL_CALL SpellAlternatives::getLocale() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return CreateLocale( nLanguage ); +} + + +sal_Int16 SAL_CALL SpellAlternatives::getFailureType() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return nType; +} + + +sal_Int16 SAL_CALL SpellAlternatives::getAlternativesCount() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return (INT16) aAlt.getLength(); +} + + +Sequence< OUString > SAL_CALL SpellAlternatives::getAlternatives() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aAlt; +} + + +void SpellAlternatives::SetWordLanguage(const OUString &rWord, INT16 nLang) +{ + MutexGuard aGuard( GetLinguMutex() ); + aWord = rWord; + nLanguage = nLang; +} + + +void SpellAlternatives::SetFailureType(INT16 nTypeP) +{ + MutexGuard aGuard( GetLinguMutex() ); + nType = nTypeP; +} + + +void SpellAlternatives::SetAlternatives( const Sequence< OUString > &rAlt ) +{ + MutexGuard aGuard( GetLinguMutex() ); + aAlt = rAlt; +} + + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + diff --git a/linguistic/source/thesdsp.cxx b/linguistic/source/thesdsp.cxx new file mode 100644 index 000000000000..6978ff900414 --- /dev/null +++ b/linguistic/source/thesdsp.cxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * $RCSfile: thesdsp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:43 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LANG_HXX //autogen wg. LANGUAGE_ENGLISH_US +#include <tools/lang.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif + +#include <cppuhelper/factory.hxx> // helper for factories +#include <com/sun/star/registry/XRegistryKey.hpp> +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#include "thesdsp.hxx" +#include "lngprops.hxx" + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + +/////////////////////////////////////////////////////////////////////////// + +SeqLangSvcEntry_Thes::~SeqLangSvcEntry_Thes() +{ +} + + +SeqLangSvcEntry_Thes::SeqLangSvcEntry_Thes( + const Sequence< OUString > &rSvcImplNames ) : + aSvcImplNames ( rSvcImplNames ), + aSvcRefs ( rSvcImplNames.getLength() ) +{ +} + +/////////////////////////////////////////////////////////////////////////// + +ThesaurusDispatcher::ThesaurusDispatcher() +{ +} + + +ThesaurusDispatcher::~ThesaurusDispatcher() +{ + ClearSvcList(); +} + + +void ThesaurusDispatcher::ClearSvcList() +{ + // release memory for each table entry + SeqLangSvcEntry_Thes *pItem = aSvcList.First(); + while (pItem) + { + SeqLangSvcEntry_Thes *pTmp = pItem; + pItem = aSvcList.Next(); + delete pTmp; + } +} + + +Sequence< Locale > SAL_CALL + ThesaurusDispatcher::getLocales() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + ULONG nCnt = aSvcList.Count(); + Sequence< Locale > aLocales( nCnt ); + Locale *pItem = aLocales.getArray(); + SeqLangSvcEntry_Thes *pEntry = aSvcList.First(); + for (ULONG i = 0; i < nCnt; i++) + { + DBG_ASSERT( pEntry, "lng : pEntry is NULL pointer" ); + pItem[i] = CreateLocale( aSvcList.GetKey( pEntry ) ); + pEntry = aSvcList.Next(); + } + return aLocales; +} + + +sal_Bool SAL_CALL + ThesaurusDispatcher::hasLocale( const Locale& rLocale ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return 0 != aSvcList.Seek( LocaleToLanguage( rLocale ) ); +} + + +Sequence< Reference< XMeaning > > SAL_CALL + ThesaurusDispatcher::queryMeanings( + const OUString& rTerm, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< Reference< XMeaning > > aMeanings; + + INT16 nLanguage = LocaleToLanguage( rLocale ); + if (nLanguage == LANGUAGE_NONE || !rTerm.getLength()) + return aMeanings; + + // search for entry with that language + SeqLangSvcEntry_Thes *pEntry = aSvcList.Seek( nLanguage ); + + if (!pEntry) + { +#ifdef LINGU_EXCEPTIONS + throw IllegalArgumentException(); +#endif + } + else + { + INT32 nLen = pEntry->aSvcRefs.getLength(); + DBG_ASSERT( nLen = pEntry->aSvcImplNames.getLength(), + "lng : sequence length mismatch"); + DBG_ASSERT( pEntry->aFlags.nLastTriedSvcIndex < nLen, + "lng : index out of range"); + + INT32 i = 0; + + // try already instantiated services first + { + const Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getConstArray(); + while (i <= pEntry->aFlags.nLastTriedSvcIndex + && aMeanings.getLength() == 0) + { + if (pRef[i].is()) + aMeanings = pRef[i]->queryMeanings( rTerm, rLocale, rProperties ); + ++i; + } + } + + // if still no result instantiate new services and try those + if (aMeanings.getLength() == 0 + && pEntry->aFlags.nLastTriedSvcIndex < nLen - 1) + { + const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray(); + Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getArray(); + + Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); + if (xMgr.is()) + { + // build service initialization argument + Sequence< Any > aArgs(1); + aArgs.getArray()[0] <<= GetPropSet(); + + while (i < nLen && aMeanings.getLength() == 0) + { + // create specific service via it's implementation name + Reference< XThesaurus > xThes( + xMgr->createInstanceWithArguments( + pImplNames[i], aArgs ), + UNO_QUERY ); + pRef[i] = xThes; + + if (xThes.is()) + aMeanings = xThes->queryMeanings( rTerm, rLocale, rProperties ); + + pEntry->aFlags.nLastTriedSvcIndex = i; + ++i; + } + } + } + } + + return aMeanings; +} + + +void ThesaurusDispatcher::SetServiceList( const Locale &rLocale, + const Sequence< OUString > &rSvcImplNames ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // search for entry with that language + INT16 nLanguage = LocaleToLanguage( rLocale ); + SeqLangSvcEntry_Thes *pEntry = aSvcList.Seek( nLanguage ); + + if (pEntry) + { + pEntry->aSvcImplNames = rSvcImplNames; + pEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( + rSvcImplNames.getLength() ); + pEntry->aFlags = SvcFlags(); + } + else + { + pEntry = new SeqLangSvcEntry_Thes( rSvcImplNames ); + aSvcList.Insert( nLanguage, pEntry ); + DBG_ASSERT( aSvcList.Seek( nLanguage ), "lng : Insert failed" ); + } +} + + +Sequence< OUString > + ThesaurusDispatcher::GetServiceList( const Locale &rLocale ) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aRes; + + // search for entry with that language and use data from that + INT16 nLanguage = LocaleToLanguage( rLocale ); + SeqLangSvcEntry_Thes *pEntry = aSvcList.Seek( nLanguage ); + if (pEntry) + aRes = pEntry->aSvcImplNames; + + return aRes; +} + + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/source/thesdsp.hxx b/linguistic/source/thesdsp.hxx new file mode 100644 index 000000000000..1e878e4f5c04 --- /dev/null +++ b/linguistic/source/thesdsp.hxx @@ -0,0 +1,209 @@ +/************************************************************************* + * + * $RCSfile: thesdsp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:43 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGUISTIC_THESDSP_HXX_ +#define _LINGUISTIC_THESDSP_HXX_ + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_ +#include <com/sun/star/uno/Sequence.h> +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYACCESS_HPP_ +#include <com/sun/star/beans/XPropertyAccess.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_ +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_ +#include <com/sun/star/lang/XInitialization.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_ +#include <com/sun/star/lang/XServiceDisplayName.hpp> +#endif + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/linguistic2/XThesaurus.hpp> + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations +#include <cppuhelper/implbase5.hxx> // helper for implementations + +#ifndef _CPPUHELPER_INTERFACECONTAINER_H_ +#include <cppuhelper/interfacecontainer.h> +#endif + +#include <vos/mutex.hxx> + +#ifndef _TOOLS_TABLE_HXX +#include <tools/table.hxx> +#endif + +#include "lngopt.hxx" + + +class LinguOptions; + +namespace com { namespace sun { namespace star { namespace beans { + class XPropertySet; +}}}}; + +/////////////////////////////////////////////////////////////////////////// + +class SeqLangSvcEntry_Thes +{ + friend class ThesaurusDispatcher; + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aSvcImplNames; + ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XThesaurus > > aSvcRefs; +// INT16 nLang; //used as key in the table + SvcFlags aFlags; + +public: + SeqLangSvcEntry_Thes() {} + SeqLangSvcEntry_Thes( const ::com::sun::star::uno::Sequence< + ::rtl::OUString > &rSvcImplNames ); + ~SeqLangSvcEntry_Thes(); + + BOOL IsAlreadyWarned() const { return aFlags.bAlreadyWarned != 0; } + void SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; } + BOOL IsDoWarnAgain() const { return aFlags.bDoWarnAgain != 0; } + void SetDoWarnAgain(BOOL bVal) { aFlags.bDoWarnAgain = 0 != bVal; } +}; + + + +DECLARE_TABLE( ThesSvcList, SeqLangSvcEntry_Thes * ); + +class ThesaurusDispatcher : + public cppu::WeakImplHelper1 + < + ::com::sun::star::linguistic2::XThesaurus + >, + public LinguDispatcher +{ + ThesSvcList aSvcList; + + ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > xPropSet; + + // disallow copy-constructor and assignment-operator for now + ThesaurusDispatcher(const ThesaurusDispatcher &); + ThesaurusDispatcher & operator = (const ThesaurusDispatcher &); + + inline ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + GetPropSet(); + + void ClearSvcList(); + +public: + ThesaurusDispatcher(); + virtual ~ThesaurusDispatcher(); + + // XSupportedLocales + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::lang::Locale > SAL_CALL + getLocales() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL + hasLocale( const ::com::sun::star::lang::Locale& aLocale ) + throw(::com::sun::star::uno::RuntimeException); + + // XThesaurus + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::linguistic2::XMeaning > > SAL_CALL + queryMeanings( const ::rtl::OUString& aTerm, + const ::com::sun::star::lang::Locale& aLocale, + const ::com::sun::star::beans::PropertyValues& aProperties ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + + // LinguDispatcher + virtual void + SetServiceList( const ::com::sun::star::lang::Locale &rLocale, + const ::com::sun::star::uno::Sequence< + rtl::OUString > &rSvcImplNames ); + virtual ::com::sun::star::uno::Sequence< rtl::OUString > + GetServiceList( const ::com::sun::star::lang::Locale &rLocale ); +}; + + +inline ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + ThesaurusDispatcher::GetPropSet() +{ + return xPropSet.is() ? + xPropSet : xPropSet = linguistic::GetLinguProperties(); +} + + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/workben/exports.dxp b/linguistic/workben/exports.dxp new file mode 100644 index 000000000000..b0f85bf7bebf --- /dev/null +++ b/linguistic/workben/exports.dxp @@ -0,0 +1,3 @@ +component_getFactory +component_getImplementationEnvironment +component_writeInfo diff --git a/linguistic/workben/lex.map b/linguistic/workben/lex.map new file mode 100644 index 000000000000..5e2ee0a16c4c --- /dev/null +++ b/linguistic/workben/lex.map @@ -0,0 +1,8 @@ +LNG_1_0 { + global: + component_getFactory; + component_getImplementationEnvironment; + component_writeInfo; + local: + *; +}; diff --git a/linguistic/workben/makefile.mk b/linguistic/workben/makefile.mk new file mode 100644 index 000000000000..0ba6dfce063b --- /dev/null +++ b/linguistic/workben/makefile.mk @@ -0,0 +1,158 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-11-17 12:37:43 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ = .. + +PRJNAME = lingu +TARGET = lex +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE + +#----- Settings --------------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +UNOUCRDEP= $(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB= $(SOLARBINDIR)$/applicat.rdb + +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.XOtherLingu\ + 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 + + +.IF "$(header)" == "" + +EXCEPTIONSFILES= \ + $(SLO)$/sprophelp.obj\ + $(SLO)$/sspellimp.obj + +SLOFILES= \ + $(SLO)$/sprophelp.obj\ + $(SLO)$/sreg.obj\ + $(SLO)$/sspellimp.obj + + +SHL1TARGET= $(TARGET)$(UPD)$(DLLPOSTFIX) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(UNOLIB) \ + $(VOSLIB) \ + $(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= $(TARGET).map +.ENDIF + +# build DEF file +DEF1NAME =$(SHL1TARGET) +#DEF1DEPN =$(MISC)$/$(SHL1TARGET).flt +#DEFLIB1NAME =$(TARGET) +#DEF1DES =Linguistic2 main DLL +DEF1EXPORTFILE= exports.dxp + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/linguistic/workben/sprophelp.cxx b/linguistic/workben/sprophelp.cxx new file mode 100644 index 000000000000..4c532949ed9d --- /dev/null +++ b/linguistic/workben/sprophelp.cxx @@ -0,0 +1,411 @@ +/************************************************************************* + * + * $RCSfile: sprophelp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:44 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "misc.hxx" + +#include "sprophelp.hxx" +#include "lngprops.hxx" + +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif + +#include <com/sun/star/linguistic2/LinguServiceEvent.hpp> +#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp> +#include <com/sun/star/linguistic2/XLinguServiceEventListener.hpp> + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +//using namespace utl; +using namespace osl; +using namespace rtl; +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; + + +#define A2OU(x) ::rtl::OUString::createFromAscii( x ) + +/////////////////////////////////////////////////////////////////////////// + + +PropertyChgHelper::PropertyChgHelper( + const Reference< XInterface > & rxSource, + Reference< XPropertySet > &rxPropSet, + const char *pPropNames[], USHORT nPropCount ) : + xMyEvtObj (rxSource), + xPropSet (rxPropSet), + aPropNames (nPropCount), + aLngSvcEvtListeners (GetLinguMutex()) +{ + OUString *pName = aPropNames.getArray(); + for (INT32 i = 0; i < nPropCount; ++i) + { + pName[i] = A2OU( pPropNames[i] ); + } +} + + +PropertyChgHelper::PropertyChgHelper( const PropertyChgHelper &rHelper ) : + aLngSvcEvtListeners (GetLinguMutex()) +{ + xPropSet = rHelper.xPropSet; + aPropNames = rHelper.aPropNames; + AddAsPropListener(); + + xMyEvtObj = rHelper.xMyEvtObj; +} + + +PropertyChgHelper::~PropertyChgHelper() +{ +} + + +void PropertyChgHelper::AddAsPropListener() +{ + if (xPropSet.is()) + { + INT32 nLen = aPropNames.getLength(); + const OUString *pPropName = aPropNames.getConstArray(); + for (INT32 i = 0; i < nLen; ++i) + { + if (pPropName[i].getLength()) + xPropSet->addPropertyChangeListener( pPropName[i], this ); + } + } +} + +void PropertyChgHelper::RemoveAsPropListener() +{ + if (xPropSet.is()) + { + INT32 nLen = aPropNames.getLength(); + const OUString *pPropName = aPropNames.getConstArray(); + for (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() ); + + BOOL bRes = FALSE; + if (rxListener.is()) + { + 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() ); + + BOOL bRes = FALSE; + if (rxListener.is()) + { + 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 +}; + + +PropertyHelper_Spell::PropertyHelper_Spell( + const Reference< XInterface > & rxSource, + Reference< XPropertySet > &rxPropSet ) : + PropertyChgHelper ( rxSource, rxPropSet, aSP, sizeof(aSP) / sizeof(aSP[0]) ) +{ + SetDefault(); + INT32 nLen = GetPropNames().getLength(); + if (rxPropSet.is() && nLen) + { + const OUString *pPropName = GetPropNames().getConstArray(); + for (INT32 i = 0; i < nLen; ++i) + { + BOOL *pbVal = NULL, + *pbResVal = NULL; + + if (A2OU( UPN_IS_GERMAN_PRE_REFORM ) == pPropName[i]) + { + pbVal = &bIsGermanPreReform; + pbResVal = &bResIsGermanPreReform; + } + else if (A2OU( UPN_IS_IGNORE_CONTROL_CHARACTERS ) == pPropName[i]) + { + pbVal = &bIsIgnoreControlCharacters; + pbResVal = &bResIsIgnoreControlCharacters; + } + else if (A2OU( UPN_IS_USE_DICTIONARY_LIST ) == pPropName[i]) + { + pbVal = &bIsUseDictionaryList; + pbResVal = &bResIsUseDictionaryList; + } + else if (A2OU( UPN_IS_SPELL_UPPER_CASE ) == pPropName[i]) + { + pbVal = &bIsSpellUpperCase; + pbResVal = &bResIsSpellUpperCase; + } + else if (A2OU( UPN_IS_SPELL_WITH_DIGITS ) == pPropName[i]) + { + pbVal = &bIsSpellWithDigits; + pbResVal = &bResIsSpellWithDigits; + } + else if (A2OU( UPN_IS_SPELL_CAPITALIZATION ) == pPropName[i]) + { + pbVal = &bIsSpellCapitalization; + pbResVal = &bResIsSpellCapitalization; + } + + if (pbVal && pbResVal) + { + rxPropSet->getPropertyValue( pPropName[i] ) >>= *pbVal; + *pbResVal = *pbVal; + } + } + } +} + + +PropertyHelper_Spell::~PropertyHelper_Spell() +{ +} + + +void PropertyHelper_Spell::SetDefault() +{ + bResIsGermanPreReform = bIsGermanPreReform = FALSE; + bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters = TRUE; + bResIsUseDictionaryList = bIsUseDictionaryList = TRUE; + bResIsSpellUpperCase = bIsSpellUpperCase = FALSE; + bResIsSpellWithDigits = bIsSpellWithDigits = FALSE; + bResIsSpellCapitalization = bIsSpellCapitalization = TRUE; +} + + +void SAL_CALL + PropertyHelper_Spell::propertyChange( const PropertyChangeEvent& rEvt ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (GetPropSet().is() && rEvt.Source == GetPropSet()) + { + INT16 nLngSvcFlags = 0; + BOOL bSCWA = FALSE, // SPELL_CORRECT_WORDS_AGAIN ? + bSWWA = FALSE; // SPELL_WRONG_WORDS_AGAIN ? + + 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 = TRUE; + break; + } + case UPH_IS_USE_DICTIONARY_LIST : + { + pbVal = &bIsUseDictionaryList; + bSCWA = bSWWA = TRUE; + break; + } + case UPH_IS_SPELL_UPPER_CASE : + { + pbVal = &bIsSpellUpperCase; + bSCWA = FALSE == *pbVal; // FALSE->TRUE change? + bSWWA = !bSCWA; // TRUE->FALSE change? + break; + } + case UPH_IS_SPELL_WITH_DIGITS : + { + pbVal = &bIsSpellWithDigits; + bSCWA = FALSE == *pbVal; // FALSE->TRUE change? + bSWWA = !bSCWA; // TRUE->FALSE change? + break; + } + case UPH_IS_SPELL_CAPITALIZATION : + { + pbVal = &bIsSpellCapitalization; + bSCWA = FALSE == *pbVal; // FALSE->TRUE change? + bSWWA = !bSCWA; // TRUE->FALSE change? + break; + } + default: + DBG_ERROR( "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; + // + INT32 nLen = rPropVals.getLength(); + if (nLen) + { + const PropertyValue *pVal = rPropVals.getConstArray(); + for (INT32 i = 0; i < nLen; ++i) + { + 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; + default: + DBG_ERROR( "unknown property" ); + } + if (pbResVal) + pVal[i].Value >>= *pbResVal; + } + } +} + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/workben/sprophelp.hxx b/linguistic/workben/sprophelp.hxx new file mode 100644 index 000000000000..e6afcb4e0c2d --- /dev/null +++ b/linguistic/workben/sprophelp.hxx @@ -0,0 +1,214 @@ +/************************************************************************* + * + * $RCSfile: sprophelp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:45 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGU2_PROPHELP_HXX_ +#define _LINGU2_PROPHELP_HXX_ + +#include <tools/solar.h> + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase2.hxx> // helper for implementations + +#ifndef _CPPUHELPER_INTERFACECONTAINER_H_ +#include <cppuhelper/interfacecontainer.h> +#endif + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_ +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_ +#include <com/sun/star/beans/PropertyValues.hpp> +#endif + +#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp> + +namespace com { namespace sun { namespace star { namespace beans { + class XPropertySet; +}}}}; + +namespace com { namespace sun { namespace star { namespace linguistic2 { + struct LinguServiceEvent; +}}}}; + + +using namespace ::rtl; +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::WeakImplHelper2 + < + XPropertyChangeListener, + XLinguServiceEventBroadcaster + > +{ + Sequence< OUString > aPropNames; + Reference< XInterface > xMyEvtObj; + ::cppu::OInterfaceContainerHelper 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[], USHORT 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 + BOOL bIsGermanPreReform; + BOOL bIsIgnoreControlCharacters; + BOOL bIsUseDictionaryList; + BOOL bIsSpellUpperCase; + BOOL bIsSpellWithDigits; + BOOL bIsSpellCapitalization; + + // return values, will be set to default value or current temporary value + BOOL bResIsGermanPreReform; + BOOL bResIsIgnoreControlCharacters; + BOOL bResIsUseDictionaryList; + BOOL bResIsSpellUpperCase; + BOOL bResIsSpellWithDigits; + 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 ); + + BOOL IsGermanPreReform() const { return bResIsGermanPreReform; } + BOOL IsIgnoreControlCharacters() const { return bResIsIgnoreControlCharacters; } + BOOL IsUseDictionaryList() const { return bResIsUseDictionaryList; } + BOOL IsSpellUpperCase() const { return bResIsSpellUpperCase; } + BOOL IsSpellWithDigits() const { return bResIsSpellWithDigits; } + BOOL IsSpellCapitalization() const { return bResIsSpellCapitalization; } +}; + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/linguistic/workben/sreg.cxx b/linguistic/workben/sreg.cxx new file mode 100644 index 000000000000..ec73c610151a --- /dev/null +++ b/linguistic/workben/sreg.cxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: sreg.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:45 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#include <cppuhelper/factory.hxx> // helper for factories +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif + +#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 sal_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 ); +} + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = SpellChecker_getFactory( + pImplName, + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + pRegistryKey ); + + return pRet; +} + +} + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/workben/sspellimp.cxx b/linguistic/workben/sspellimp.cxx new file mode 100644 index 000000000000..6e7525c58615 --- /dev/null +++ b/linguistic/workben/sspellimp.cxx @@ -0,0 +1,555 @@ +/************************************************************************* + * + * $RCSfile: sspellimp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:45 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_ +#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp> +#endif + +#include <com/sun/star/linguistic2/SpellFailure.hpp> +#include <cppuhelper/factory.hxx> // helper for factories +#include <com/sun/star/registry/XRegistryKey.hpp> + +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _SPELLIMP_HXX +#include <sspellimp.hxx> +#endif + +#include "lngprops.hxx" +#include "spelldta.hxx" + +using namespace utl; +using namespace osl; +using namespace rtl; +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; + + +/////////////////////////////////////////////////////////////////////////// + +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() ) +{ + bDisposing = FALSE; + pPropHelper = NULL; +} + + +SpellChecker::~SpellChecker() +{ + if (pPropHelper) + pPropHelper->RemoveAsPropListener(); +} + + +PropertyHelper_Spell & SpellChecker::GetPropHelper_Impl() +{ + if (!pPropHelper) + { + Reference< XPropertySet > xPropSet( GetLinguProperties(), UNO_QUERY ); + + 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( A2OU("en"), A2OU("US"), OUString() ); + pLocale[1] = Locale( A2OU("de"), A2OU("DE"), OUString() ); + pLocale[2] = Locale( A2OU("de"), A2OU("CH"), OUString() ); + } + + return aSuppLocales; +} + + +sal_Bool SAL_CALL SpellChecker::hasLocale(const Locale& rLocale) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + BOOL bRes = FALSE; + if (!aSuppLocales.getLength()) + getLocales(); + INT32 nLen = aSuppLocales.getLength(); + for (INT32 i = 0; i < nLen; ++i) + { + const Locale *pLocale = aSuppLocales.getConstArray(); + if (rLocale == pLocale[i]) + { + bRes = TRUE; + break; + } + } + return bRes; +} + + +INT16 SpellChecker::GetSpellFailure( const OUString &rWord, const Locale &rLocale ) +{ + // Checks wether a word is OK in a given language (Locale) or not, and + // provides a failure type for the incorrect ones. + // - words with "liss" (case sensitiv) 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. + + INT16 nRes = -1; + + String aTmp( rWord ); + if (aTmp.Len()) + { + if (STRING_NOTFOUND != aTmp.SearchAscii( "liss" )) + { + nRes = SpellFailure::IS_NEGATIVE_WORD; + } + else if (STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'x' ) || + STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'X' )) + { + nRes = SpellFailure::SPELLING_ERROR; + } + else + { + sal_Unicode cChar = aTmp.GetChar( 0 ); + if (cChar == (sal_Unicode) 's' || cChar == (sal_Unicode) '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 TRUE; + + if (!hasLocale( rLocale )) +#ifdef LINGU_EXCEPTIONS + throw( IllegalArgumentException() ); +#else + return 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 simplier solution than the provided + // one using the PropertyHelper_Spell. + PropertyHelper_Spell &rHelper = GetPropHelper(); + rHelper.SetTmpPropVals( rProperties ); + + INT16 nFailure = GetSpellFailure( rWord, rLocale ); + if (nFailure != -1) + { + INT16 nLang = LocaleToLanguage( 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()) + { + INT16 nLang = LocaleToLanguage( rLocale ); + + if (STRING_NOTFOUND != aTmp.SearchAscii( "liss" )) + { + aTmp.SearchAndReplaceAllAscii( "liss", A2OU("liz") ); + xRes = new SpellAlternatives( aTmp, nLang, + SpellFailure::IS_NEGATIVE_WORD, aTmp ); + } + else if (STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'x' ) || + STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'X' )) + { + Sequence< OUString > aStr( 2 ); + OUString *pStr = aStr.getArray(); + String aAlt1( aTmp ), + aAlt2( aTmp ); + aAlt1.SearchAndReplaceAll( (sal_Unicode) 'x', (sal_Unicode) 'u'); + aAlt1.SearchAndReplaceAll( (sal_Unicode) 'X', (sal_Unicode) 'U'); + aAlt2.EraseAllChars( (sal_Unicode) 'x' ); + aAlt2.EraseAllChars( (sal_Unicode) '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 == (sal_Unicode) 's' || cChar == (sal_Unicode) 'S') + { + sal_Unicode cNewChar = cChar == (sal_Unicode) 's' ? + (sal_Unicode) 'S': (sal_Unicode) 's'; + aTmp.GetBufferAccess()[0] = cNewChar; + xRes = new SpellAlternatives( aTmp, nLang, + SpellFailure::CAPTION_ERROR, aTmp ); + } + } + } + + 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 > & rSMgr ) + 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() ); + + BOOL bRes = 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() ); + + BOOL bRes = 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& rLocale ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return A2OU( "StarOffice example SpellChecker" ); +} + + +void SAL_CALL + SpellChecker::initialize( const Sequence< Any >& rArguments ) + throw(Exception, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!pPropHelper) + { + INT32 nLen = rArguments.getLength(); + if (2 == nLen) + { + Reference< XPropertySet > xPropSet; + rArguments.getConstArray()[0] >>= xPropSet; + //rArguments.getConstArray()[1] >>= xDicList; + + //! 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 not longer used. + pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet ); + xPropHelper = pPropHelper; + pPropHelper->AddAsPropListener(); //! after a reference is established + } + else + DBG_ERROR( "wrong number of arguments in sequence" ); + } +} + + +void SAL_CALL + SpellChecker::dispose() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing) + { + bDisposing = 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) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getImplementationName_Static(); +} + + +sal_Bool SAL_CALL SpellChecker::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( INT32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return TRUE; + return FALSE; +} + + +Sequence< OUString > SAL_CALL SpellChecker::getSupportedServiceNames() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getSupportedServiceNames_Static(); +} + + +Sequence< OUString > SpellChecker::getSupportedServiceNames_Static() + throw() +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich + aSNS.getArray()[0] = A2OU( SN_SPELLCHECKER ); + return aSNS; +} + + +sal_Bool SAL_CALL SpellChecker_writeInfo( + void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey ) +{ + try + { + String aImpl( '/' ); + aImpl += SpellChecker::getImplementationName_Static().getStr(); + aImpl.AppendAscii( "/UNO/SERVICES" ); + Reference< registry::XRegistryKey > xNewKey = + pRegistryKey->createKey( aImpl ); + Sequence< OUString > aServices = + SpellChecker::getSupportedServiceNames_Static(); + for( 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 sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, void * ) +{ + void * pRet = 0; + if ( !SpellChecker::getImplementationName_Static().compareToAscii( 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; +} + + +/////////////////////////////////////////////////////////////////////////// + diff --git a/linguistic/workben/sspellimp.hxx b/linguistic/workben/sspellimp.hxx new file mode 100644 index 000000000000..06466e3a8570 --- /dev/null +++ b/linguistic/workben/sspellimp.hxx @@ -0,0 +1,221 @@ +/************************************************************************* + * + * $RCSfile: sspellimp.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-11-17 12:37:46 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _LINGU2_SPELLIMP_HXX_ +#define _LINGU2_SPELLIMP_HXX_ + +#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type +#include <cppuhelper/implbase1.hxx> // helper for implementations +#include <cppuhelper/implbase6.hxx> // helper for implementations + +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_ +#include <com/sun/star/lang/XInitialization.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_ +#include <com/sun/star/lang/XServiceDisplayName.hpp> +#endif +#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> + +#ifndef _TOOLS_TABLE_HXX +#include <tools/table.hxx> +#endif + +#include "misc.hxx" +#include "sprophelp.hxx" + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::linguistic2; + + +#define A2OU(x) ::rtl::OUString::createFromAscii( x ) + +/////////////////////////////////////////////////////////////////////////// + + +class SpellChecker : + public cppu::WeakImplHelper6 + < + XSpellChecker, + XLinguServiceEventBroadcaster, + XInitialization, + XComponent, + XServiceInfo, + XServiceDisplayName + > +{ + Sequence< Locale > aSuppLocales; + ::cppu::OInterfaceContainerHelper aEvtListeners; + Reference< XPropertyChangeListener > xPropHelper; + PropertyHelper_Spell * pPropHelper; + 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(); + } + + 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 A2OU( "com.sun.star.lingu.examples.SpellChecker" ); +} + + +/////////////////////////////////////////////////////////////////////////// + +#endif + |