From b8fc450949f90981edf9e1dec82b0aaddd98426e Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 16 Dec 2011 11:29:53 +0100 Subject: lingucomponent: MacOSX: use gb_Library_add_objcxxobjects --- lingucomponent/Library_MacOSXSpell.mk | 6 +- .../source/spellcheck/macosxspell/macreg.cxx | 71 --- .../source/spellcheck/macosxspell/macreg.mm | 71 +++ .../source/spellcheck/macosxspell/macspellimp.cxx | 623 --------------------- .../source/spellcheck/macosxspell/macspellimp.mm | 623 +++++++++++++++++++++ 5 files changed, 695 insertions(+), 699 deletions(-) delete mode 100644 lingucomponent/source/spellcheck/macosxspell/macreg.cxx create mode 100644 lingucomponent/source/spellcheck/macosxspell/macreg.mm delete mode 100644 lingucomponent/source/spellcheck/macosxspell/macspellimp.cxx create mode 100644 lingucomponent/source/spellcheck/macosxspell/macspellimp.mm diff --git a/lingucomponent/Library_MacOSXSpell.mk b/lingucomponent/Library_MacOSXSpell.mk index ee35fda4b097..57c064089ae5 100644 --- a/lingucomponent/Library_MacOSXSpell.mk +++ b/lingucomponent/Library_MacOSXSpell.mk @@ -56,13 +56,9 @@ $(eval $(call gb_Library_use_externals,MacOSXSpell,\ hunspell \ )) -$(eval $(call gb_Library_add_exception_objects,MacOSXSpell,\ +$(eval $(call gb_Library_add_objcxxobjects,MacOSXSpell,\ lingucomponent/source/spellcheck/macosxspell/macreg \ lingucomponent/source/spellcheck/macosxspell/macspellimp \ )) -$(eval $(call gb_Library_add_cxxflags,MacOSXSpell,\ - $(gb_LinkTarget_OBJCXXFLAGS) \ -)) - # vim: set noet sw=4 ts=4: diff --git a/lingucomponent/source/spellcheck/macosxspell/macreg.cxx b/lingucomponent/source/spellcheck/macosxspell/macreg.cxx deleted file mode 100644 index 9020aceb8f61..000000000000 --- a/lingucomponent/source/spellcheck/macosxspell/macreg.cxx +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org 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 version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - - -#include // helper for factories -#include - -#include - -using namespace com::sun::star::lang; -using namespace com::sun::star::registry; - -//////////////////////////////////////// -// declaration of external RegEntry-functions defined by the service objects -// - -extern void * SAL_CALL MacSpellChecker_getFactory( - const sal_Char * pImplName, - XMultiServiceFactory * pServiceManager, - void * /*pRegistryKey*/ ); - -//////////////////////////////////////// -// definition of the two functions that are used to provide the services -// - -extern "C" -{ - -SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( - const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) -{ - void * pRet = NULL; - pRet = MacSpellChecker_getFactory( - pImplName, - reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), - pRegistryKey ); - - return pRet; -} - -} - -/////////////////////////////////////////////////////////////////////////// - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/lingucomponent/source/spellcheck/macosxspell/macreg.mm b/lingucomponent/source/spellcheck/macosxspell/macreg.mm new file mode 100644 index 000000000000..9020aceb8f61 --- /dev/null +++ b/lingucomponent/source/spellcheck/macosxspell/macreg.mm @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +#include // helper for factories +#include + +#include + +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; + +//////////////////////////////////////// +// declaration of external RegEntry-functions defined by the service objects +// + +extern void * SAL_CALL MacSpellChecker_getFactory( + const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, + void * /*pRegistryKey*/ ); + +//////////////////////////////////////// +// definition of the two functions that are used to provide the services +// + +extern "C" +{ + +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = NULL; + pRet = MacSpellChecker_getFactory( + pImplName, + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + pRegistryKey ); + + return pRet; +} + +} + +/////////////////////////////////////////////////////////////////////////// + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/lingucomponent/source/spellcheck/macosxspell/macspellimp.cxx b/lingucomponent/source/spellcheck/macosxspell/macspellimp.cxx deleted file mode 100644 index 5baf4d411cea..000000000000 --- a/lingucomponent/source/spellcheck/macosxspell/macspellimp.cxx +++ /dev/null @@ -1,623 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org 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 version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include -#include - -#include -#include // helper for factories -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -using namespace utl; -using namespace osl; -using namespace com::sun::star; -using namespace com::sun::star::beans; -using namespace com::sun::star::lang; -using namespace com::sun::star::uno; -using namespace com::sun::star::linguistic2; -using namespace linguistic; - -using ::rtl::OUString; -using ::rtl::OString; -using ::rtl::OUStringBuffer; -using ::rtl::OUStringToOString; - -/////////////////////////////////////////////////////////////////////////// - -MacSpellChecker::MacSpellChecker() : - aEvtListeners ( GetLinguMutex() ) -{ - aDEncs = NULL; - aDLocs = NULL; - aDNames = NULL; - bDisposing = sal_False; - pPropHelper = NULL; - numdict = 0; - NSApplicationLoad(); - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - macSpell = [NSSpellChecker sharedSpellChecker]; - macTag = [NSSpellChecker uniqueSpellDocumentTag]; - [pool release]; -} - - -MacSpellChecker::~MacSpellChecker() -{ - numdict = 0; - if (aDEncs) delete[] aDEncs; - aDEncs = NULL; - if (aDLocs) delete[] aDLocs; - aDLocs = NULL; - if (aDNames) delete[] aDNames; - aDNames = NULL; - if (pPropHelper) - pPropHelper->RemoveAsPropListener(); -} - - -PropertyHelper_Spell & MacSpellChecker::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 MacSpellChecker::getLocales() - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - // this routine should return the locales supported by the installed - // dictionaries. So here we need to parse both the user edited - // dictionary list and the shared dictionary list - // to see what dictionaries the admin/user has installed - - int numusr; // number of user dictionary entries - int numshr; // number of shared dictionary entries - dictentry * spdict; // shared dict entry pointer - dictentry * updict; // user dict entry pointer - SvtPathOptions aPathOpt; - rtl_TextEncoding aEnc = RTL_TEXTENCODING_UTF8; - - std::vector postspdict; - std::vector postupdict; - - - if (!numdict) { - - // invoke a dictionary manager to get the user dictionary list - // TODO How on Mac OS X? - - // invoke a second dictionary manager to get the shared dictionary list - NSArray *aLocales = [NSLocale availableLocaleIdentifiers]; - - //Test for existence of the dictionaries - for (unsigned int i = 0; i < [aLocales count]; i++) - { - if( [macSpell setLanguage:[aLocales objectAtIndex:i] ] ) - { - postspdict.push_back( [ aLocales objectAtIndex:i ] ); - } - } - - numusr = postupdict.size(); - numshr = postspdict.size(); - - // we really should merge these and remove duplicates but since - // users can name their dictionaries anything they want it would - // be impossible to know if a real duplication exists unless we - // add some unique key to each myspell dictionary - numdict = numshr + numusr; - - if (numdict) { - aDLocs = new Locale [numdict]; - aDEncs = new rtl_TextEncoding [numdict]; - aDNames = new OUString [numdict]; - aSuppLocales.realloc(numdict); - Locale * pLocale = aSuppLocales.getArray(); - int numlocs = 0; - int newloc; - int i,j; - int k = 0; - - //first add the user dictionaries - //TODO for MAC? - - // now add the shared dictionaries - for (i = 0; i < numshr; i++) { - NSDictionary *aLocDict = [ NSLocale componentsFromLocaleIdentifier:postspdict[i] ]; - NSString* aLang = [ aLocDict objectForKey:NSLocaleLanguageCode ]; - NSString* aCountry = [ aLocDict objectForKey:NSLocaleCountryCode ]; - OUString lang([aLang cStringUsingEncoding: NSUTF8StringEncoding], [aLang length], aEnc); - OUString country([ aCountry cStringUsingEncoding: NSUTF8StringEncoding], [aCountry length], aEnc); - Locale nLoc( lang, country, OUString() ); - newloc = 1; - //eliminate duplicates (is this needed for MacOS?) - for (j = 0; j < numlocs; j++) { - if (nLoc == pLocale[j]) newloc = 0; - } - if (newloc) { - pLocale[numlocs] = nLoc; - numlocs++; - } - aDLocs[k] = nLoc; - aDEncs[k] = 0; - k++; - } - - aSuppLocales.realloc(numlocs); - - } else { - /* no dictionary.lst found so register no dictionaries */ - numdict = 0; - aDEncs = NULL; - aDLocs = NULL; - aDNames = NULL; - aSuppLocales.realloc(0); - } - - /* de-allocation of memory is handled inside the DictMgr */ - updict = NULL; - spdict = NULL; - - } - - return aSuppLocales; -} - - - -sal_Bool SAL_CALL MacSpellChecker::hasLocale(const Locale& rLocale) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - sal_Bool bRes = sal_False; - if (!aSuppLocales.getLength()) - getLocales(); - - sal_Int32 nLen = aSuppLocales.getLength(); - for (sal_Int32 i = 0; i < nLen; ++i) - { - const Locale *pLocale = aSuppLocales.getConstArray(); - if (rLocale == pLocale[i]) - { - bRes = sal_True; - break; - } - } - return bRes; -} - - -sal_Int16 MacSpellChecker::GetSpellFailure( const OUString &rWord, const Locale &rLocale ) -{ - rtl_TextEncoding aEnc; - - // initialize a myspell object for each dictionary once - // (note: mutex is held higher up in isValid) - - - sal_Int16 nRes = -1; - - // first handle smart quotes both single and double - OUStringBuffer rBuf(rWord); - sal_Int32 n = rBuf.getLength(); - sal_Unicode c; - for (sal_Int32 ix=0; ix < n; ix++) { - c = rBuf[ix]; - if ((c == 0x201C) || (c == 0x201D)) rBuf[ix] = (sal_Unicode)0x0022; - if ((c == 0x2018) || (c == 0x2019)) rBuf[ix] = (sal_Unicode)0x0027; - } - OUString nWord(rBuf.makeStringAndClear()); - - if (n) - { - aEnc = 0; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSString* aNSStr = [[NSString alloc] initWithCharacters: nWord.getStr() length: nWord.getLength()]; - NSString* aLang = [[NSString alloc] initWithCharacters: rLocale.Language.getStr() length: rLocale.Language.getLength()]; - if(rLocale.Country.getLength()>0) - { - NSString* aCountry = [[NSString alloc] initWithCharacters: rLocale.Country.getStr() length: rLocale.Country.getLength()]; - NSString* aTag = @"_"; - NSString* aTaggedCountry = [aTag stringByAppendingString:aCountry]; - [aLang autorelease]; - aLang = [aLang stringByAppendingString:aTaggedCountry]; - } - - int aCount; - NSRange range = [macSpell checkSpellingOfString:aNSStr startingAt:0 language:aLang wrap:sal_False inSpellDocumentWithTag:macTag wordCount:&aCount]; - int rVal = 0; - if(range.length>0) - { - rVal = -1; - } - else - { - rVal = 1; - } - [pool release]; - if (rVal != 1) - { - nRes = SpellFailure::SPELLING_ERROR; - } else { - return -1; - } - } - return nRes; -} - - - -sal_Bool SAL_CALL - MacSpellChecker::isValid( const OUString& rWord, const Locale& rLocale, - const PropertyValues& rProperties ) - throw(IllegalArgumentException, RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - if (rLocale == Locale() || !rWord.getLength()) - return sal_True; - - if (!hasLocale( rLocale )) -#ifdef LINGU_EXCEPTIONS - throw( IllegalArgumentException() ); -#else - return sal_True; -#endif - - // Get property values to be used. - // These are be the default values set in the SN_LINGU_PROPERTIES - // PropertySet which are overridden by the supplied ones from the - // last argument. - // You'll probably like to use a simplier solution than the provided - // one using the PropertyHelper_Spell. - - PropertyHelper_Spell &rHelper = GetPropHelper(); - rHelper.SetTmpPropVals( rProperties ); - - sal_Int16 nFailure = GetSpellFailure( rWord, rLocale ); - if (nFailure != -1) - { - sal_Int16 nLang = 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 > - MacSpellChecker::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: - - Reference< XSpellAlternatives > xRes; - // note: mutex is held by higher up by spell which covers both - - sal_Int16 nLang = LocaleToLanguage( rLocale ); - int count; - Sequence< OUString > aStr( 0 ); - - // first handle smart quotes (single and double) - OUStringBuffer rBuf(rWord); - sal_Int32 n = rBuf.getLength(); - sal_Unicode c; - for (sal_Int32 ix=0; ix < n; ix++) { - c = rBuf[ix]; - if ((c == 0x201C) || (c == 0x201D)) rBuf[ix] = (sal_Unicode)0x0022; - if ((c == 0x2018) || (c == 0x2019)) rBuf[ix] = (sal_Unicode)0x0027; - } - OUString nWord(rBuf.makeStringAndClear()); - - if (n) - { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSString* aNSStr = [[NSString alloc] initWithCharacters: nWord.getStr() length: nWord.getLength()]; - NSString* aLang = [[NSString alloc] initWithCharacters: rLocale.Language.getStr() length: rLocale.Language.getLength() ]; - if(rLocale.Country.getLength()>0) - { - NSString* aCountry = [[NSString alloc] initWithCharacters: rLocale.Country.getStr() length: rLocale.Country.getLength() ]; - NSString* aTag = @"_"; - NSString* aTaggedCountry = [aTag stringByAppendingString:aCountry]; - [aLang autorelease]; - aLang = [aLang stringByAppendingString:aTaggedCountry]; - } - [macSpell setLanguage:aLang]; - NSArray *guesses = [macSpell guessesForWord:aNSStr]; - count = [guesses count]; - if (count) - { - aStr.realloc( count ); - OUString *pStr = aStr.getArray(); - for (int ii=0; ii < count; ii++) - { - // if needed add: if (suglst[ii] == NULL) continue; - NSString* guess = [guesses objectAtIndex:ii]; - OUString cvtwrd((const sal_Unicode*)[guess cStringUsingEncoding:NSUnicodeStringEncoding], (sal_Int32)[guess length]); - pStr[ii] = cvtwrd; - } - } - [pool release]; - } - - // now return an empty alternative for no suggestions or the list of alternatives if some found - SpellAlternatives *pAlt = new SpellAlternatives; - String aTmp(rWord); - pAlt->SetWordLanguage( aTmp, nLang ); - pAlt->SetFailureType( SpellFailure::SPELLING_ERROR ); - pAlt->SetAlternatives( aStr ); - xRes = pAlt; - return xRes; - -} - - - - -Reference< XSpellAlternatives > SAL_CALL - MacSpellChecker::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 MacSpellChecker_CreateInstance( - const Reference< XMultiServiceFactory > & /*rSMgr*/ ) - throw(Exception) -{ - - Reference< XInterface > xService = (cppu::OWeakObject*) new MacSpellChecker; - return xService; -} - - -sal_Bool SAL_CALL - MacSpellChecker::addLinguServiceEventListener( - const Reference< XLinguServiceEventListener >& rxLstnr ) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - sal_Bool bRes = sal_False; - if (!bDisposing && rxLstnr.is()) - { - bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr ); - } - return bRes; -} - - -sal_Bool SAL_CALL - MacSpellChecker::removeLinguServiceEventListener( - const Reference< XLinguServiceEventListener >& rxLstnr ) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - sal_Bool bRes = sal_False; - if (!bDisposing && rxLstnr.is()) - { - DBG_ASSERT( xPropHelper.is(), "xPropHelper non existent" ); - bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr ); - } - return bRes; -} - - -OUString SAL_CALL - MacSpellChecker::getServiceDisplayName( const Locale& /*rLocale*/ ) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - return A2OU( "Mac OS X Spell Checker" ); -} - - -void SAL_CALL - MacSpellChecker::initialize( const Sequence< Any >& rArguments ) - throw(Exception, RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - if (!pPropHelper) - { - sal_Int32 nLen = rArguments.getLength(); - if (2 == nLen) - { - Reference< XPropertySet > xPropSet; - rArguments.getConstArray()[0] >>= xPropSet; - //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 - OSL_FAIL( "wrong number of arguments in sequence" ); - - } -} - - -void SAL_CALL - MacSpellChecker::dispose() - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - if (!bDisposing) - { - bDisposing = sal_True; - EventObject aEvtObj( (XSpellChecker *) this ); - aEvtListeners.disposeAndClear( aEvtObj ); - } -} - - -void SAL_CALL - MacSpellChecker::addEventListener( const Reference< XEventListener >& rxListener ) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - if (!bDisposing && rxListener.is()) - aEvtListeners.addInterface( rxListener ); -} - - -void SAL_CALL - MacSpellChecker::removeEventListener( const Reference< XEventListener >& rxListener ) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - if (!bDisposing && rxListener.is()) - aEvtListeners.removeInterface( rxListener ); -} - - -/////////////////////////////////////////////////////////////////////////// -// Service specific part -// - -OUString SAL_CALL MacSpellChecker::getImplementationName() - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - return getImplementationName_Static(); -} - - -sal_Bool SAL_CALL MacSpellChecker::supportsService( const OUString& ServiceName ) - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - Sequence< OUString > aSNL = getSupportedServiceNames(); - const OUString * pArray = aSNL.getConstArray(); - for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) - if( pArray[i] == ServiceName ) - return sal_True; - return sal_False; -} - - -Sequence< OUString > SAL_CALL MacSpellChecker::getSupportedServiceNames() - throw(RuntimeException) -{ - MutexGuard aGuard( GetLinguMutex() ); - - return getSupportedServiceNames_Static(); -} - - -Sequence< OUString > MacSpellChecker::getSupportedServiceNames_Static() - throw() -{ - MutexGuard aGuard( GetLinguMutex() ); - - Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich - aSNS.getArray()[0] = A2OU( SN_SPELLCHECKER ); - return aSNS; -} - -void * SAL_CALL MacSpellChecker_getFactory( const sal_Char * pImplName, - XMultiServiceFactory * pServiceManager, void * ) -{ - void * pRet = 0; - if ( !MacSpellChecker::getImplementationName_Static().compareToAscii( pImplName ) ) - { - Reference< XSingleServiceFactory > xFactory = - cppu::createOneInstanceFactory( - pServiceManager, - MacSpellChecker::getImplementationName_Static(), - MacSpellChecker_CreateInstance, - MacSpellChecker::getSupportedServiceNames_Static()); - // acquire, because we return an interface pointer instead of a reference - xFactory->acquire(); - pRet = xFactory.get(); - } - return pRet; -} - - -/////////////////////////////////////////////////////////////////////////// - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/lingucomponent/source/spellcheck/macosxspell/macspellimp.mm b/lingucomponent/source/spellcheck/macosxspell/macspellimp.mm new file mode 100644 index 000000000000..5baf4d411cea --- /dev/null +++ b/lingucomponent/source/spellcheck/macosxspell/macspellimp.mm @@ -0,0 +1,623 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include +#include + +#include +#include // helper for factories +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +using namespace utl; +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::linguistic2; +using namespace linguistic; + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OUStringBuffer; +using ::rtl::OUStringToOString; + +/////////////////////////////////////////////////////////////////////////// + +MacSpellChecker::MacSpellChecker() : + aEvtListeners ( GetLinguMutex() ) +{ + aDEncs = NULL; + aDLocs = NULL; + aDNames = NULL; + bDisposing = sal_False; + pPropHelper = NULL; + numdict = 0; + NSApplicationLoad(); + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + macSpell = [NSSpellChecker sharedSpellChecker]; + macTag = [NSSpellChecker uniqueSpellDocumentTag]; + [pool release]; +} + + +MacSpellChecker::~MacSpellChecker() +{ + numdict = 0; + if (aDEncs) delete[] aDEncs; + aDEncs = NULL; + if (aDLocs) delete[] aDLocs; + aDLocs = NULL; + if (aDNames) delete[] aDNames; + aDNames = NULL; + if (pPropHelper) + pPropHelper->RemoveAsPropListener(); +} + + +PropertyHelper_Spell & MacSpellChecker::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 MacSpellChecker::getLocales() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + // this routine should return the locales supported by the installed + // dictionaries. So here we need to parse both the user edited + // dictionary list and the shared dictionary list + // to see what dictionaries the admin/user has installed + + int numusr; // number of user dictionary entries + int numshr; // number of shared dictionary entries + dictentry * spdict; // shared dict entry pointer + dictentry * updict; // user dict entry pointer + SvtPathOptions aPathOpt; + rtl_TextEncoding aEnc = RTL_TEXTENCODING_UTF8; + + std::vector postspdict; + std::vector postupdict; + + + if (!numdict) { + + // invoke a dictionary manager to get the user dictionary list + // TODO How on Mac OS X? + + // invoke a second dictionary manager to get the shared dictionary list + NSArray *aLocales = [NSLocale availableLocaleIdentifiers]; + + //Test for existence of the dictionaries + for (unsigned int i = 0; i < [aLocales count]; i++) + { + if( [macSpell setLanguage:[aLocales objectAtIndex:i] ] ) + { + postspdict.push_back( [ aLocales objectAtIndex:i ] ); + } + } + + numusr = postupdict.size(); + numshr = postspdict.size(); + + // we really should merge these and remove duplicates but since + // users can name their dictionaries anything they want it would + // be impossible to know if a real duplication exists unless we + // add some unique key to each myspell dictionary + numdict = numshr + numusr; + + if (numdict) { + aDLocs = new Locale [numdict]; + aDEncs = new rtl_TextEncoding [numdict]; + aDNames = new OUString [numdict]; + aSuppLocales.realloc(numdict); + Locale * pLocale = aSuppLocales.getArray(); + int numlocs = 0; + int newloc; + int i,j; + int k = 0; + + //first add the user dictionaries + //TODO for MAC? + + // now add the shared dictionaries + for (i = 0; i < numshr; i++) { + NSDictionary *aLocDict = [ NSLocale componentsFromLocaleIdentifier:postspdict[i] ]; + NSString* aLang = [ aLocDict objectForKey:NSLocaleLanguageCode ]; + NSString* aCountry = [ aLocDict objectForKey:NSLocaleCountryCode ]; + OUString lang([aLang cStringUsingEncoding: NSUTF8StringEncoding], [aLang length], aEnc); + OUString country([ aCountry cStringUsingEncoding: NSUTF8StringEncoding], [aCountry length], aEnc); + Locale nLoc( lang, country, OUString() ); + newloc = 1; + //eliminate duplicates (is this needed for MacOS?) + for (j = 0; j < numlocs; j++) { + if (nLoc == pLocale[j]) newloc = 0; + } + if (newloc) { + pLocale[numlocs] = nLoc; + numlocs++; + } + aDLocs[k] = nLoc; + aDEncs[k] = 0; + k++; + } + + aSuppLocales.realloc(numlocs); + + } else { + /* no dictionary.lst found so register no dictionaries */ + numdict = 0; + aDEncs = NULL; + aDLocs = NULL; + aDNames = NULL; + aSuppLocales.realloc(0); + } + + /* de-allocation of memory is handled inside the DictMgr */ + updict = NULL; + spdict = NULL; + + } + + return aSuppLocales; +} + + + +sal_Bool SAL_CALL MacSpellChecker::hasLocale(const Locale& rLocale) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (!aSuppLocales.getLength()) + getLocales(); + + sal_Int32 nLen = aSuppLocales.getLength(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + const Locale *pLocale = aSuppLocales.getConstArray(); + if (rLocale == pLocale[i]) + { + bRes = sal_True; + break; + } + } + return bRes; +} + + +sal_Int16 MacSpellChecker::GetSpellFailure( const OUString &rWord, const Locale &rLocale ) +{ + rtl_TextEncoding aEnc; + + // initialize a myspell object for each dictionary once + // (note: mutex is held higher up in isValid) + + + sal_Int16 nRes = -1; + + // first handle smart quotes both single and double + OUStringBuffer rBuf(rWord); + sal_Int32 n = rBuf.getLength(); + sal_Unicode c; + for (sal_Int32 ix=0; ix < n; ix++) { + c = rBuf[ix]; + if ((c == 0x201C) || (c == 0x201D)) rBuf[ix] = (sal_Unicode)0x0022; + if ((c == 0x2018) || (c == 0x2019)) rBuf[ix] = (sal_Unicode)0x0027; + } + OUString nWord(rBuf.makeStringAndClear()); + + if (n) + { + aEnc = 0; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* aNSStr = [[NSString alloc] initWithCharacters: nWord.getStr() length: nWord.getLength()]; + NSString* aLang = [[NSString alloc] initWithCharacters: rLocale.Language.getStr() length: rLocale.Language.getLength()]; + if(rLocale.Country.getLength()>0) + { + NSString* aCountry = [[NSString alloc] initWithCharacters: rLocale.Country.getStr() length: rLocale.Country.getLength()]; + NSString* aTag = @"_"; + NSString* aTaggedCountry = [aTag stringByAppendingString:aCountry]; + [aLang autorelease]; + aLang = [aLang stringByAppendingString:aTaggedCountry]; + } + + int aCount; + NSRange range = [macSpell checkSpellingOfString:aNSStr startingAt:0 language:aLang wrap:sal_False inSpellDocumentWithTag:macTag wordCount:&aCount]; + int rVal = 0; + if(range.length>0) + { + rVal = -1; + } + else + { + rVal = 1; + } + [pool release]; + if (rVal != 1) + { + nRes = SpellFailure::SPELLING_ERROR; + } else { + return -1; + } + } + return nRes; +} + + + +sal_Bool SAL_CALL + MacSpellChecker::isValid( const OUString& rWord, const Locale& rLocale, + const PropertyValues& rProperties ) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (rLocale == Locale() || !rWord.getLength()) + return sal_True; + + if (!hasLocale( rLocale )) +#ifdef LINGU_EXCEPTIONS + throw( IllegalArgumentException() ); +#else + return sal_True; +#endif + + // Get property values to be used. + // These are be the default values set in the SN_LINGU_PROPERTIES + // PropertySet which are overridden by the supplied ones from the + // last argument. + // You'll probably like to use a simplier solution than the provided + // one using the PropertyHelper_Spell. + + PropertyHelper_Spell &rHelper = GetPropHelper(); + rHelper.SetTmpPropVals( rProperties ); + + sal_Int16 nFailure = GetSpellFailure( rWord, rLocale ); + if (nFailure != -1) + { + sal_Int16 nLang = 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 > + MacSpellChecker::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: + + Reference< XSpellAlternatives > xRes; + // note: mutex is held by higher up by spell which covers both + + sal_Int16 nLang = LocaleToLanguage( rLocale ); + int count; + Sequence< OUString > aStr( 0 ); + + // first handle smart quotes (single and double) + OUStringBuffer rBuf(rWord); + sal_Int32 n = rBuf.getLength(); + sal_Unicode c; + for (sal_Int32 ix=0; ix < n; ix++) { + c = rBuf[ix]; + if ((c == 0x201C) || (c == 0x201D)) rBuf[ix] = (sal_Unicode)0x0022; + if ((c == 0x2018) || (c == 0x2019)) rBuf[ix] = (sal_Unicode)0x0027; + } + OUString nWord(rBuf.makeStringAndClear()); + + if (n) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* aNSStr = [[NSString alloc] initWithCharacters: nWord.getStr() length: nWord.getLength()]; + NSString* aLang = [[NSString alloc] initWithCharacters: rLocale.Language.getStr() length: rLocale.Language.getLength() ]; + if(rLocale.Country.getLength()>0) + { + NSString* aCountry = [[NSString alloc] initWithCharacters: rLocale.Country.getStr() length: rLocale.Country.getLength() ]; + NSString* aTag = @"_"; + NSString* aTaggedCountry = [aTag stringByAppendingString:aCountry]; + [aLang autorelease]; + aLang = [aLang stringByAppendingString:aTaggedCountry]; + } + [macSpell setLanguage:aLang]; + NSArray *guesses = [macSpell guessesForWord:aNSStr]; + count = [guesses count]; + if (count) + { + aStr.realloc( count ); + OUString *pStr = aStr.getArray(); + for (int ii=0; ii < count; ii++) + { + // if needed add: if (suglst[ii] == NULL) continue; + NSString* guess = [guesses objectAtIndex:ii]; + OUString cvtwrd((const sal_Unicode*)[guess cStringUsingEncoding:NSUnicodeStringEncoding], (sal_Int32)[guess length]); + pStr[ii] = cvtwrd; + } + } + [pool release]; + } + + // now return an empty alternative for no suggestions or the list of alternatives if some found + SpellAlternatives *pAlt = new SpellAlternatives; + String aTmp(rWord); + pAlt->SetWordLanguage( aTmp, nLang ); + pAlt->SetFailureType( SpellFailure::SPELLING_ERROR ); + pAlt->SetAlternatives( aStr ); + xRes = pAlt; + return xRes; + +} + + + + +Reference< XSpellAlternatives > SAL_CALL + MacSpellChecker::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 MacSpellChecker_CreateInstance( + const Reference< XMultiServiceFactory > & /*rSMgr*/ ) + throw(Exception) +{ + + Reference< XInterface > xService = (cppu::OWeakObject*) new MacSpellChecker; + return xService; +} + + +sal_Bool SAL_CALL + MacSpellChecker::addLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxLstnr ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (!bDisposing && rxLstnr.is()) + { + bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr ); + } + return bRes; +} + + +sal_Bool SAL_CALL + MacSpellChecker::removeLinguServiceEventListener( + const Reference< XLinguServiceEventListener >& rxLstnr ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Bool bRes = sal_False; + if (!bDisposing && rxLstnr.is()) + { + DBG_ASSERT( xPropHelper.is(), "xPropHelper non existent" ); + bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr ); + } + return bRes; +} + + +OUString SAL_CALL + MacSpellChecker::getServiceDisplayName( const Locale& /*rLocale*/ ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return A2OU( "Mac OS X Spell Checker" ); +} + + +void SAL_CALL + MacSpellChecker::initialize( const Sequence< Any >& rArguments ) + throw(Exception, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!pPropHelper) + { + sal_Int32 nLen = rArguments.getLength(); + if (2 == nLen) + { + Reference< XPropertySet > xPropSet; + rArguments.getConstArray()[0] >>= xPropSet; + //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 + OSL_FAIL( "wrong number of arguments in sequence" ); + + } +} + + +void SAL_CALL + MacSpellChecker::dispose() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing) + { + bDisposing = sal_True; + EventObject aEvtObj( (XSpellChecker *) this ); + aEvtListeners.disposeAndClear( aEvtObj ); + } +} + + +void SAL_CALL + MacSpellChecker::addEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.addInterface( rxListener ); +} + + +void SAL_CALL + MacSpellChecker::removeEventListener( const Reference< XEventListener >& rxListener ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (!bDisposing && rxListener.is()) + aEvtListeners.removeInterface( rxListener ); +} + + +/////////////////////////////////////////////////////////////////////////// +// Service specific part +// + +OUString SAL_CALL MacSpellChecker::getImplementationName() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + return getImplementationName_Static(); +} + + +sal_Bool SAL_CALL MacSpellChecker::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + + +Sequence< OUString > SAL_CALL MacSpellChecker::getSupportedServiceNames() + throw(RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + return getSupportedServiceNames_Static(); +} + + +Sequence< OUString > MacSpellChecker::getSupportedServiceNames_Static() + throw() +{ + MutexGuard aGuard( GetLinguMutex() ); + + Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich + aSNS.getArray()[0] = A2OU( SN_SPELLCHECKER ); + return aSNS; +} + +void * SAL_CALL MacSpellChecker_getFactory( const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, void * ) +{ + void * pRet = 0; + if ( !MacSpellChecker::getImplementationName_Static().compareToAscii( pImplName ) ) + { + Reference< XSingleServiceFactory > xFactory = + cppu::createOneInstanceFactory( + pServiceManager, + MacSpellChecker::getImplementationName_Static(), + MacSpellChecker_CreateInstance, + MacSpellChecker::getSupportedServiceNames_Static()); + // acquire, because we return an interface pointer instead of a reference + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + + +/////////////////////////////////////////////////////////////////////////// + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.1