1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
25 #include <com/sun/star/uno/Reference.h>
26 #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
28 #include <cppuhelper/factory.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <com/sun/star/registry/XRegistryKey.hpp>
31 #include <i18nlangtag/languagetag.hxx>
32 #include <tools/debug.hxx>
33 #include <osl/mutex.hxx>
36 #include <hyphenimp.hxx>
38 #include <linguistic/hyphdta.hxx>
39 #include <rtl/ustring.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <rtl/textenc.h>
43 #include <linguistic/lngprops.hxx>
44 #include <linguistic/misc.hxx>
45 #include <unotools/pathoptions.hxx>
46 #include <unotools/useroptions.hxx>
47 #include <unotools/lingucfg.hxx>
48 #include <osl/file.hxx>
55 #include <boost/scoped_array.hpp>
59 using namespace com::sun::star
;
60 using namespace com::sun::star::beans
;
61 using namespace com::sun::star::lang
;
62 using namespace com::sun::star::uno
;
63 using namespace com::sun::star::linguistic2
;
64 using namespace linguistic
;
67 #define Max(a,b) (a > b ? a : b)
69 Hyphenator::Hyphenator() :
70 aEvtListeners ( GetLinguMutex() )
78 Hyphenator::~Hyphenator()
80 if (numdict
&& aDicts
)
82 for (int i
=0; i
< numdict
; ++i
)
84 delete aDicts
[i
].apCC
;
86 hnj_hyphen_free(aDicts
[i
].aPtr
);
93 pPropHelper
->RemoveAsPropListener();
98 PropertyHelper_Hyphenation
& Hyphenator::GetPropHelper_Impl()
102 Reference
< XLinguProperties
> xPropSet( GetLinguProperties(), UNO_QUERY
);
104 pPropHelper
= new PropertyHelper_Hyphenation ((XHyphenator
*) this, xPropSet
);
105 pPropHelper
->AddAsPropListener(); //! after a reference is established
110 Sequence
< Locale
> SAL_CALL
Hyphenator::getLocales()
111 throw(RuntimeException
, std::exception
)
113 MutexGuard
aGuard( GetLinguMutex() );
115 // this routine should return the locales supported by the installed
119 SvtLinguConfig aLinguCfg
;
121 // get list of dictionaries-to-use
122 // (or better speaking: the list of dictionaries using the
123 // new configuration entries).
124 std::list
< SvtLinguConfigDictionaryEntry
> aDics
;
125 uno::Sequence
< OUString
> aFormatList
;
126 aLinguCfg
.GetSupportedDictionaryFormatsFor( "Hyphenators",
127 "org.openoffice.lingu.LibHnjHyphenator", aFormatList
);
128 sal_Int32 nLen
= aFormatList
.getLength();
129 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
131 std::vector
< SvtLinguConfigDictionaryEntry
> aTmpDic(
132 aLinguCfg
.GetActiveDictionariesByFormat( aFormatList
[i
] ) );
133 aDics
.insert( aDics
.end(), aTmpDic
.begin(), aTmpDic
.end() );
136 //!! for compatibility with old dictionaries (the ones not using extensions
137 //!! or new configuration entries, but still using the dictionary.lst file)
138 //!! Get the list of old style spell checking dictionaries to use...
139 std::vector
< SvtLinguConfigDictionaryEntry
> aOldStyleDics(
140 GetOldStyleDics( "HYPH" ) );
142 // to prefer dictionaries with configuration entries we will only
143 // use those old style dictionaries that add a language that
144 // is not yet supported by the list od new style dictionaries
145 MergeNewStyleDicsAndOldStyleDics( aDics
, aOldStyleDics
);
147 numdict
= aDics
.size();
150 // get supported locales from the dictionaries-to-use...
152 std::set
< OUString
, lt_rtl_OUString
> aLocaleNamesSet
;
153 std::list
< SvtLinguConfigDictionaryEntry
>::const_iterator aDictIt
;
154 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
156 uno::Sequence
< OUString
> aLocaleNames( aDictIt
->aLocaleNames
);
157 sal_Int32 nLen2
= aLocaleNames
.getLength();
158 for (k
= 0; k
< nLen2
; ++k
)
160 aLocaleNamesSet
.insert( aLocaleNames
[k
] );
163 // ... and add them to the resulting sequence
164 aSuppLocales
.realloc( aLocaleNamesSet
.size() );
165 std::set
< OUString
, lt_rtl_OUString
>::const_iterator aItB
;
167 for (aItB
= aLocaleNamesSet
.begin(); aItB
!= aLocaleNamesSet
.end(); ++aItB
)
169 Locale
aTmp( LanguageTag::convertToLocale( *aItB
));
170 aSuppLocales
[k
++] = aTmp
;
173 //! For each dictionary and each locale we need a separate entry.
174 //! If this results in more than one dictionary per locale than (for now)
175 //! it is undefined which dictionary gets used.
176 //! In the future the implementation should support using several dictionaries
179 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
180 numdict
= numdict
+ aDictIt
->aLocaleNames
.getLength();
182 // add dictionary information
183 aDicts
= new HDInfo
[numdict
];
186 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
188 if (aDictIt
->aLocaleNames
.getLength() > 0 &&
189 aDictIt
->aLocations
.getLength() > 0)
191 uno::Sequence
< OUString
> aLocaleNames( aDictIt
->aLocaleNames
);
192 sal_Int32 nLocales
= aLocaleNames
.getLength();
194 // currently only one language per dictionary is supported in the actual implementation...
195 // Thus here we work-around this by adding the same dictionary several times.
196 // Once for each of it's supported locales.
197 for (sal_Int32 i
= 0; i
< nLocales
; ++i
)
199 LanguageTag
aLanguageTag( aDictIt
->aLocaleNames
[i
] );
200 aDicts
[k
].aPtr
= NULL
;
201 aDicts
[k
].eEnc
= RTL_TEXTENCODING_DONTKNOW
;
202 aDicts
[k
].aLoc
= aLanguageTag
.getLocale();
203 aDicts
[k
].apCC
= new CharClass( aLanguageTag
);
204 // also both files have to be in the same directory and the
205 // file names must only differ in the extension (.aff/.dic).
206 // Thus we use the first location only and strip the extension part.
207 OUString aLocation
= aDictIt
->aLocations
[0];
208 sal_Int32 nPos
= aLocation
.lastIndexOf( '.' );
209 aLocation
= aLocation
.copy( 0, nPos
);
210 aDicts
[k
].aName
= aLocation
;
216 DBG_ASSERT( k
== numdict
, "index mismatch?" );
220 // no dictionary found so register no dictionaries
223 aSuppLocales
.realloc(0);
230 sal_Bool SAL_CALL
Hyphenator::hasLocale(const Locale
& rLocale
)
231 throw(RuntimeException
, std::exception
)
233 MutexGuard
aGuard( GetLinguMutex() );
236 if (!aSuppLocales
.getLength())
239 const Locale
*pLocale
= aSuppLocales
.getConstArray();
240 sal_Int32 nLen
= aSuppLocales
.getLength();
241 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
243 if (rLocale
== pLocale
[i
])
252 Reference
< XHyphenatedWord
> SAL_CALL
Hyphenator::hyphenate( const OUString
& aWord
,
253 const ::com::sun::star::lang::Locale
& aLocale
,
254 sal_Int16 nMaxLeading
,
255 const ::com::sun::star::beans::PropertyValues
& aProperties
)
256 throw (com::sun::star::uno::RuntimeException
, com::sun::star::lang::IllegalArgumentException
, std::exception
)
260 PropertyHelper_Hyphenation
& rHelper
= GetPropHelper();
261 rHelper
.SetTmpPropVals(aProperties
);
262 sal_Int16 minTrail
= rHelper
.GetMinTrailing();
263 sal_Int16 minLead
= rHelper
.GetMinLeading();
264 sal_Int16 minLen
= rHelper
.GetMinWordLength();
266 HyphenDict
*dict
= NULL
;
267 rtl_TextEncoding eEnc
= RTL_TEXTENCODING_DONTKNOW
;
269 Reference
< XHyphenatedWord
> xRes
;
272 for (int j
= 0; j
< numdict
; j
++)
274 if (aLocale
== aDicts
[j
].aLoc
)
278 // if we have a hyphenation dictionary matching this locale
281 int nHyphenationPos
= -1;
282 int nHyphenationPosAlt
= -1;
283 int nHyphenationPosAltHyph
= -1;
285 // if this dictinary has not been loaded yet do that
288 OUString DictFN
= aDicts
[k
].aName
+ ".dic";
291 osl::FileBase::getSystemPathFromFileURL( DictFN
, dictpath
);
294 // Hyphen waits UTF-8 encoded paths with \\?\ long path prefix.
295 OString sTmp
= Win_AddLongPathPrefix(OUStringToOString(dictpath
, RTL_TEXTENCODING_UTF8
));
297 OString
sTmp( OU2ENC( dictpath
, osl_getThreadTextEncoding() ) );
300 if ( ( dict
= hnj_hyphen_load ( sTmp
.getStr()) ) == NULL
)
302 fprintf(stderr
, "Couldn't find file %s\n", OU2ENC(dictpath
, osl_getThreadTextEncoding()) );
305 aDicts
[k
].aPtr
= dict
;
306 aDicts
[k
].eEnc
= getTextEncodingFromCharset(dict
->cset
);
309 // other wise hyphenate the word with that dictionary
310 dict
= aDicts
[k
].aPtr
;
311 eEnc
= aDicts
[k
].eEnc
;
312 CharClass
* pCC
= aDicts
[k
].apCC
;
314 // we don't want to work with a default text encoding since following incorrect
315 // results may occur only for specific text and thus may be hard to notice.
316 // Thus better always make a clean exit here if the text encoding is in question.
317 // Hopefully something not working at all will raise proper attention quickly. ;-)
318 DBG_ASSERT( eEnc
!= RTL_TEXTENCODING_DONTKNOW
, "failed to get text encoding! (maybe incorrect encoding string in file)" );
319 if (eEnc
== RTL_TEXTENCODING_DONTKNOW
)
322 CapType ct
= capitalType(aWord
, pCC
);
324 // first convert any smart quotes or apostrophes to normal ones
325 OUStringBuffer
rBuf(aWord
);
326 sal_Int32 nc
= rBuf
.getLength();
328 for (sal_Int32 ix
=0; ix
< nc
; ix
++)
331 if ((ch
== 0x201C) || (ch
== 0x201D))
332 rBuf
[ix
] = (sal_Unicode
)0x0022;
333 if ((ch
== 0x2018) || (ch
== 0x2019))
334 rBuf
[ix
] = (sal_Unicode
)0x0027;
336 OUString
nWord(rBuf
.makeStringAndClear());
338 // now convert word to all lowercase for pattern recognition
339 OUString
nTerm(makeLowerCase(nWord
, pCC
));
341 // now convert word to needed encoding
342 OString
encWord(OU2ENC(nTerm
,eEnc
));
344 int wordlen
= encWord
.getLength();
345 boost::scoped_array
<char> lcword(new char[wordlen
+ 1]);
346 boost::scoped_array
<char> hyphens(new char[wordlen
+ 5]);
348 char ** rep
= NULL
; // replacements of discretionary hyphenation
349 int * pos
= NULL
; // array of [hyphenation point] minus [deletion position]
350 int * cut
= NULL
; // length of deletions in original word
352 // copy converted word into simple char buffer
353 strcpy(lcword
.get(),encWord
.getStr());
355 // now strip off any ending periods
357 while((n
>=0) && (lcword
[n
] == '.'))
362 const bool bFailed
= 0 != hnj_hyphen_hyphenate3( dict
, lcword
.get(), n
, hyphens
.get(), NULL
,
363 &rep
, &pos
, &cut
, minLead
, minTrail
,
364 Max(dict
->clhmin
, Max(dict
->clhmin
, 2) + Max(0, minLead
- Max(dict
->lhmin
, 2))),
365 Max(dict
->crhmin
, Max(dict
->crhmin
, 2) + Max(0, minTrail
- Max(dict
->rhmin
, 2))) );
368 // whoops something did not work
371 for(int j
= 0; j
< n
; j
++)
373 if (rep
[j
]) free(rep
[j
]);
383 // now backfill hyphens[] for any removed trailing periods
384 for (int c
= n
; c
< wordlen
; c
++) hyphens
[c
] = '0';
385 hyphens
[wordlen
] = '\0';
387 sal_Int32 Leading
= GetPosInWordToCheck( aWord
, nMaxLeading
);
389 for (sal_Int32 i
= 0; i
< n
; i
++)
392 bool hit
= (n
>= minLen
);
393 if (!rep
|| !rep
[i
] || (i
>= n
))
395 hit
= hit
&& (hyphens
[i
]&1) && (i
< Leading
);
396 hit
= hit
&& (i
>= (minLead
-1) );
397 hit
= hit
&& ((n
- i
- 1) >= minTrail
);
401 // calculate change character length before hyphenation point signed with '='
402 for (char * c
= rep
[i
]; *c
&& (*c
!= '='); c
++)
404 if (eEnc
== RTL_TEXTENCODING_UTF8
)
406 if (((unsigned char) *c
) >> 6 != 2)
412 hit
= hit
&& (hyphens
[i
]&1) && ((i
+ leftrep
- pos
[i
]) < Leading
);
413 hit
= hit
&& ((i
+ leftrep
- pos
[i
]) >= (minLead
-1) );
414 hit
= hit
&& ((n
- i
- 1 + sal::static_int_cast
< sal_sSize
>(strlen(rep
[i
])) - leftrep
- 1) >= minTrail
);
419 if (rep
&& (i
< n
) && rep
[i
])
421 nHyphenationPosAlt
= i
- pos
[i
];
422 nHyphenationPosAltHyph
= i
+ leftrep
- pos
[i
];
427 if (nHyphenationPos
== -1)
433 if (rep
&& rep
[nHyphenationPos
])
436 char * s
= rep
[nHyphenationPos
];
440 if (*s
== '=') eq
= 1;
441 if (eq
) *s
= *(s
+ 1);
443 OUString
repHyphlow(rep
[nHyphenationPos
], strlen(rep
[nHyphenationPos
]), eEnc
);
447 case CapType::ALLCAP
:
449 repHyph
= makeUpperCase(repHyphlow
, pCC
);
452 case CapType::INITCAP
:
454 if (nHyphenationPosAlt
== -1)
455 repHyph
= makeInitCap(repHyphlow
, pCC
);
457 repHyph
= repHyphlow
;
462 repHyph
= repHyphlow
;
468 sal_Int16 nPos
= (sal_Int16
) ((nHyphenationPosAltHyph
< nHyphenationPos
) ?
469 nHyphenationPosAltHyph
: nHyphenationPos
);
470 // dicretionary hyphenation
471 xRes
= HyphenatedWord::CreateHyphenatedWord( aWord
, LinguLocaleToLanguage( aLocale
), nPos
,
472 aWord
.replaceAt(nHyphenationPosAlt
+ 1, cut
[nHyphenationPos
], repHyph
),
473 (sal_Int16
) nHyphenationPosAltHyph
);
477 xRes
= HyphenatedWord::CreateHyphenatedWord( aWord
, LinguLocaleToLanguage( aLocale
),
478 (sal_Int16
)nHyphenationPos
, aWord
, (sal_Int16
) nHyphenationPos
);
484 for(int j
= 0; j
< n
; j
++)
486 if (rep
[j
]) free(rep
[j
]);
497 Reference
< XHyphenatedWord
> SAL_CALL
Hyphenator::queryAlternativeSpelling(
498 const OUString
& aWord
,
499 const ::com::sun::star::lang::Locale
& aLocale
,
501 const ::com::sun::star::beans::PropertyValues
& aProperties
)
502 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
504 // Firstly we allow only one plus character before the hyphen to avoid to miss the right break point:
505 for (int extrachar
= 1; extrachar
<= 2; extrachar
++)
507 Reference
< XHyphenatedWord
> xRes
= hyphenate(aWord
, aLocale
, nIndex
+ 1 + extrachar
, aProperties
);
508 if (xRes
.is() && xRes
->isAlternativeSpelling() && xRes
->getHyphenationPos() == nIndex
)
515 static OString
Win_GetShortPathName( const OUString
&rLongPathName
)
519 sal_Unicode aShortBuffer
[1024] = {0};
520 sal_Int32 nShortBufSize
= SAL_N_ELEMENTS( aShortBuffer
);
522 // use the version of 'GetShortPathName' that can deal with Unicode...
523 sal_Int32 nShortLen
= GetShortPathNameW(
524 reinterpret_cast<LPCWSTR
>( rLongPathName
.getStr() ),
525 reinterpret_cast<LPWSTR
>( aShortBuffer
),
528 if (nShortLen
< nShortBufSize
) // conversion successful?
529 aRes
= OString( OU2ENC( OUString( aShortBuffer
, nShortLen
), osl_getThreadTextEncoding()) );
531 OSL_FAIL( "Win_GetShortPathName: buffer to short" );
535 #endif //defined(WNT)
537 Reference
< XPossibleHyphens
> SAL_CALL
Hyphenator::createPossibleHyphens( const OUString
& aWord
,
538 const ::com::sun::star::lang::Locale
& aLocale
,
539 const ::com::sun::star::beans::PropertyValues
& aProperties
)
540 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
542 PropertyHelper_Hyphenation
& rHelper
= GetPropHelper();
543 rHelper
.SetTmpPropVals(aProperties
);
544 sal_Int16 minTrail
= rHelper
.GetMinTrailing();
545 sal_Int16 minLead
= rHelper
.GetMinLeading();
546 sal_Int16 minLen
= rHelper
.GetMinWordLength();
548 // Resolves: fdo#41083 honour MinWordLength in "createPossibleHyphens" as
549 // well as "hyphenate"
550 if (aWord
.getLength() < minLen
)
552 return PossibleHyphens::CreatePossibleHyphens( aWord
, LinguLocaleToLanguage( aLocale
),
553 aWord
, Sequence
< sal_Int16
>() );
557 for (int j
= 0; j
< numdict
; j
++)
559 if (aLocale
== aDicts
[j
].aLoc
) k
= j
;
562 // if we have a hyphenation dictionary matching this locale
565 HyphenDict
*dict
= NULL
;
566 // if this dictioanry has not been loaded yet do that
569 OUString DictFN
= aDicts
[k
].aName
+ ".dic";
572 osl::FileBase::getSystemPathFromFileURL( DictFN
, dictpath
);
573 OString
sTmp( OU2ENC( dictpath
, osl_getThreadTextEncoding() ) );
576 // workaround for Windows specific problem that the
577 // path length in calls to 'fopen' is limted to somewhat
578 // about 120+ characters which will usually be exceed when
579 // using dictionaries as extensions.
580 sTmp
= Win_GetShortPathName( dictpath
);
583 if ( ( dict
= hnj_hyphen_load ( sTmp
.getStr()) ) == NULL
)
585 fprintf(stderr
, "Couldn't find file %s and %s\n", sTmp
.getStr(), OU2ENC(dictpath
, osl_getThreadTextEncoding()) );
588 aDicts
[k
].aPtr
= dict
;
589 aDicts
[k
].eEnc
= getTextEncodingFromCharset(dict
->cset
);
592 // other wise hyphenate the word with that dictionary
593 dict
= aDicts
[k
].aPtr
;
594 rtl_TextEncoding eEnc
= aDicts
[k
].eEnc
;
595 CharClass
* pCC
= aDicts
[k
].apCC
;
597 // we don't want to work with a default text encoding since following incorrect
598 // results may occur only for specific text and thus may be hard to notice.
599 // Thus better always make a clean exit here if the text encoding is in question.
600 // Hopefully something not working at all will raise proper attention quickly. ;-)
601 DBG_ASSERT( eEnc
!= RTL_TEXTENCODING_DONTKNOW
, "failed to get text encoding! (maybe incorrect encoding string in file)" );
602 if (eEnc
== RTL_TEXTENCODING_DONTKNOW
)
605 // first handle smart quotes both single and double
606 OUStringBuffer
rBuf(aWord
);
607 sal_Int32 nc
= rBuf
.getLength();
609 for (sal_Int32 ix
=0; ix
< nc
; ix
++)
612 if ((ch
== 0x201C) || (ch
== 0x201D))
613 rBuf
[ix
] = (sal_Unicode
)0x0022;
614 if ((ch
== 0x2018) || (ch
== 0x2019))
615 rBuf
[ix
] = (sal_Unicode
)0x0027;
617 OUString
nWord(rBuf
.makeStringAndClear());
619 // now convert word to all lowercase for pattern recognition
620 OUString
nTerm(makeLowerCase(nWord
, pCC
));
622 // now convert word to needed encoding
623 OString
encWord(OU2ENC(nTerm
,eEnc
));
625 int wordlen
= encWord
.getLength();
626 boost::scoped_array
<char> lcword(new char[wordlen
+1]);
627 boost::scoped_array
<char> hyphens(new char[wordlen
+5]);
628 char ** rep
= NULL
; // replacements of discretionary hyphenation
629 int * pos
= NULL
; // array of [hyphenation point] minus [deletion position]
630 int * cut
= NULL
; // length of deletions in original word
632 // copy converted word into simple char buffer
633 strcpy(lcword
.get(),encWord
.getStr());
635 // first remove any trailing periods
637 while((n
>=0) && (lcword
[n
] == '.'))
642 const bool bFailed
= 0 != hnj_hyphen_hyphenate3(dict
, lcword
.get(), n
, hyphens
.get(), NULL
,
643 &rep
, &pos
, &cut
, minLead
, minTrail
,
644 Max(dict
->clhmin
, Max(dict
->clhmin
, 2) + Max(0, minLead
- Max(dict
->lhmin
, 2))),
645 Max(dict
->crhmin
, Max(dict
->crhmin
, 2) + Max(0, minTrail
- Max(dict
->rhmin
, 2))) );
650 for(int j
= 0; j
< n
; j
++)
652 if (rep
[j
]) free(rep
[j
]);
662 // now backfill hyphens[] for any removed periods
663 for (int c
= n
; c
< wordlen
; c
++)
665 hyphens
[wordlen
] = '\0';
667 sal_Int16 nHyphCount
= 0;
670 for ( i
= 0; i
< encWord
.getLength(); i
++)
676 Sequence
< sal_Int16
> aHyphPos(nHyphCount
);
677 sal_Int16
*pPos
= aHyphPos
.getArray();
678 OUStringBuffer hyphenatedWordBuffer
;
681 for (i
= 0; i
< nWord
.getLength(); i
++)
683 hyphenatedWordBuffer
.append(aWord
[i
]);
684 // hyphenation position
687 pPos
[nHyphCount
] = i
;
688 hyphenatedWordBuffer
.append('=');
693 OUString hyphenatedWord
= hyphenatedWordBuffer
.makeStringAndClear();
695 Reference
< XPossibleHyphens
> xRes
= PossibleHyphens::CreatePossibleHyphens(
696 aWord
, LinguLocaleToLanguage( aLocale
), hyphenatedWord
, aHyphPos
);
700 for(int j
= 0; j
< n
; j
++)
702 if (rep
[j
]) free(rep
[j
]);
715 OUString SAL_CALL
Hyphenator::makeLowerCase(const OUString
& aTerm
, CharClass
* pCC
)
718 return pCC
->lowercase(aTerm
);
722 OUString SAL_CALL
Hyphenator::makeUpperCase(const OUString
& aTerm
, CharClass
* pCC
)
725 return pCC
->uppercase(aTerm
);
729 OUString SAL_CALL
Hyphenator::makeInitCap(const OUString
& aTerm
, CharClass
* pCC
)
731 sal_Int32 tlen
= aTerm
.getLength();
734 OUString bTemp
= aTerm
.copy(0,1);
736 return ( pCC
->uppercase(bTemp
, 0, 1) + pCC
->lowercase(aTerm
,1,(tlen
-1)) );
738 return pCC
->uppercase(bTemp
, 0, 1);
743 Reference
< XInterface
> SAL_CALL
Hyphenator_CreateInstance(
744 const Reference
< XMultiServiceFactory
> & /*rSMgr*/ )
747 Reference
< XInterface
> xService
= (cppu::OWeakObject
*) new Hyphenator
;
751 sal_Bool SAL_CALL
Hyphenator::addLinguServiceEventListener(
752 const Reference
< XLinguServiceEventListener
>& rxLstnr
)
753 throw(RuntimeException
, std::exception
)
755 MutexGuard
aGuard( GetLinguMutex() );
758 if (!bDisposing
&& rxLstnr
.is())
760 bRes
= GetPropHelper().addLinguServiceEventListener( rxLstnr
);
765 sal_Bool SAL_CALL
Hyphenator::removeLinguServiceEventListener(
766 const Reference
< XLinguServiceEventListener
>& rxLstnr
)
767 throw(RuntimeException
, std::exception
)
769 MutexGuard
aGuard( GetLinguMutex() );
772 if (!bDisposing
&& rxLstnr
.is())
774 bRes
= GetPropHelper().removeLinguServiceEventListener( rxLstnr
);
779 OUString SAL_CALL
Hyphenator::getServiceDisplayName( const Locale
& /*rLocale*/ )
780 throw(RuntimeException
, std::exception
)
782 MutexGuard
aGuard( GetLinguMutex() );
783 return OUString( "Libhyphen Hyphenator" );
786 void SAL_CALL
Hyphenator::initialize( const Sequence
< Any
>& rArguments
)
787 throw(Exception
, RuntimeException
, std::exception
)
789 MutexGuard
aGuard( GetLinguMutex() );
793 sal_Int32 nLen
= rArguments
.getLength();
796 Reference
< XLinguProperties
> xPropSet
;
797 rArguments
.getConstArray()[0] >>= xPropSet
;
798 // rArguments.getConstArray()[1] >>= xDicList;
800 //! Pointer allows for access of the non-UNO functions.
801 //! And the reference to the UNO-functions while increasing
802 //! the ref-count and will implicitly free the memory
803 //! when the object is not longer used.
804 pPropHelper
= new PropertyHelper_Hyphenation( (XHyphenator
*) this, xPropSet
);
805 pPropHelper
->AddAsPropListener(); //! after a reference is established
808 OSL_FAIL( "wrong number of arguments in sequence" );
813 void SAL_CALL
Hyphenator::dispose()
814 throw(RuntimeException
, std::exception
)
816 MutexGuard
aGuard( GetLinguMutex() );
821 EventObject
aEvtObj( (XHyphenator
*) this );
822 aEvtListeners
.disposeAndClear( aEvtObj
);
825 pPropHelper
->RemoveAsPropListener();
832 void SAL_CALL
Hyphenator::addEventListener( const Reference
< XEventListener
>& rxListener
)
833 throw(RuntimeException
, std::exception
)
835 MutexGuard
aGuard( GetLinguMutex() );
837 if (!bDisposing
&& rxListener
.is())
838 aEvtListeners
.addInterface( rxListener
);
841 void SAL_CALL
Hyphenator::removeEventListener( const Reference
< XEventListener
>& rxListener
)
842 throw(RuntimeException
, std::exception
)
844 MutexGuard
aGuard( GetLinguMutex() );
846 if (!bDisposing
&& rxListener
.is())
847 aEvtListeners
.removeInterface( rxListener
);
850 // Service specific part
851 OUString SAL_CALL
Hyphenator::getImplementationName()
852 throw(RuntimeException
, std::exception
)
854 MutexGuard
aGuard( GetLinguMutex() );
856 return getImplementationName_Static();
859 sal_Bool SAL_CALL
Hyphenator::supportsService( const OUString
& ServiceName
)
860 throw(RuntimeException
, std::exception
)
862 return cppu::supportsService(this, ServiceName
);
865 Sequence
< OUString
> SAL_CALL
Hyphenator::getSupportedServiceNames()
866 throw(RuntimeException
, std::exception
)
868 MutexGuard
aGuard( GetLinguMutex() );
870 return getSupportedServiceNames_Static();
873 Sequence
< OUString
> Hyphenator::getSupportedServiceNames_Static()
876 MutexGuard
aGuard( GetLinguMutex() );
878 Sequence
< OUString
> aSNS( 1 ); // more than 1 service is possible, too
879 aSNS
.getArray()[0] = SN_HYPHENATOR
;
883 void * SAL_CALL
Hyphenator_getFactory( const sal_Char
* pImplName
,
884 XMultiServiceFactory
* pServiceManager
, void * )
887 if ( Hyphenator::getImplementationName_Static().equalsAscii( pImplName
) )
889 Reference
< XSingleServiceFactory
> xFactory
=
890 cppu::createOneInstanceFactory(
892 Hyphenator::getImplementationName_Static(),
893 Hyphenator_CreateInstance
,
894 Hyphenator::getSupportedServiceNames_Static());
895 // acquire, because we return an interface pointer instead of a reference
897 pRet
= xFactory
.get();
902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */