1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hyphenimp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_lingucomponent.hxx"
35 #include <com/sun/star/uno/Reference.h>
36 #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
38 //#include <com/sun/star/linguistic2/SpellFailure.hpp>
39 #include <cppuhelper/factory.hxx> // helper for factories
40 #include <com/sun/star/registry/XRegistryKey.hpp>
41 #include <i18npool/mslangid.hxx>
42 #include <svtools/pathoptions.hxx>
43 #include <svtools/useroptions.hxx>
44 #include <tools/debug.hxx>
45 #include <unotools/processfactory.hxx>
46 #include <osl/mutex.hxx>
50 #ifndef _HYPHENIMP_HXX
51 #include <hyphenimp.hxx>
54 #include <linguistic/hyphdta.hxx>
55 #include <rtl/ustring.hxx>
57 #include <rtl/ustrbuf.hxx>
59 #include <linguistic/lngprops.hxx>
60 #include <svtools/pathoptions.hxx>
61 #include <svtools/useroptions.hxx>
62 #include <svtools/lingucfg.hxx>
63 #include <osl/file.hxx>
65 #include "dictmgr.hxx"
75 using namespace com::sun::star
;
76 using namespace com::sun::star::beans
;
77 using namespace com::sun::star::lang
;
78 using namespace com::sun::star::uno
;
79 using namespace com::sun::star::linguistic2
;
80 using namespace linguistic
;
82 // values asigned to capitalization types
83 #define CAPTYPE_UNKNOWN 0
84 #define CAPTYPE_NOCAP 1
85 #define CAPTYPE_INITCAP 2
86 #define CAPTYPE_ALLCAP 3
87 #define CAPTYPE_MIXED 4
91 //#define Min(a,b) (a < b ? a : b)
92 #define Max(a,b) (a > b ? a : b)
94 ///////////////////////////////////////////////////////////////////////////
97 Hyphenator::Hyphenator() :
98 aEvtListeners ( GetLinguMutex() )
108 Hyphenator::~Hyphenator()
111 pPropHelper
->RemoveAsPropListener();
113 if ((numdict
) && (aDicts
)) {
114 for (int i
=0; i
< numdict
; i
++) {
115 if (aDicts
[i
].apCC
) delete aDicts
[i
].apCC
;
116 aDicts
[i
].apCC
= NULL
;
119 if (aDicts
) delete[] aDicts
;
125 PropertyHelper_Hyphen
& Hyphenator::GetPropHelper_Impl()
130 Reference
< XPropertySet
> xPropSet( GetLinguProperties(), UNO_QUERY
);
132 pPropHelper
= new PropertyHelper_Hyphen ((XHyphenator
*) this, xPropSet
);
133 xPropHelper
= pPropHelper
;
134 pPropHelper
->AddAsPropListener(); //! after a reference is established
141 Sequence
< Locale
> SAL_CALL
Hyphenator::getLocales()
142 throw(RuntimeException
)
144 MutexGuard
aGuard( GetLinguMutex() );
146 // this routine should return the locales supported by the installed
151 SvtLinguConfig aLinguCfg
;
153 // get list of dictionaries-to-use
154 // (or better speaking: the list of dictionaries using the
155 // new configuration entries).
156 std::list
< SvtLinguConfigDictionaryEntry
> aDics
;
157 uno::Sequence
< rtl::OUString
> aFormatList
;
158 aLinguCfg
.GetSupportedDictionaryFormatsFor( A2OU("Hyphenators"),
159 A2OU("org.openoffice.lingu.LibHnjHyphenator"), aFormatList
);
160 sal_Int32 nLen
= aFormatList
.getLength();
161 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
163 std::vector
< SvtLinguConfigDictionaryEntry
> aTmpDic(
164 aLinguCfg
.GetActiveDictionariesByFormat( aFormatList
[i
] ) );
165 aDics
.insert( aDics
.end(), aTmpDic
.begin(), aTmpDic
.end() );
168 //!! for compatibility with old dictionaries (the ones not using extensions
169 //!! or new configuration entries, but still using the dictionary.lst file)
170 //!! Get the list of old style spell checking dictionaries to use...
171 std::vector
< SvtLinguConfigDictionaryEntry
> aOldStyleDics(
172 GetOldStyleDics( "HYPH" ) );
174 // to prefer dictionaries with configuration entries we will only
175 // use those old style dictionaries that add a language that
176 // is not yet supported by the list od new style dictionaries
177 MergeNewStyleDicsAndOldStyleDics( aDics
, aOldStyleDics
);
179 numdict
= aDics
.size();
182 // get supported locales from the dictionaries-to-use...
184 std::set
< rtl::OUString
, lt_rtl_OUString
> aLocaleNamesSet
;
185 std::list
< SvtLinguConfigDictionaryEntry
>::const_iterator aDictIt
;
186 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
188 uno::Sequence
< rtl::OUString
> aLocaleNames( aDictIt
->aLocaleNames
);
189 sal_Int32 nLen2
= aLocaleNames
.getLength();
190 for (k
= 0; k
< nLen2
; ++k
)
192 aLocaleNamesSet
.insert( aLocaleNames
[k
] );
195 // ... and add them to the resulting sequence
196 aSuppLocales
.realloc( aLocaleNamesSet
.size() );
197 std::set
< rtl::OUString
, lt_rtl_OUString
>::const_iterator aItB
;
199 for (aItB
= aLocaleNamesSet
.begin(); aItB
!= aLocaleNamesSet
.end(); ++aItB
)
201 Locale
aTmp( MsLangId::convertLanguageToLocale(
202 MsLangId::convertIsoStringToLanguage( *aItB
)));
203 aSuppLocales
[k
++] = aTmp
;
206 //! For each dictionary and each locale we need a seperate entry.
207 //! If this results in more than one dictionary per locale than (for now)
208 //! it is undefined which dictionary gets used.
209 //! In the future the implementation should support using several dictionaries
212 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
213 numdict
= numdict
+ aDictIt
->aLocaleNames
.getLength();
215 // add dictionary information
216 aDicts
= new HDInfo
[numdict
];
218 aTEncs = new rtl_TextEncoding [numdict];
219 aTLocs = new Locale [numdict];
220 aTNames = new OUString [numdict];
221 aCharSetInfo = new CharClass* [numdict];
224 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
226 if (aDictIt
->aLocaleNames
.getLength() > 0 &&
227 aDictIt
->aLocations
.getLength() > 0)
229 uno::Sequence
< rtl::OUString
> aLocaleNames( aDictIt
->aLocaleNames
);
230 sal_Int32 nLocales
= aLocaleNames
.getLength();
232 // currently only one language per dictionary is supported in the actual implementation...
233 // Thus here we work-around this by adding the same dictionary several times.
234 // Once for each of it's supported locales.
235 for (sal_Int32 i
= 0; i
< nLocales
; ++i
)
237 aDicts
[k
].aPtr
= NULL
;
239 aDicts
[k
].aLoc
= MsLangId::convertLanguageToLocale(
240 MsLangId::convertIsoStringToLanguage( aDictIt
->aLocaleNames
[i
] ));
241 aDicts
[k
].apCC
= new CharClass( aDicts
[k
].aLoc
);
242 // also both files have to be in the same directory and the
243 // file names must only differ in the extension (.aff/.dic).
244 // Thus we use the first location only and strip the extension part.
245 rtl::OUString aLocation
= aDictIt
->aLocations
[0];
246 sal_Int32 nPos
= aLocation
.lastIndexOf( '.' );
247 aLocation
= aLocation
.copy( 0, nPos
);
248 aDicts
[k
].aName
= aLocation
;
254 DBG_ASSERT( k
== numdict
, "index mismatch?" );
258 /* no dictionary found so register no dictionaries */
261 aSuppLocales
.realloc(0);
270 sal_Bool SAL_CALL
Hyphenator::hasLocale(const Locale
& rLocale
)
271 throw(RuntimeException
)
273 MutexGuard
aGuard( GetLinguMutex() );
276 if (!aSuppLocales
.getLength())
279 const Locale
*pLocale
= aSuppLocales
.getConstArray();
280 INT32 nLen
= aSuppLocales
.getLength();
281 for (INT32 i
= 0; i
< nLen
; ++i
)
283 if (rLocale
== pLocale
[i
])
293 Reference
< XHyphenatedWord
> SAL_CALL
294 Hyphenator::hyphenate( const ::rtl::OUString
& aWord
,
295 const ::com::sun::star::lang::Locale
& aLocale
,
296 sal_Int16 nMaxLeading
,
297 const ::com::sun::star::beans::PropertyValues
& aProperties
)
298 throw (com::sun::star::uno::RuntimeException
,
299 com::sun::star::lang::IllegalArgumentException
)
301 int nHyphenationPos
= -1;
302 int nHyphenationPosAlt
= -1;
303 int nHyphenationPosAltHyph
= -1;
309 PropertyHelper_Hyphen
& rHelper
= GetPropHelper();
310 rHelper
.SetTmpPropVals(aProperties
);
311 sal_Int16 minTrail
= rHelper
.GetMinTrailing();
312 sal_Int16 minLead
= rHelper
.GetMinLeading();
313 sal_Int16 minLen
= rHelper
.GetMinWordLength();
315 HyphenDict
*dict
= NULL
;
316 rtl_TextEncoding aEnc
= 0;
317 CharClass
* pCC
= NULL
;
319 Reference
< XHyphenatedWord
> xRes
;
322 for (int j
= 0; j
< numdict
; j
++)
323 if (aLocale
== aDicts
[j
].aLoc
) k
= j
;
326 // if we have a hyphenation dictionary matching this locale
329 // if this dictinary has not been loaded yet do that
330 if (!aDicts
[k
].aPtr
) {
332 OUString DictFN
= aDicts
[k
].aName
+ A2OU(".dic");
335 osl::FileBase::getSystemPathFromFileURL( DictFN
, dictpath
);
336 OString
sTmp( OU2ENC( dictpath
, osl_getThreadTextEncoding() ) );
339 // workaround for Windows specifc problem that the
340 // path length in calls to 'fopen' is limted to somewhat
341 // about 120+ characters which will usually be exceed when
342 // using dictionaries as extensions.
343 sTmp
= Win_GetShortPathName( dictpath
);
346 if ( ( dict
= hnj_hyphen_load ( sTmp
.getStr()) ) == NULL
)
348 fprintf(stderr
, "Couldn't find file %s\n", OU2ENC(dictpath
, osl_getThreadTextEncoding()) );
351 aDicts
[k
].aPtr
= dict
;
352 aDicts
[k
].aEnc
= rtl_getTextEncodingFromUnixCharset(dict
->cset
);
353 if (aDicts
[k
].aEnc
== RTL_TEXTENCODING_DONTKNOW
) {
354 if (strcmp("ISCII-DEVANAGARI", dict
->cset
) == 0) {
355 aDicts
[k
].aEnc
= RTL_TEXTENCODING_ISCII_DEVANAGARI
;
356 } else if (strcmp("UTF-8", dict
->cset
) == 0) {
357 aDicts
[k
].aEnc
= RTL_TEXTENCODING_UTF8
;
362 // other wise hyphenate the word with that dictionary
363 dict
= aDicts
[k
].aPtr
;
364 aEnc
= aDicts
[k
].aEnc
;
365 pCC
= aDicts
[k
].apCC
;
367 sal_uInt16 ct
= CAPTYPE_UNKNOWN
;
368 ct
= capitalType(aWord
, pCC
);
370 // first convert any smart quotes or apostrophes to normal ones
371 OUStringBuffer
rBuf(aWord
);
372 sal_Int32 nc
= rBuf
.getLength();
374 for (sal_Int32 ix
=0; ix
< nc
; ix
++) {
375 ch
= rBuf
.charAt(ix
);
376 if ((ch
== 0x201C) || (ch
== 0x201D)) rBuf
.setCharAt(ix
,(sal_Unicode
)0x0022);
377 if ((ch
== 0x2018) || (ch
== 0x2019)) rBuf
.setCharAt(ix
,(sal_Unicode
)0x0027);
379 OUString
nWord(rBuf
.makeStringAndClear());
381 // now convert word to all lowercase for pattern recognition
382 OUString
nTerm(makeLowerCase(nWord
, pCC
));
384 // now convert word to needed encoding
385 OString
encWord(OU2ENC(nTerm
,aEnc
));
387 wordlen
= encWord
.getLength();
388 lcword
= new char[wordlen
+ 1];
389 hyphens
= new char[wordlen
+ 5];
391 char ** rep
= NULL
; // replacements of discretionary hyphenation
392 int * pos
= NULL
; // array of [hyphenation point] minus [deletion position]
393 int * cut
= NULL
; // length of deletions in original word
395 // copy converted word into simple char buffer
396 strcpy(lcword
,encWord
.getStr());
398 // now strip off any ending periods
400 while((n
>=0) && (lcword
[n
] == '.')) n
--;
403 if (hnj_hyphen_hyphenate3(dict
, lcword
, n
, hyphens
, NULL
, &rep
, &pos
, &cut
,
404 minLead
, minTrail
, Max(dict
->clhmin
, Max(dict
->clhmin
, 2) + Max(0, minLead
- Max(dict
->lhmin
, 2))),
405 Max(dict
->crhmin
, Max(dict
->crhmin
, 2) + Max(0, minTrail
- Max(dict
->rhmin
, 2)))))
407 //whoops something did not work
411 for(int j
= 0; j
< n
; j
++) {
412 if (rep
[j
]) free(rep
[j
]);
422 // now backfill hyphens[] for any removed trailing periods
423 for (int c
= n
; c
< wordlen
; c
++) hyphens
[c
] = '0';
424 hyphens
[wordlen
] = '\0';
426 INT32 Leading
= GetPosInWordToCheck( aWord
, nMaxLeading
);
428 for (INT32 i
= 0; i
< n
; i
++)
431 BOOL hit
= (n
>= minLen
);
432 if (!rep
|| !rep
[i
] || (i
>= n
)) {
433 hit
= hit
&& (hyphens
[i
]&1) && (i
< Leading
);
434 hit
= hit
&& (i
>= (minLead
-1) );
435 hit
= hit
&& ((n
- i
- 1) >= minTrail
);
437 // calculate change character length before hyphenation point signed with '='
438 for (char * c
= rep
[i
]; *c
&& (*c
!= '='); c
++) {
439 if (aEnc
== RTL_TEXTENCODING_UTF8
) {
440 if (((unsigned char) *c
) >> 6 != 2) leftrep
++;
443 hit
= hit
&& (hyphens
[i
]&1) && ((i
+ leftrep
- pos
[i
]) < Leading
);
444 hit
= hit
&& ((i
+ leftrep
- pos
[i
]) >= (minLead
-1) );
445 hit
= hit
&& ((n
- i
- 1 + sal::static_int_cast
< sal_sSize
>(strlen(rep
[i
])) - leftrep
- 1) >= minTrail
);
449 if (rep
&& (i
< n
) && rep
[i
]) {
450 nHyphenationPosAlt
= i
- pos
[i
];
451 nHyphenationPosAltHyph
= i
+ leftrep
- pos
[i
];
456 if (nHyphenationPos
== -1) {
459 if (rep
&& rep
[nHyphenationPos
]) {
461 char * s
= rep
[nHyphenationPos
];
464 if (*s
== '=') eq
= 1;
465 if (eq
) *s
= *(s
+ 1);
467 OUString
repHyphlow(rep
[nHyphenationPos
], strlen(rep
[nHyphenationPos
]), aEnc
);
472 repHyph
= makeUpperCase(repHyphlow
, pCC
);
475 case CAPTYPE_INITCAP
:
477 if (nHyphenationPosAlt
== 0) {
478 repHyph
= makeInitCap(repHyphlow
, pCC
);
480 repHyph
= repHyphlow
;
486 repHyph
= repHyphlow
;
492 INT16 nPos
= (INT16
) ((nHyphenationPosAltHyph
< nHyphenationPos
) ?
493 nHyphenationPosAltHyph
: nHyphenationPos
);
494 // dicretionary hyphenation
495 xRes
= new HyphenatedWord( aWord
, LocaleToLanguage( aLocale
), nPos
,
496 aWord
.replaceAt(nHyphenationPosAlt
+ 1, cut
[nHyphenationPos
], repHyph
),
497 (INT16
) nHyphenationPosAltHyph
);
499 xRes
= new HyphenatedWord( aWord
, LocaleToLanguage( aLocale
),
500 (INT16
)nHyphenationPos
, aWord
, (INT16
) nHyphenationPos
);
507 for(int j
= 0; j
< n
; j
++) {
508 if (rep
[j
]) free(rep
[j
]);
520 Reference
< XHyphenatedWord
> SAL_CALL
521 Hyphenator::queryAlternativeSpelling( const ::rtl::OUString
& /*aWord*/,
522 const ::com::sun::star::lang::Locale
& /*aLocale*/,
523 sal_Int16
/*nIndex*/,
524 const ::com::sun::star::beans::PropertyValues
& /*aProperties*/ )
525 throw(::com::sun::star::lang::IllegalArgumentException
,
526 ::com::sun::star::uno::RuntimeException
)
528 /* alternative spelling isn't supported by tex dictionaries */
529 /* XXX: OOo's extended libhjn algorithm can support alternative spellings with extended TeX dic. */
530 /* TASK: implement queryAlternativeSpelling() */
534 Reference
< XPossibleHyphens
> SAL_CALL
535 Hyphenator::createPossibleHyphens( const ::rtl::OUString
& aWord
,
536 const ::com::sun::star::lang::Locale
& aLocale
,
537 const ::com::sun::star::beans::PropertyValues
& /*aProperties*/ )
538 throw(::com::sun::star::lang::IllegalArgumentException
,
539 ::com::sun::star::uno::RuntimeException
)
548 HyphenDict
*dict
= NULL
;
549 rtl_TextEncoding aEnc
= 0;
550 CharClass
* pCC
= NULL
;
552 Reference
< XPossibleHyphens
> xRes
;
555 for (int j
= 0; j
< numdict
; j
++)
556 if (aLocale
== aDicts
[j
].aLoc
) k
= j
;
559 // if we have a hyphenation dictionary matching this locale
562 // if this dictioanry has not been loaded yet do that
563 if (!aDicts
[k
].aPtr
) {
565 OUString DictFN
= aDicts
[k
].aName
+ A2OU(".dic");
568 osl::FileBase::getSystemPathFromFileURL( DictFN
, dictpath
);
569 OString
sTmp( OU2ENC( dictpath
, osl_getThreadTextEncoding() ) );
572 // workaround for Windows specifc problem that the
573 // path length in calls to 'fopen' is limted to somewhat
574 // about 120+ characters which will usually be exceed when
575 // using dictionaries as extensions.
576 sTmp
= Win_GetShortPathName( dictpath
);
579 if ( ( dict
= hnj_hyphen_load ( sTmp
.getStr()) ) == NULL
)
581 fprintf(stderr
, "Couldn't find file %s and %s\n", sTmp
.getStr(), OU2ENC(dictpath
, osl_getThreadTextEncoding()) );
584 aDicts
[k
].aPtr
= dict
;
585 aDicts
[k
].aEnc
= rtl_getTextEncodingFromUnixCharset(dict
->cset
);
586 if (aDicts
[k
].aEnc
== RTL_TEXTENCODING_DONTKNOW
) {
587 if (strcmp("ISCII-DEVANAGARI", dict
->cset
) == 0) {
588 aDicts
[k
].aEnc
= RTL_TEXTENCODING_ISCII_DEVANAGARI
;
589 } else if (strcmp("UTF-8", dict
->cset
) == 0) {
590 aDicts
[k
].aEnc
= RTL_TEXTENCODING_UTF8
;
595 // other wise hyphenate the word with that dictionary
596 dict
= aDicts
[k
].aPtr
;
597 aEnc
= aDicts
[k
].aEnc
;
598 pCC
= aDicts
[k
].apCC
;
600 // first handle smart quotes both single and double
601 OUStringBuffer
rBuf(aWord
);
602 sal_Int32 nc
= rBuf
.getLength();
604 for (sal_Int32 ix
=0; ix
< nc
; ix
++) {
605 ch
= rBuf
.charAt(ix
);
606 if ((ch
== 0x201C) || (ch
== 0x201D)) rBuf
.setCharAt(ix
,(sal_Unicode
)0x0022);
607 if ((ch
== 0x2018) || (ch
== 0x2019)) rBuf
.setCharAt(ix
,(sal_Unicode
)0x0027);
609 OUString
nWord(rBuf
.makeStringAndClear());
611 // now convert word to all lowercase for pattern recognition
612 OUString
nTerm(makeLowerCase(nWord
, pCC
));
614 // now convert word to needed encoding
615 OString
encWord(OU2ENC(nTerm
,aEnc
));
617 wordlen
= encWord
.getLength();
618 lcword
= new char[wordlen
+1];
619 hyphens
= new char[wordlen
+5];
621 // copy converted word into simple char buffer
622 strcpy(lcword
,encWord
.getStr());
624 // first remove any trailing periods
626 while((n
>=0) && (lcword
[n
] == '.')) n
--;
628 // fprintf(stderr,"hyphenate... %s\n",lcword); fflush(stderr);
630 if (hnj_hyphen_hyphenate(dict
, lcword
, n
, hyphens
))
637 // now backfill hyphens[] for any removed periods
638 for (int c
= n
; c
< wordlen
; c
++) hyphens
[c
] = '0';
639 hyphens
[wordlen
] = '\0';
640 // fprintf(stderr,"... %s\n",hyphens); fflush(stderr);
642 INT16 nHyphCount
= 0;
645 for ( i
= 0; i
< encWord
.getLength(); i
++)
649 Sequence
< INT16
> aHyphPos(nHyphCount
);
650 INT16
*pPos
= aHyphPos
.getArray();
651 OUStringBuffer hyphenatedWordBuffer
;
652 OUString hyphenatedWord
;
655 for (i
= 0; i
< encWord
.getLength(); i
++)
657 hyphenatedWordBuffer
.append(aWord
[i
]);
660 pPos
[nHyphCount
] = i
;
661 hyphenatedWordBuffer
.append(sal_Unicode('='));
666 hyphenatedWord
= hyphenatedWordBuffer
.makeStringAndClear();
667 //fprintf(stderr,"result is %s\n",OU2A(hyphenatedWord));
670 xRes
= new PossibleHyphens( aWord
, LocaleToLanguage( aLocale
),
671 hyphenatedWord
, aHyphPos
);
682 sal_uInt16 SAL_CALL
Hyphenator::capitalType(const OUString
& aTerm
, CharClass
* pCC
)
684 sal_Int32 tlen
= aTerm
.getLength();
685 if ((pCC
) && (tlen
)) {
688 for (xub_StrLen tindex
= 0; tindex
< tlen
; tindex
++) {
689 if (pCC
->getCharacterType(aStr
,tindex
) &
690 ::com::sun::star::i18n::KCharacterType::UPPER
) nc
++;
693 if (nc
== 0) return (sal_uInt16
) CAPTYPE_NOCAP
;
695 if (nc
== tlen
) return (sal_uInt16
) CAPTYPE_ALLCAP
;
697 if ((nc
== 1) && (pCC
->getCharacterType(aStr
,0) &
698 ::com::sun::star::i18n::KCharacterType::UPPER
))
699 return (sal_uInt16
) CAPTYPE_INITCAP
;
701 return (sal_uInt16
) CAPTYPE_MIXED
;
703 return (sal_uInt16
) CAPTYPE_UNKNOWN
;
706 OUString SAL_CALL
Hyphenator::makeLowerCase(const OUString
& aTerm
, CharClass
* pCC
)
709 return pCC
->toLower_rtl(aTerm
, 0, aTerm
.getLength());
713 OUString SAL_CALL
Hyphenator::makeUpperCase(const OUString
& aTerm
, CharClass
* pCC
)
716 return pCC
->toUpper_rtl(aTerm
, 0, aTerm
.getLength());
721 OUString SAL_CALL
Hyphenator::makeInitCap(const OUString
& aTerm
, CharClass
* pCC
)
723 sal_Int32 tlen
= aTerm
.getLength();
724 if ((pCC
) && (tlen
)) {
725 OUString bTemp
= aTerm
.copy(0,1);
727 return ( pCC
->toUpper_rtl(bTemp
, 0, 1)
728 + pCC
->toLower_rtl(aTerm
,1,(tlen
-1)) );
730 return pCC
->toUpper_rtl(bTemp
, 0, 1);
738 Reference
< XInterface
> SAL_CALL
Hyphenator_CreateInstance(
739 const Reference
< XMultiServiceFactory
> & /*rSMgr*/ )
743 Reference
< XInterface
> xService
= (cppu::OWeakObject
*) new Hyphenator
;
749 Hyphenator::addLinguServiceEventListener(
750 const Reference
< XLinguServiceEventListener
>& rxLstnr
)
751 throw(RuntimeException
)
753 MutexGuard
aGuard( GetLinguMutex() );
756 if (!bDisposing
&& rxLstnr
.is())
758 bRes
= GetPropHelper().addLinguServiceEventListener( rxLstnr
);
765 Hyphenator::removeLinguServiceEventListener(
766 const Reference
< XLinguServiceEventListener
>& rxLstnr
)
767 throw(RuntimeException
)
769 MutexGuard
aGuard( GetLinguMutex() );
772 if (!bDisposing
&& rxLstnr
.is())
774 DBG_ASSERT( xPropHelper
.is(), "xPropHelper non existent" );
775 bRes
= GetPropHelper().removeLinguServiceEventListener( rxLstnr
);
782 Hyphenator::getServiceDisplayName( const Locale
& /*rLocale*/ )
783 throw(RuntimeException
)
785 MutexGuard
aGuard( GetLinguMutex() );
786 return A2OU( "Libhyphen Hyphenator" );
791 Hyphenator::initialize( const Sequence
< Any
>& rArguments
)
792 throw(Exception
, RuntimeException
)
794 MutexGuard
aGuard( GetLinguMutex() );
798 INT32 nLen
= rArguments
.getLength();
801 Reference
< XPropertySet
> xPropSet
;
802 rArguments
.getConstArray()[0] >>= xPropSet
;
803 //rArguments.getConstArray()[1] >>= xDicList;
805 //! Pointer allows for access of the non-UNO functions.
806 //! And the reference to the UNO-functions while increasing
807 //! the ref-count and will implicitly free the memory
808 //! when the object is not longer used.
809 pPropHelper
= new PropertyHelper_Hyphen( (XHyphenator
*) this, xPropSet
);
810 xPropHelper
= pPropHelper
;
811 pPropHelper
->AddAsPropListener(); //! after a reference is established
814 DBG_ERROR( "wrong number of arguments in sequence" );
822 Hyphenator::dispose()
823 throw(RuntimeException
)
825 MutexGuard
aGuard( GetLinguMutex() );
830 EventObject
aEvtObj( (XHyphenator
*) this );
831 aEvtListeners
.disposeAndClear( aEvtObj
);
837 Hyphenator::addEventListener( const Reference
< XEventListener
>& rxListener
)
838 throw(RuntimeException
)
840 MutexGuard
aGuard( GetLinguMutex() );
842 if (!bDisposing
&& rxListener
.is())
843 aEvtListeners
.addInterface( rxListener
);
848 Hyphenator::removeEventListener( const Reference
< XEventListener
>& rxListener
)
849 throw(RuntimeException
)
851 MutexGuard
aGuard( GetLinguMutex() );
853 if (!bDisposing
&& rxListener
.is())
854 aEvtListeners
.removeInterface( rxListener
);
858 ///////////////////////////////////////////////////////////////////////////
859 // Service specific part
862 OUString SAL_CALL
Hyphenator::getImplementationName()
863 throw(RuntimeException
)
865 MutexGuard
aGuard( GetLinguMutex() );
867 return getImplementationName_Static();
871 sal_Bool SAL_CALL
Hyphenator::supportsService( const OUString
& ServiceName
)
872 throw(RuntimeException
)
874 MutexGuard
aGuard( GetLinguMutex() );
876 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
877 const OUString
* pArray
= aSNL
.getConstArray();
878 for( INT32 i
= 0; i
< aSNL
.getLength(); i
++ )
879 if( pArray
[i
] == ServiceName
)
885 Sequence
< OUString
> SAL_CALL
Hyphenator::getSupportedServiceNames()
886 throw(RuntimeException
)
888 MutexGuard
aGuard( GetLinguMutex() );
890 return getSupportedServiceNames_Static();
894 Sequence
< OUString
> Hyphenator::getSupportedServiceNames_Static()
897 MutexGuard
aGuard( GetLinguMutex() );
899 Sequence
< OUString
> aSNS( 1 ); // auch mehr als 1 Service moeglich
900 aSNS
.getArray()[0] = A2OU( SN_HYPHENATOR
);
905 sal_Bool SAL_CALL
Hyphenator_writeInfo(
906 void * /*pServiceManager*/, registry::XRegistryKey
* pRegistryKey
)
912 aImpl
+= Hyphenator::getImplementationName_Static().getStr();
913 aImpl
.AppendAscii( "/UNO/SERVICES" );
914 Reference
< registry::XRegistryKey
> xNewKey
=
915 pRegistryKey
->createKey( aImpl
);
916 Sequence
< OUString
> aServices
=
917 Hyphenator::getSupportedServiceNames_Static();
918 for( INT32 i
= 0; i
< aServices
.getLength(); i
++ )
919 xNewKey
->createKey( aServices
.getConstArray()[i
] );
930 void * SAL_CALL
Hyphenator_getFactory( const sal_Char
* pImplName
,
931 XMultiServiceFactory
* pServiceManager
, void * )
934 if ( !Hyphenator::getImplementationName_Static().compareToAscii( pImplName
) )
936 Reference
< XSingleServiceFactory
> xFactory
=
937 cppu::createOneInstanceFactory(
939 Hyphenator::getImplementationName_Static(),
940 Hyphenator_CreateInstance
,
941 Hyphenator::getSupportedServiceNames_Static());
942 // acquire, because we return an interface pointer instead of a reference
944 pRet
= xFactory
.get();
950 ///////////////////////////////////////////////////////////////////////////
952 #undef CAPTYPE_UNKNOWN
954 #undef CAPTYPE_INITCAP
955 #undef CAPTYPE_ALLCAP