20#include <com/sun/star/uno/Reference.h>
22#include <com/sun/star/linguistic2/SpellFailure.hpp>
23#include <com/sun/star/linguistic2/XLinguProperties.hpp>
27#include <com/sun/star/registry/XRegistryKey.hpp>
28#include <com/sun/star/lang/XSingleServiceFactory.hpp>
30#include <osl/mutex.hxx>
37#include <osl/file.hxx>
39#include <rtl/ustrbuf.hxx>
60 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]
init];
61 macTag = [NSSpellChecker uniqueSpellDocumentTag];
89 xPropHelper =
new PropertyHelper_Spell(
static_cast<XSpellChecker *
>(
this), xPropSet );
106 rtl_TextEncoding aEnc = RTL_TEXTENCODING_UTF8;
108 std::vector<NSString *> postspdict;
117 NSArray *aSpellCheckLanguages = [[NSSpellChecker sharedSpellChecker] availableLanguages];
119 NSArray *aSpellCheckLanguages = [UITextChecker availableLanguages];
122 for (NSUInteger
i = 0;
i < [aSpellCheckLanguages
count];
i++)
124 NSString* pLangStr =
static_cast<NSString*
>([aSpellCheckLanguages objectAtIndex:
i]);
128 if ([pLangStr isEqualToString:
@"ar"])
130 const std::vector<NSString*> aAR
131 {
@"AE",
@"BH",
@"DJ",
@"DZ",
@"EG",
@"ER",
@"IL",
@"IQ",
@"JO",
132 @"KM",
@"KW",
@"LB",
@"LY",
@"MA",
@"MR",
@"OM",
@"PS",
@"QA",
133 @"SA",
@"SD",
@"SO",
@"SY",
@"TD",
@"TN",
@"YE" };
136 pLangStr = [
@"ar_" stringByAppendingString: c];
137 postspdict.push_back( pLangStr );
140 else if ([pLangStr isEqualToString:
@"da"])
142 postspdict.push_back(
@"da_DK" );
144 else if ([pLangStr isEqualToString:
@"de"])
147 const std::vector<NSString*> aDE
148 {
@"AT",
@"BE",
@"DE",
@"LU" };
151 pLangStr = [
@"de_" stringByAppendingString: c];
152 postspdict.push_back( pLangStr );
159 else if ([pLangStr isEqualToString:
@"de_DE"])
161 const std::vector<NSString*> aDE
162 {
@"AT",
@"BE",
@"DE",
@"LU" };
165 pLangStr = [
@"de_" stringByAppendingString: c];
166 postspdict.push_back( pLangStr );
170 else if ([pLangStr isEqualToString:
@"en"])
173 const std::vector<NSString*> aEN
174 {
@"BW",
@"BZ",
@"GH",
@"GM",
@"IE",
@"JM",
@"MU",
@"MW",
@"MY",
@"NA",
175 @"NZ",
@"PH",
@"TT",
@"US",
@"ZA",
@"ZW" };
178 pLangStr = [
@"en_" stringByAppendingString: c];
179 postspdict.push_back( pLangStr );
182 else if ([pLangStr isEqualToString:
@"en_JP"]
183 || [pLangStr isEqualToString:
@"en_SG"])
187 else if ([pLangStr isEqualToString:
@"es"])
189 const std::vector<NSString*> aES
190 {
@"AR",
@"BO",
@"CL",
@"CO",
@"CR",
@"CU",
@"DO",
@"EC",
@"ES",
@"GT",
191 @"HN",
@"MX",
@"NI",
@"PA",
@"PE",
@"PR",
@"PY",
@"SV",
@"UY",
@"VE" };
194 pLangStr = [
@"es_" stringByAppendingString: c];
195 postspdict.push_back( pLangStr );
198 else if ([pLangStr isEqualToString:
@"fi"])
200 postspdict.push_back(
@"fi_FI" );
202 else if ([pLangStr isEqualToString:
@"fr"])
204 const std::vector<NSString*> aFR
205 {
@"BE",
@"BF",
@"BJ",
@"CA",
@"CH",
@"CI",
@"FR",
@"LU",
@"MC",
@"ML",
206 @"MU",
@"NE",
@"SN",
@"TG" };
209 pLangStr = [
@"fr_" stringByAppendingString: c];
210 postspdict.push_back( pLangStr );
214 else if ([pLangStr isEqualToString:
@"fr_FR"])
216 const std::vector<NSString*> aFR
217 {
@"BE",
@"BF",
@"BJ",
@"CA",
@"CH",
@"CI",
@"FR",
@"LU",
@"MC",
@"ML",
218 @"MU",
@"NE",
@"SN",
@"TG" };
221 pLangStr = [
@"fr_" stringByAppendingString: c];
222 postspdict.push_back( pLangStr );
226 else if ([pLangStr isEqualToString:
@"it"])
228 postspdict.push_back(
@"it_CH" );
229 postspdict.push_back(
@"it_IT" );
232 else if ([pLangStr isEqualToString:
@"it_IT"])
234 const std::vector<NSString*> aIT
238 pLangStr = [
@"it_" stringByAppendingString: c];
239 postspdict.push_back( pLangStr );
243 else if ([pLangStr isEqualToString:
@"ko"])
245 postspdict.push_back(
@"ko_KR" );
247 else if ([pLangStr isEqualToString:
@"nl"])
249 postspdict.push_back(
@"nl_BE" );
250 postspdict.push_back(
@"nl_NL" );
252 else if ([pLangStr isEqualToString:
@"nb"])
254 postspdict.push_back(
@"nb_NO" );
256 else if ([pLangStr isEqualToString:
@"pl"])
258 postspdict.push_back(
@"pl_PL" );
260 else if ([pLangStr isEqualToString:
@"ru"])
262 postspdict.push_back(
@"ru_RU" );
264 else if ([pLangStr isEqualToString:
@"sv"])
266 postspdict.push_back(
@"sv_FI" );
267 postspdict.push_back(
@"sv_SE" );
270 else if ([pLangStr isEqualToString:
@"sv_SE"])
272 postspdict.push_back(
@"sv_FI" );
273 postspdict.push_back(
@"sv_SE" );
276 else if ([pLangStr isEqualToString:
@"tr"])
278 postspdict.push_back(
@"tr_TR" );
281 postspdict.push_back( pLangStr );
284 postspdict.push_back(
@"pt_AO" );
286 numshr = postspdict.size();
309 for (
i = 0;
i < numshr;
i++) {
310 NSDictionary *aLocDict = [ NSLocale componentsFromLocaleIdentifier:postspdict[
i] ];
311 NSString* aLang = [ aLocDict objectForKey:NSLocaleLanguageCode ];
312 NSString* aCountry = [ aLocDict objectForKey:NSLocaleCountryCode ];
313 OUString lang([aLang cStringUsingEncoding: NSUTF8StringEncoding], [aLang
length], aEnc);
314 OUString country([ aCountry cStringUsingEncoding: NSUTF8StringEncoding], [aCountry
length], aEnc);
315 Locale nLoc( lang, country, OUString() );
318 for (j = 0; j < numlocs; j++) {
319 if (nLoc ==
pLocale[j]) newloc = 0;
356 for (sal_Int32
i = 0;
i < nLen; ++
i)
378 OUStringBuffer rBuf(rWord);
379 sal_Int32
n = rBuf.getLength();
381 for (sal_Int32 ix=0; ix <
n; ix++) {
383 if ((c == 0x201C) || (c == 0x201D)) rBuf[ix] =
u'"';
384 if ((c == 0x2018) || (c == 0x2019)) rBuf[ix] =
u'\'';
386 OUString nWord(rBuf.makeStringAndClear());
390 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]
init];
391 NSString* aNSStr = [[[NSString alloc] initWithCharacters:
reinterpret_cast<unichar
const *
>(nWord.getStr())
length: nWord.getLength()]autorelease];
392 NSString* aLang = [[[NSString alloc] initWithCharacters:
reinterpret_cast<unichar
const *
>(rLocale.Language.getStr())
length: rLocale.Language.getLength()]autorelease];
393 if(rLocale.Country.getLength()>0)
395 NSString* aCountry = [[[NSString alloc] initWithCharacters:
reinterpret_cast<unichar
const *
>(rLocale.Country.getStr())
length: rLocale.Country.getLength()]autorelease];
396 NSString* aTaggedCountry = [
@"_" stringByAppendingString:aCountry];
397 aLang = [aLang stringByAppendingString:aTaggedCountry];
402 NSRange range = [[NSSpellChecker sharedSpellChecker] checkSpellingOfString:aNSStr startingAt:0 language:aLang wrap:
false inSpellDocumentWithTag:macTag wordCount:&aCount];
404 NSRange range = [
pChecker rangeOfMisspelledWordInString:aNSStr range:NSMakeRange(0, [aNSStr
length]) startingAt:0 wrap:
NO language:aLang];
418 nRes = SpellFailure::SPELLING_ERROR;
430 const css::uno::Sequence<PropertyValue>& rProperties )
434 if (rLocale ==
Locale() || !rWord.getLength())
448 rHelper.SetTmpPropVals( rProperties );
455 if ( (!rHelper.IsSpellUpperCase() &&
IsUpper( rWord, nLang ))
456 || (!rHelper.IsSpellWithDigits() &&
HasDigits( rWord ))
457 || (!rHelper.IsSpellCapitalization()
458 && nFailure == SpellFailure::CAPTION_ERROR)
463 return (nFailure == -1);
481 OUStringBuffer rBuf(rWord);
482 sal_Int32
n = rBuf.getLength();
484 for (sal_Int32 ix=0; ix <
n; ix++) {
486 if ((c == 0x201C) || (c == 0x201D)) rBuf[ix] =
u'"';
487 if ((c == 0x2018) || (c == 0x2019)) rBuf[ix] =
u'\'';
489 OUString nWord(rBuf.makeStringAndClear());
493 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]
init];
494 NSString* aNSStr = [[[NSString alloc] initWithCharacters:
reinterpret_cast<unichar
const *
>(nWord.getStr())
length: nWord.getLength()]autorelease];
495 NSString* aLang = [[[NSString alloc] initWithCharacters:
reinterpret_cast<unichar
const *
>(rLocale.Language.getStr())
length: rLocale.Language.getLength()]autorelease];
496 if(rLocale.Country.getLength()>0)
498 NSString* aCountry = [[[NSString alloc] initWithCharacters:
reinterpret_cast<unichar
const *
>(rLocale.Country.getStr())
length: rLocale.Country.getLength()]autorelease];
499 NSString* aTaggedCountry = [
@"_" stringByAppendingString:aCountry];
500 aLang = [aLang stringByAppendingString:aTaggedCountry];
503 [[NSSpellChecker sharedSpellChecker] setLanguage:aLang];
504 NSArray *guesses = [[NSSpellChecker sharedSpellChecker] guessesForWordRange:NSMakeRange(0, [aNSStr
length]) inString:aNSStr language:aLang inSpellDocumentWithTag:0];
507 NSArray *guesses = [
pChecker guessesForWordRange:NSMakeRange(0, [aNSStr
length]) inString:aNSStr language:aLang];
513 OUString *pStr =
aStr.getArray();
514 for (
int ii=0; ii <
count; ii++)
517 NSString* guess = [guesses objectAtIndex:ii];
518 OUString cvtwrd(
reinterpret_cast<const sal_Unicode*
>([guess cStringUsingEncoding:NSUnicodeStringEncoding]),
static_cast<sal_Int32
>([guess
length]));
527 pAlt->SetWordLanguage( rWord, nLang );
528 pAlt->SetFailureType( SpellFailure::SPELLING_ERROR );
529 pAlt->SetAlternatives(
aStr );
537 const css::uno::Sequence<PropertyValue>& rProperties )
541 if (rLocale ==
Locale() || !rWord.getLength())
548 if (!
isValid( rWord, rLocale, rProperties ))
564 bRes =
GetPropHelper().addLinguServiceEventListener( rxLstnr );
580 bRes =
GetPropHelper().removeLinguServiceEventListener( rxLstnr );
590 return "macOS Spell Checker";
601 sal_Int32 nLen = rArguments.getLength();
605 rArguments.getConstArray()[0] >>= xPropSet;
612 xPropHelper =
new PropertyHelper_Spell(
static_cast<XSpellChecker *
>(
this), xPropSet );
616 OSL_FAIL(
"wrong number of arguments in sequence" );
630 EventObject aEvtObj(
static_cast<XSpellChecker *
>(
this) );
658 return "org.openoffice.lingu.MacOSXSpellChecker";
671extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
673 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any>
const&)
FILE * init(int, char **)
virtual Sequence< Locale > SAL_CALL getLocales() override
virtual void SAL_CALL dispose() override
virtual Reference< XSpellAlternatives > SAL_CALL spell(const OUString &rWord, const Locale &rLocale, const css::uno::Sequence< PropertyValue > &rProperties) override
virtual sal_Bool SAL_CALL removeLinguServiceEventListener(const Reference< XLinguServiceEventListener > &rxLstnr) override
virtual sal_Bool SAL_CALL addLinguServiceEventListener(const Reference< XLinguServiceEventListener > &rxLstnr) override
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override
linguistic::PropertyHelper_Spell & GetPropHelper_Impl()
virtual OUString SAL_CALL getImplementationName() override
virtual ~MacSpellChecker() override
virtual void SAL_CALL addEventListener(const Reference< XEventListener > &rxListener) override
virtual sal_Bool SAL_CALL hasLocale(const Locale &rLocale) override
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
rtl::Reference< linguistic::PropertyHelper_Spell > xPropHelper
virtual sal_Bool SAL_CALL isValid(const OUString &rWord, const Locale &rLocale, const css::uno::Sequence< PropertyValue > &rProperties) override
virtual void SAL_CALL removeEventListener(const Reference< XEventListener > &rxListener) override
Sequence< Locale > aSuppLocales
linguistic::PropertyHelper_Spell & GetPropHelper()
Reference< XSpellAlternatives > GetProposals(const OUString &rWord, const Locale &rLocale)
sal_Int16 GetSpellFailure(const OUString &rWord, const Locale &rLocale)
::comphelper::OInterfaceContainerHelper3< XEventListener > aEvtListeners
virtual void SAL_CALL initialize(const Sequence< Any > &rArguments) override
virtual OUString SAL_CALL getServiceDisplayName(const Locale &rLocale) override
rtl_TextEncoding * aDEncs
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
#define DBG_ASSERT(sCon, aError)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * lingucomponent_MacSpellChecker_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
constexpr OUStringLiteral SN_SPELLCHECKER
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
uno::Reference< XLinguProperties > GetLinguProperties()
osl::Mutex & GetLinguMutex()
bool IsUpper(const OUString &rText, sal_Int32 nPos, sal_Int32 nLen, LanguageType nLanguage)
bool HasDigits(const OUString &rText)
LanguageType LinguLocaleToLanguage(const css::lang::Locale &rLocale)