1b0844812SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b0844812SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b0844812SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b0844812SAndrew Rist * distributed with this work for additional information
6b0844812SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b0844812SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b0844812SAndrew Rist * "License"); you may not use this file except in compliance
9b0844812SAndrew Rist * with the License. You may obtain a copy of the License at
10b0844812SAndrew Rist *
11b0844812SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b0844812SAndrew Rist *
13b0844812SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b0844812SAndrew Rist * software distributed under the License is distributed on an
15b0844812SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b0844812SAndrew Rist * KIND, either express or implied. See the License for the
17b0844812SAndrew Rist * specific language governing permissions and limitations
18b0844812SAndrew Rist * under the License.
19b0844812SAndrew Rist *
20b0844812SAndrew Rist *************************************************************/
21b0844812SAndrew Rist
22b0844812SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25*c4c42a0eSDamjan Jovanovic #include "precompiled_hyphen.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
29cdf0e10cSrcweir #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <cppuhelper/factory.hxx> // helper for factories
32cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp>
33cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
34cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
35cdf0e10cSrcweir #include <unotools/useroptions.hxx>
36cdf0e10cSrcweir #include <tools/debug.hxx>
37cdf0e10cSrcweir #include <unotools/processfactory.hxx>
38cdf0e10cSrcweir #include <osl/mutex.hxx>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include <hyphen.h>
41cdf0e10cSrcweir #include <hyphenimp.hxx>
42cdf0e10cSrcweir
43cdf0e10cSrcweir #include <linguistic/hyphdta.hxx>
44cdf0e10cSrcweir #include <rtl/ustring.hxx>
45cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
46cdf0e10cSrcweir #include <rtl/textenc.h>
47cdf0e10cSrcweir
48cdf0e10cSrcweir #include <linguistic/lngprops.hxx>
49cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
50cdf0e10cSrcweir #include <unotools/useroptions.hxx>
51cdf0e10cSrcweir #include <unotools/lingucfg.hxx>
52cdf0e10cSrcweir #include <osl/file.hxx>
53cdf0e10cSrcweir
54cdf0e10cSrcweir #include <stdio.h>
55cdf0e10cSrcweir #include <string.h>
56cdf0e10cSrcweir
57cdf0e10cSrcweir #include <list>
58cdf0e10cSrcweir #include <set>
59cdf0e10cSrcweir
60cdf0e10cSrcweir using namespace utl;
61cdf0e10cSrcweir using namespace osl;
62cdf0e10cSrcweir using namespace rtl;
63cdf0e10cSrcweir using namespace com::sun::star;
64cdf0e10cSrcweir using namespace com::sun::star::beans;
65cdf0e10cSrcweir using namespace com::sun::star::lang;
66cdf0e10cSrcweir using namespace com::sun::star::uno;
67cdf0e10cSrcweir using namespace com::sun::star::linguistic2;
68cdf0e10cSrcweir using namespace linguistic;
69cdf0e10cSrcweir
7030acf5e8Spfg // values assigned to capitalization types
71cdf0e10cSrcweir #define CAPTYPE_UNKNOWN 0
72cdf0e10cSrcweir #define CAPTYPE_NOCAP 1
73cdf0e10cSrcweir #define CAPTYPE_INITCAP 2
74cdf0e10cSrcweir #define CAPTYPE_ALLCAP 3
75cdf0e10cSrcweir #define CAPTYPE_MIXED 4
76cdf0e10cSrcweir
77cdf0e10cSrcweir // min, max
78cdf0e10cSrcweir
79cdf0e10cSrcweir //#define Min(a,b) (a < b ? a : b)
80cdf0e10cSrcweir #define Max(a,b) (a > b ? a : b)
81cdf0e10cSrcweir
82cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
83cdf0e10cSrcweir
84cdf0e10cSrcweir
Hyphenator()85cdf0e10cSrcweir Hyphenator::Hyphenator() :
86cdf0e10cSrcweir aEvtListeners ( GetLinguMutex() )
87cdf0e10cSrcweir {
88cdf0e10cSrcweir bDisposing = sal_False;
89cdf0e10cSrcweir pPropHelper = NULL;
90cdf0e10cSrcweir aDicts = NULL;
91cdf0e10cSrcweir numdict = 0;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir
94cdf0e10cSrcweir
~Hyphenator()95cdf0e10cSrcweir Hyphenator::~Hyphenator()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir if (pPropHelper)
98cdf0e10cSrcweir pPropHelper->RemoveAsPropListener();
99cdf0e10cSrcweir
100cdf0e10cSrcweir if ((numdict) && (aDicts))
101cdf0e10cSrcweir {
102cdf0e10cSrcweir for (int i=0; i < numdict; i++)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir if (aDicts[i].apCC) delete aDicts[i].apCC;
105cdf0e10cSrcweir aDicts[i].apCC = NULL;
106cdf0e10cSrcweir }
107cdf0e10cSrcweir }
108cdf0e10cSrcweir if (aDicts) delete[] aDicts;
109cdf0e10cSrcweir aDicts = NULL;
110cdf0e10cSrcweir numdict = 0;
111b63233d8Sdamjan delete pPropHelper;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
114cdf0e10cSrcweir
GetPropHelper_Impl()115b63233d8Sdamjan PropertyHelper_Hyphenation& Hyphenator::GetPropHelper_Impl()
116cdf0e10cSrcweir {
117cdf0e10cSrcweir if (!pPropHelper)
118cdf0e10cSrcweir {
119cdf0e10cSrcweir Reference< XPropertySet > xPropSet( GetLinguProperties(), UNO_QUERY );
120cdf0e10cSrcweir
121b63233d8Sdamjan pPropHelper = new PropertyHelper_Hyphenation ((XHyphenator *) this, xPropSet );
122cdf0e10cSrcweir pPropHelper->AddAsPropListener(); //! after a reference is established
123cdf0e10cSrcweir }
124cdf0e10cSrcweir return *pPropHelper;
125cdf0e10cSrcweir
126cdf0e10cSrcweir }
127cdf0e10cSrcweir
128cdf0e10cSrcweir
getLocales()129cdf0e10cSrcweir Sequence< Locale > SAL_CALL Hyphenator::getLocales()
130cdf0e10cSrcweir throw(RuntimeException)
131cdf0e10cSrcweir {
132cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
133cdf0e10cSrcweir
134cdf0e10cSrcweir // this routine should return the locales supported by the installed
135cdf0e10cSrcweir // dictionaries.
136cdf0e10cSrcweir
137cdf0e10cSrcweir if (!numdict)
138cdf0e10cSrcweir {
139cdf0e10cSrcweir SvtLinguConfig aLinguCfg;
140cdf0e10cSrcweir
141cdf0e10cSrcweir // get list of dictionaries-to-use
142cdf0e10cSrcweir // (or better speaking: the list of dictionaries using the
143cdf0e10cSrcweir // new configuration entries).
144cdf0e10cSrcweir std::list< SvtLinguConfigDictionaryEntry > aDics;
145cdf0e10cSrcweir uno::Sequence< rtl::OUString > aFormatList;
146cdf0e10cSrcweir aLinguCfg.GetSupportedDictionaryFormatsFor( A2OU("Hyphenators"),
147cdf0e10cSrcweir A2OU("org.openoffice.lingu.LibHnjHyphenator"), aFormatList );
148cdf0e10cSrcweir sal_Int32 nLen = aFormatList.getLength();
149cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i)
150cdf0e10cSrcweir {
151cdf0e10cSrcweir std::vector< SvtLinguConfigDictionaryEntry > aTmpDic(
152cdf0e10cSrcweir aLinguCfg.GetActiveDictionariesByFormat( aFormatList[i] ) );
153cdf0e10cSrcweir aDics.insert( aDics.end(), aTmpDic.begin(), aTmpDic.end() );
154cdf0e10cSrcweir }
155cdf0e10cSrcweir
156cdf0e10cSrcweir //!! for compatibility with old dictionaries (the ones not using extensions
157cdf0e10cSrcweir //!! or new configuration entries, but still using the dictionary.lst file)
158cdf0e10cSrcweir //!! Get the list of old style spell checking dictionaries to use...
159cdf0e10cSrcweir std::vector< SvtLinguConfigDictionaryEntry > aOldStyleDics(
160cdf0e10cSrcweir GetOldStyleDics( "HYPH" ) );
161cdf0e10cSrcweir
162cdf0e10cSrcweir // to prefer dictionaries with configuration entries we will only
163cdf0e10cSrcweir // use those old style dictionaries that add a language that
164cdf0e10cSrcweir // is not yet supported by the list od new style dictionaries
165cdf0e10cSrcweir MergeNewStyleDicsAndOldStyleDics( aDics, aOldStyleDics );
166cdf0e10cSrcweir
167cdf0e10cSrcweir numdict = aDics.size();
168cdf0e10cSrcweir if (numdict)
169cdf0e10cSrcweir {
170cdf0e10cSrcweir // get supported locales from the dictionaries-to-use...
171cdf0e10cSrcweir sal_Int32 k = 0;
172cdf0e10cSrcweir std::set< rtl::OUString, lt_rtl_OUString > aLocaleNamesSet;
173cdf0e10cSrcweir std::list< SvtLinguConfigDictionaryEntry >::const_iterator aDictIt;
174cdf0e10cSrcweir for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
175cdf0e10cSrcweir {
176cdf0e10cSrcweir uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
177cdf0e10cSrcweir sal_Int32 nLen2 = aLocaleNames.getLength();
178cdf0e10cSrcweir for (k = 0; k < nLen2; ++k)
179cdf0e10cSrcweir {
180cdf0e10cSrcweir aLocaleNamesSet.insert( aLocaleNames[k] );
181cdf0e10cSrcweir }
182cdf0e10cSrcweir }
183cdf0e10cSrcweir // ... and add them to the resulting sequence
184cdf0e10cSrcweir aSuppLocales.realloc( aLocaleNamesSet.size() );
185cdf0e10cSrcweir std::set< rtl::OUString, lt_rtl_OUString >::const_iterator aItB;
186cdf0e10cSrcweir k = 0;
187cdf0e10cSrcweir for (aItB = aLocaleNamesSet.begin(); aItB != aLocaleNamesSet.end(); ++aItB)
188cdf0e10cSrcweir {
189cdf0e10cSrcweir Locale aTmp( MsLangId::convertLanguageToLocale(
190cdf0e10cSrcweir MsLangId::convertIsoStringToLanguage( *aItB )));
191cdf0e10cSrcweir aSuppLocales[k++] = aTmp;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir
194a893be29SPedro Giffuni //! For each dictionary and each locale we need a separate entry.
195cdf0e10cSrcweir //! If this results in more than one dictionary per locale than (for now)
196cdf0e10cSrcweir //! it is undefined which dictionary gets used.
197cdf0e10cSrcweir //! In the future the implementation should support using several dictionaries
198cdf0e10cSrcweir //! for one locale.
199cdf0e10cSrcweir numdict = 0;
200cdf0e10cSrcweir for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
201cdf0e10cSrcweir numdict = numdict + aDictIt->aLocaleNames.getLength();
202cdf0e10cSrcweir
203cdf0e10cSrcweir // add dictionary information
204cdf0e10cSrcweir aDicts = new HDInfo[numdict];
205cdf0e10cSrcweir
206cdf0e10cSrcweir k = 0;
207cdf0e10cSrcweir for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
208cdf0e10cSrcweir {
209cdf0e10cSrcweir if (aDictIt->aLocaleNames.getLength() > 0 &&
210cdf0e10cSrcweir aDictIt->aLocations.getLength() > 0)
211cdf0e10cSrcweir {
212cdf0e10cSrcweir uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
213cdf0e10cSrcweir sal_Int32 nLocales = aLocaleNames.getLength();
214cdf0e10cSrcweir
215cdf0e10cSrcweir // currently only one language per dictionary is supported in the actual implementation...
216cdf0e10cSrcweir // Thus here we work-around this by adding the same dictionary several times.
217cdf0e10cSrcweir // Once for each of it's supported locales.
218cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLocales; ++i)
219cdf0e10cSrcweir {
220cdf0e10cSrcweir aDicts[k].aPtr = NULL;
221cdf0e10cSrcweir aDicts[k].eEnc = RTL_TEXTENCODING_DONTKNOW;
222cdf0e10cSrcweir aDicts[k].aLoc = MsLangId::convertLanguageToLocale(
223cdf0e10cSrcweir MsLangId::convertIsoStringToLanguage( aDictIt->aLocaleNames[i] ));
224cdf0e10cSrcweir aDicts[k].apCC = new CharClass( aDicts[k].aLoc );
225cdf0e10cSrcweir // also both files have to be in the same directory and the
226cdf0e10cSrcweir // file names must only differ in the extension (.aff/.dic).
227cdf0e10cSrcweir // Thus we use the first location only and strip the extension part.
228cdf0e10cSrcweir rtl::OUString aLocation = aDictIt->aLocations[0];
229cdf0e10cSrcweir sal_Int32 nPos = aLocation.lastIndexOf( '.' );
230cdf0e10cSrcweir aLocation = aLocation.copy( 0, nPos );
231cdf0e10cSrcweir aDicts[k].aName = aLocation;
232cdf0e10cSrcweir
233cdf0e10cSrcweir ++k;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir }
236cdf0e10cSrcweir }
237cdf0e10cSrcweir DBG_ASSERT( k == numdict, "index mismatch?" );
238cdf0e10cSrcweir }
239cdf0e10cSrcweir else
240cdf0e10cSrcweir {
241cdf0e10cSrcweir /* no dictionary found so register no dictionaries */
242cdf0e10cSrcweir numdict = 0;
243cdf0e10cSrcweir aDicts = NULL;
244cdf0e10cSrcweir aSuppLocales.realloc(0);
245cdf0e10cSrcweir }
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
248cdf0e10cSrcweir return aSuppLocales;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir
251cdf0e10cSrcweir
252cdf0e10cSrcweir
hasLocale(const Locale & rLocale)253cdf0e10cSrcweir sal_Bool SAL_CALL Hyphenator::hasLocale(const Locale& rLocale)
254cdf0e10cSrcweir throw(RuntimeException)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
257cdf0e10cSrcweir
258cdf0e10cSrcweir sal_Bool bRes = sal_False;
259cdf0e10cSrcweir if (!aSuppLocales.getLength())
260cdf0e10cSrcweir getLocales();
261cdf0e10cSrcweir
262cdf0e10cSrcweir const Locale *pLocale = aSuppLocales.getConstArray();
263cdf0e10cSrcweir sal_Int32 nLen = aSuppLocales.getLength();
264cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i)
265cdf0e10cSrcweir {
266cdf0e10cSrcweir if (rLocale == pLocale[i])
267cdf0e10cSrcweir {
268cdf0e10cSrcweir bRes = sal_True;
269cdf0e10cSrcweir break;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir }
272cdf0e10cSrcweir return bRes;
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
275cdf0e10cSrcweir
hyphenate(const::rtl::OUString & aWord,const::com::sun::star::lang::Locale & aLocale,sal_Int16 nMaxLeading,const::com::sun::star::beans::PropertyValues & aProperties)276cdf0e10cSrcweir Reference< XHyphenatedWord > SAL_CALL Hyphenator::hyphenate( const ::rtl::OUString& aWord,
277cdf0e10cSrcweir const ::com::sun::star::lang::Locale& aLocale,
278cdf0e10cSrcweir sal_Int16 nMaxLeading,
279cdf0e10cSrcweir const ::com::sun::star::beans::PropertyValues& aProperties )
280cdf0e10cSrcweir throw (com::sun::star::uno::RuntimeException, com::sun::star::lang::IllegalArgumentException)
281cdf0e10cSrcweir {
282cdf0e10cSrcweir int nHyphenationPos = -1;
283cdf0e10cSrcweir int nHyphenationPosAlt = -1;
284cdf0e10cSrcweir int nHyphenationPosAltHyph = -1;
285cdf0e10cSrcweir int wordlen;
286cdf0e10cSrcweir char *hyphens;
287cdf0e10cSrcweir char *lcword;
288cdf0e10cSrcweir int k = 0;
289cdf0e10cSrcweir
290b63233d8Sdamjan PropertyHelper_Hyphenation& rHelper = GetPropHelper();
291cdf0e10cSrcweir rHelper.SetTmpPropVals(aProperties);
292cdf0e10cSrcweir sal_Int16 minTrail = rHelper.GetMinTrailing();
293cdf0e10cSrcweir sal_Int16 minLead = rHelper.GetMinLeading();
294cdf0e10cSrcweir sal_Int16 minLen = rHelper.GetMinWordLength();
295cdf0e10cSrcweir
296cdf0e10cSrcweir HyphenDict *dict = NULL;
297cdf0e10cSrcweir rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
298cdf0e10cSrcweir CharClass * pCC = NULL;
299cdf0e10cSrcweir
300cdf0e10cSrcweir Reference< XHyphenatedWord > xRes;
301cdf0e10cSrcweir
302cdf0e10cSrcweir k = -1;
303cdf0e10cSrcweir for (int j = 0; j < numdict; j++)
304cdf0e10cSrcweir {
305cdf0e10cSrcweir if (aLocale == aDicts[j].aLoc)
306cdf0e10cSrcweir k = j;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
309cdf0e10cSrcweir // if we have a hyphenation dictionary matching this locale
310cdf0e10cSrcweir if (k != -1)
311cdf0e10cSrcweir {
312cdf0e10cSrcweir // if this dictinary has not been loaded yet do that
313cdf0e10cSrcweir if (!aDicts[k].aPtr)
314cdf0e10cSrcweir {
315cdf0e10cSrcweir OUString DictFN = aDicts[k].aName + A2OU(".dic");
316cdf0e10cSrcweir OUString dictpath;
317cdf0e10cSrcweir
318cdf0e10cSrcweir osl::FileBase::getSystemPathFromFileURL( DictFN, dictpath );
319cdf0e10cSrcweir OString sTmp( OU2ENC( dictpath, osl_getThreadTextEncoding() ) );
320cdf0e10cSrcweir
321cdf0e10cSrcweir #if defined(WNT)
322cdf0e10cSrcweir // workaround for Windows specifc problem that the
323cdf0e10cSrcweir // path length in calls to 'fopen' is limted to somewhat
324cdf0e10cSrcweir // about 120+ characters which will usually be exceed when
325cdf0e10cSrcweir // using dictionaries as extensions.
326cdf0e10cSrcweir sTmp = Win_GetShortPathName( dictpath );
327cdf0e10cSrcweir #endif
328cdf0e10cSrcweir
329cdf0e10cSrcweir if ( ( dict = hnj_hyphen_load ( sTmp.getStr()) ) == NULL )
330cdf0e10cSrcweir {
331cdf0e10cSrcweir fprintf(stderr, "Couldn't find file %s\n", OU2ENC(dictpath, osl_getThreadTextEncoding()) );
332cdf0e10cSrcweir return NULL;
333cdf0e10cSrcweir }
334cdf0e10cSrcweir aDicts[k].aPtr = dict;
335cdf0e10cSrcweir aDicts[k].eEnc = getTextEncodingFromCharset(dict->cset);
336cdf0e10cSrcweir }
337cdf0e10cSrcweir
338cdf0e10cSrcweir // other wise hyphenate the word with that dictionary
339cdf0e10cSrcweir dict = aDicts[k].aPtr;
340cdf0e10cSrcweir eEnc = aDicts[k].eEnc;
341cdf0e10cSrcweir pCC = aDicts[k].apCC;
342cdf0e10cSrcweir
343cdf0e10cSrcweir // we don't want to work with a default text encoding since following incorrect
344cdf0e10cSrcweir // results may occur only for specific text and thus may be hard to notice.
345cdf0e10cSrcweir // Thus better always make a clean exit here if the text encoding is in question.
346cdf0e10cSrcweir // Hopefully something not working at all will raise proper attention quickly. ;-)
347cdf0e10cSrcweir DBG_ASSERT( eEnc != RTL_TEXTENCODING_DONTKNOW, "failed to get text encoding! (maybe incorrect encoding string in file)" );
348cdf0e10cSrcweir if (eEnc == RTL_TEXTENCODING_DONTKNOW)
349cdf0e10cSrcweir return NULL;
350cdf0e10cSrcweir
351cdf0e10cSrcweir sal_uInt16 ct = CAPTYPE_UNKNOWN;
352cdf0e10cSrcweir ct = capitalType(aWord, pCC);
353cdf0e10cSrcweir
354cdf0e10cSrcweir // first convert any smart quotes or apostrophes to normal ones
355cdf0e10cSrcweir OUStringBuffer rBuf(aWord);
356cdf0e10cSrcweir sal_Int32 nc = rBuf.getLength();
357cdf0e10cSrcweir sal_Unicode ch;
358cdf0e10cSrcweir for (sal_Int32 ix=0; ix < nc; ix++)
359cdf0e10cSrcweir {
360cdf0e10cSrcweir ch = rBuf.charAt(ix);
361cdf0e10cSrcweir if ((ch == 0x201C) || (ch == 0x201D))
362cdf0e10cSrcweir rBuf.setCharAt(ix,(sal_Unicode)0x0022);
363cdf0e10cSrcweir if ((ch == 0x2018) || (ch == 0x2019))
364cdf0e10cSrcweir rBuf.setCharAt(ix,(sal_Unicode)0x0027);
365cdf0e10cSrcweir }
366cdf0e10cSrcweir OUString nWord(rBuf.makeStringAndClear());
367cdf0e10cSrcweir
368cdf0e10cSrcweir // now convert word to all lowercase for pattern recognition
369cdf0e10cSrcweir OUString nTerm(makeLowerCase(nWord, pCC));
370cdf0e10cSrcweir
371cdf0e10cSrcweir // now convert word to needed encoding
372cdf0e10cSrcweir OString encWord(OU2ENC(nTerm,eEnc));
373cdf0e10cSrcweir
374cdf0e10cSrcweir wordlen = encWord.getLength();
375cdf0e10cSrcweir lcword = new char[wordlen + 1];
376cdf0e10cSrcweir hyphens = new char[wordlen + 5];
377cdf0e10cSrcweir
378cdf0e10cSrcweir char ** rep = NULL; // replacements of discretionary hyphenation
379cdf0e10cSrcweir int * pos = NULL; // array of [hyphenation point] minus [deletion position]
380cdf0e10cSrcweir int * cut = NULL; // length of deletions in original word
381cdf0e10cSrcweir
382cdf0e10cSrcweir // copy converted word into simple char buffer
383cdf0e10cSrcweir strcpy(lcword,encWord.getStr());
384cdf0e10cSrcweir
385cdf0e10cSrcweir // now strip off any ending periods
386cdf0e10cSrcweir int n = wordlen-1;
387cdf0e10cSrcweir while((n >=0) && (lcword[n] == '.'))
388cdf0e10cSrcweir n--;
389cdf0e10cSrcweir n++;
390cdf0e10cSrcweir if (n > 0)
391cdf0e10cSrcweir {
392cdf0e10cSrcweir const bool bFailed = 0 != hnj_hyphen_hyphenate3( dict, lcword, n, hyphens, NULL,
393cdf0e10cSrcweir &rep, &pos, &cut, minLead, minTrail,
394cdf0e10cSrcweir Max(dict->clhmin, Max(dict->clhmin, 2) + Max(0, minLead - Max(dict->lhmin, 2))),
395cdf0e10cSrcweir Max(dict->crhmin, Max(dict->crhmin, 2) + Max(0, minTrail - Max(dict->rhmin, 2))) );
396cdf0e10cSrcweir if (bFailed)
397cdf0e10cSrcweir {
398cdf0e10cSrcweir //whoops something did not work
399cdf0e10cSrcweir delete[] hyphens;
400cdf0e10cSrcweir delete[] lcword;
401cdf0e10cSrcweir if (rep)
402cdf0e10cSrcweir {
403cdf0e10cSrcweir for(int j = 0; j < n; j++)
404cdf0e10cSrcweir {
405cdf0e10cSrcweir if (rep[j]) free(rep[j]);
406cdf0e10cSrcweir }
407cdf0e10cSrcweir free(rep);
408cdf0e10cSrcweir }
409cdf0e10cSrcweir if (pos) free(pos);
410cdf0e10cSrcweir if (cut) free(cut);
411cdf0e10cSrcweir return NULL;
412cdf0e10cSrcweir }
413cdf0e10cSrcweir }
414cdf0e10cSrcweir
415cdf0e10cSrcweir // now backfill hyphens[] for any removed trailing periods
416cdf0e10cSrcweir for (int c = n; c < wordlen; c++) hyphens[c] = '0';
417cdf0e10cSrcweir hyphens[wordlen] = '\0';
418cdf0e10cSrcweir
419cdf0e10cSrcweir sal_Int32 Leading = GetPosInWordToCheck( aWord, nMaxLeading );
420cdf0e10cSrcweir
421cdf0e10cSrcweir for (sal_Int32 i = 0; i < n; i++)
422cdf0e10cSrcweir {
423cdf0e10cSrcweir int leftrep = 0;
424cdf0e10cSrcweir sal_Bool hit = (n >= minLen);
425cdf0e10cSrcweir if (!rep || !rep[i] || (i >= n))
426cdf0e10cSrcweir {
427cdf0e10cSrcweir hit = hit && (hyphens[i]&1) && (i < Leading);
428cdf0e10cSrcweir hit = hit && (i >= (minLead-1) );
429cdf0e10cSrcweir hit = hit && ((n - i - 1) >= minTrail);
430cdf0e10cSrcweir }
431cdf0e10cSrcweir else
432cdf0e10cSrcweir {
433cdf0e10cSrcweir // calculate change character length before hyphenation point signed with '='
434cdf0e10cSrcweir for (char * c = rep[i]; *c && (*c != '='); c++)
435cdf0e10cSrcweir {
436cdf0e10cSrcweir if (eEnc == RTL_TEXTENCODING_UTF8)
437cdf0e10cSrcweir {
438cdf0e10cSrcweir if (((unsigned char) *c) >> 6 != 2)
439cdf0e10cSrcweir leftrep++;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir else
442cdf0e10cSrcweir leftrep++;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir hit = hit && (hyphens[i]&1) && ((i + leftrep - pos[i]) < Leading);
445cdf0e10cSrcweir hit = hit && ((i + leftrep - pos[i]) >= (minLead-1) );
446cdf0e10cSrcweir hit = hit && ((n - i - 1 + sal::static_int_cast< sal_sSize >(strlen(rep[i])) - leftrep - 1) >= minTrail);
447cdf0e10cSrcweir }
448cdf0e10cSrcweir if (hit)
449cdf0e10cSrcweir {
450cdf0e10cSrcweir nHyphenationPos = i;
451cdf0e10cSrcweir if (rep && (i < n) && rep[i])
452cdf0e10cSrcweir {
453cdf0e10cSrcweir nHyphenationPosAlt = i - pos[i];
454cdf0e10cSrcweir nHyphenationPosAltHyph = i + leftrep - pos[i];
455cdf0e10cSrcweir }
456cdf0e10cSrcweir }
457cdf0e10cSrcweir }
458cdf0e10cSrcweir
459cdf0e10cSrcweir if (nHyphenationPos == -1)
460cdf0e10cSrcweir {
461cdf0e10cSrcweir xRes = NULL;
462cdf0e10cSrcweir }
463cdf0e10cSrcweir else
464cdf0e10cSrcweir {
465cdf0e10cSrcweir if (rep && rep[nHyphenationPos])
466cdf0e10cSrcweir {
467cdf0e10cSrcweir // remove equal sign
468cdf0e10cSrcweir char * s = rep[nHyphenationPos];
469cdf0e10cSrcweir int eq = 0;
470cdf0e10cSrcweir for (; *s; s++)
471cdf0e10cSrcweir {
472cdf0e10cSrcweir if (*s == '=') eq = 1;
473cdf0e10cSrcweir if (eq) *s = *(s + 1);
474cdf0e10cSrcweir }
475cdf0e10cSrcweir OUString repHyphlow(rep[nHyphenationPos], strlen(rep[nHyphenationPos]), eEnc);
476cdf0e10cSrcweir OUString repHyph;
477cdf0e10cSrcweir switch (ct)
478cdf0e10cSrcweir {
479cdf0e10cSrcweir case CAPTYPE_ALLCAP:
480cdf0e10cSrcweir {
481cdf0e10cSrcweir repHyph = makeUpperCase(repHyphlow, pCC);
482cdf0e10cSrcweir break;
483cdf0e10cSrcweir }
484cdf0e10cSrcweir case CAPTYPE_INITCAP:
485cdf0e10cSrcweir {
486cdf0e10cSrcweir if (nHyphenationPosAlt == 0)
487cdf0e10cSrcweir repHyph = makeInitCap(repHyphlow, pCC);
488cdf0e10cSrcweir else
489cdf0e10cSrcweir repHyph = repHyphlow;
490cdf0e10cSrcweir break;
491cdf0e10cSrcweir }
492cdf0e10cSrcweir default:
493cdf0e10cSrcweir {
494cdf0e10cSrcweir repHyph = repHyphlow;
495cdf0e10cSrcweir break;
496cdf0e10cSrcweir }
497cdf0e10cSrcweir }
498cdf0e10cSrcweir
499cdf0e10cSrcweir // handle shortening
500cdf0e10cSrcweir sal_Int16 nPos = (sal_Int16) ((nHyphenationPosAltHyph < nHyphenationPos) ?
501cdf0e10cSrcweir nHyphenationPosAltHyph : nHyphenationPos);
502cdf0e10cSrcweir // dicretionary hyphenation
503b63233d8Sdamjan xRes = HyphenatedWord::CreateHyphenatedWord( aWord, LocaleToLanguage( aLocale ), nPos,
504cdf0e10cSrcweir aWord.replaceAt(nHyphenationPosAlt + 1, cut[nHyphenationPos], repHyph),
505cdf0e10cSrcweir (sal_Int16) nHyphenationPosAltHyph);
506cdf0e10cSrcweir }
507cdf0e10cSrcweir else
508cdf0e10cSrcweir {
509b63233d8Sdamjan xRes = HyphenatedWord::CreateHyphenatedWord( aWord, LocaleToLanguage( aLocale ),
510cdf0e10cSrcweir (sal_Int16)nHyphenationPos, aWord, (sal_Int16) nHyphenationPos);
511cdf0e10cSrcweir }
512cdf0e10cSrcweir }
513cdf0e10cSrcweir
514cdf0e10cSrcweir delete[] lcword;
515cdf0e10cSrcweir delete[] hyphens;
516cdf0e10cSrcweir if (rep)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir for(int j = 0; j < n; j++)
519cdf0e10cSrcweir {
520cdf0e10cSrcweir if (rep[j]) free(rep[j]);
521cdf0e10cSrcweir }
522cdf0e10cSrcweir free(rep);
523cdf0e10cSrcweir }
524cdf0e10cSrcweir if (pos) free(pos);
525cdf0e10cSrcweir if (cut) free(cut);
526cdf0e10cSrcweir return xRes;
527cdf0e10cSrcweir }
528cdf0e10cSrcweir return NULL;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir
531cdf0e10cSrcweir
queryAlternativeSpelling(const::rtl::OUString &,const::com::sun::star::lang::Locale &,sal_Int16,const::com::sun::star::beans::PropertyValues &)532cdf0e10cSrcweir Reference < XHyphenatedWord > SAL_CALL Hyphenator::queryAlternativeSpelling(
533cdf0e10cSrcweir const ::rtl::OUString& /*aWord*/,
534cdf0e10cSrcweir const ::com::sun::star::lang::Locale& /*aLocale*/,
535cdf0e10cSrcweir sal_Int16 /*nIndex*/,
536cdf0e10cSrcweir const ::com::sun::star::beans::PropertyValues& /*aProperties*/ )
537cdf0e10cSrcweir throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
538cdf0e10cSrcweir {
539cdf0e10cSrcweir /* alternative spelling isn't supported by tex dictionaries */
540cdf0e10cSrcweir /* XXX: OOo's extended libhjn algorithm can support alternative spellings with extended TeX dic. */
541cdf0e10cSrcweir /* TASK: implement queryAlternativeSpelling() */
542cdf0e10cSrcweir return NULL;
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
createPossibleHyphens(const::rtl::OUString & aWord,const::com::sun::star::lang::Locale & aLocale,const::com::sun::star::beans::PropertyValues & aProperties)545cdf0e10cSrcweir Reference< XPossibleHyphens > SAL_CALL Hyphenator::createPossibleHyphens( const ::rtl::OUString& aWord,
546cdf0e10cSrcweir const ::com::sun::star::lang::Locale& aLocale,
547cdf0e10cSrcweir const ::com::sun::star::beans::PropertyValues& aProperties )
548cdf0e10cSrcweir throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir int wordlen;
551cdf0e10cSrcweir char *hyphens;
552cdf0e10cSrcweir char *lcword;
553cdf0e10cSrcweir int k;
554cdf0e10cSrcweir
555b63233d8Sdamjan PropertyHelper_Hyphenation& rHelper = GetPropHelper();
556cdf0e10cSrcweir rHelper.SetTmpPropVals(aProperties);
557cdf0e10cSrcweir sal_Int16 minTrail = rHelper.GetMinTrailing();
558cdf0e10cSrcweir sal_Int16 minLead = rHelper.GetMinLeading();
559cdf0e10cSrcweir
560cdf0e10cSrcweir HyphenDict *dict = NULL;
561cdf0e10cSrcweir rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
562cdf0e10cSrcweir CharClass* pCC = NULL;
563cdf0e10cSrcweir
564cdf0e10cSrcweir Reference< XPossibleHyphens > xRes;
565cdf0e10cSrcweir
566cdf0e10cSrcweir k = -1;
567cdf0e10cSrcweir for (int j = 0; j < numdict; j++)
568cdf0e10cSrcweir {
569cdf0e10cSrcweir if (aLocale == aDicts[j].aLoc) k = j;
570cdf0e10cSrcweir }
571cdf0e10cSrcweir
572cdf0e10cSrcweir // if we have a hyphenation dictionary matching this locale
573cdf0e10cSrcweir if (k != -1)
574cdf0e10cSrcweir {
575cdf0e10cSrcweir // if this dictioanry has not been loaded yet do that
576cdf0e10cSrcweir if (!aDicts[k].aPtr)
577cdf0e10cSrcweir {
578cdf0e10cSrcweir OUString DictFN = aDicts[k].aName + A2OU(".dic");
579cdf0e10cSrcweir OUString dictpath;
580cdf0e10cSrcweir
581cdf0e10cSrcweir osl::FileBase::getSystemPathFromFileURL( DictFN, dictpath );
582cdf0e10cSrcweir OString sTmp( OU2ENC( dictpath, osl_getThreadTextEncoding() ) );
583cdf0e10cSrcweir
584cdf0e10cSrcweir #if defined(WNT)
585cdf0e10cSrcweir // workaround for Windows specifc problem that the
586cdf0e10cSrcweir // path length in calls to 'fopen' is limted to somewhat
587cdf0e10cSrcweir // about 120+ characters which will usually be exceed when
588cdf0e10cSrcweir // using dictionaries as extensions.
589cdf0e10cSrcweir sTmp = Win_GetShortPathName( dictpath );
590cdf0e10cSrcweir #endif
591cdf0e10cSrcweir
592cdf0e10cSrcweir if ( ( dict = hnj_hyphen_load ( sTmp.getStr()) ) == NULL )
593cdf0e10cSrcweir {
594cdf0e10cSrcweir fprintf(stderr, "Couldn't find file %s and %s\n", sTmp.getStr(), OU2ENC(dictpath, osl_getThreadTextEncoding()) );
595cdf0e10cSrcweir return NULL;
596cdf0e10cSrcweir }
597cdf0e10cSrcweir aDicts[k].aPtr = dict;
598cdf0e10cSrcweir aDicts[k].eEnc = getTextEncodingFromCharset(dict->cset);
599cdf0e10cSrcweir }
600cdf0e10cSrcweir
601cdf0e10cSrcweir // other wise hyphenate the word with that dictionary
602cdf0e10cSrcweir dict = aDicts[k].aPtr;
603cdf0e10cSrcweir eEnc = aDicts[k].eEnc;
604cdf0e10cSrcweir pCC = aDicts[k].apCC;
605cdf0e10cSrcweir
606cdf0e10cSrcweir // we don't want to work with a default text encoding since following incorrect
607cdf0e10cSrcweir // results may occur only for specific text and thus may be hard to notice.
608cdf0e10cSrcweir // Thus better always make a clean exit here if the text encoding is in question.
609cdf0e10cSrcweir // Hopefully something not working at all will raise proper attention quickly. ;-)
610cdf0e10cSrcweir DBG_ASSERT( eEnc != RTL_TEXTENCODING_DONTKNOW, "failed to get text encoding! (maybe incorrect encoding string in file)" );
611cdf0e10cSrcweir if (eEnc == RTL_TEXTENCODING_DONTKNOW)
612cdf0e10cSrcweir return NULL;
613cdf0e10cSrcweir
614cdf0e10cSrcweir // first handle smart quotes both single and double
615cdf0e10cSrcweir OUStringBuffer rBuf(aWord);
616cdf0e10cSrcweir sal_Int32 nc = rBuf.getLength();
617cdf0e10cSrcweir sal_Unicode ch;
618cdf0e10cSrcweir for (sal_Int32 ix=0; ix < nc; ix++)
619cdf0e10cSrcweir {
620cdf0e10cSrcweir ch = rBuf.charAt(ix);
621cdf0e10cSrcweir if ((ch == 0x201C) || (ch == 0x201D))
622cdf0e10cSrcweir rBuf.setCharAt(ix,(sal_Unicode)0x0022);
623cdf0e10cSrcweir if ((ch == 0x2018) || (ch == 0x2019))
624cdf0e10cSrcweir rBuf.setCharAt(ix,(sal_Unicode)0x0027);
625cdf0e10cSrcweir }
626cdf0e10cSrcweir OUString nWord(rBuf.makeStringAndClear());
627cdf0e10cSrcweir
628cdf0e10cSrcweir // now convert word to all lowercase for pattern recognition
629cdf0e10cSrcweir OUString nTerm(makeLowerCase(nWord, pCC));
630cdf0e10cSrcweir
631cdf0e10cSrcweir // now convert word to needed encoding
632cdf0e10cSrcweir OString encWord(OU2ENC(nTerm,eEnc));
633cdf0e10cSrcweir
634cdf0e10cSrcweir wordlen = encWord.getLength();
635cdf0e10cSrcweir lcword = new char[wordlen+1];
636cdf0e10cSrcweir hyphens = new char[wordlen+5];
637cdf0e10cSrcweir char ** rep = NULL; // replacements of discretionary hyphenation
638cdf0e10cSrcweir int * pos = NULL; // array of [hyphenation point] minus [deletion position]
639cdf0e10cSrcweir int * cut = NULL; // length of deletions in original word
640cdf0e10cSrcweir
641cdf0e10cSrcweir // copy converted word into simple char buffer
642cdf0e10cSrcweir strcpy(lcword,encWord.getStr());
643cdf0e10cSrcweir
644cdf0e10cSrcweir // first remove any trailing periods
645cdf0e10cSrcweir int n = wordlen-1;
646cdf0e10cSrcweir while((n >=0) && (lcword[n] == '.'))
647cdf0e10cSrcweir n--;
648cdf0e10cSrcweir n++;
649cdf0e10cSrcweir // fprintf(stderr,"hyphenate... %s\n",lcword); fflush(stderr);
650cdf0e10cSrcweir if (n > 0)
651cdf0e10cSrcweir {
652cdf0e10cSrcweir const bool bFailed = 0 != hnj_hyphen_hyphenate3(dict, lcword, n, hyphens, NULL,
653cdf0e10cSrcweir &rep, &pos, &cut, minLead, minTrail,
654cdf0e10cSrcweir Max(dict->clhmin, Max(dict->clhmin, 2) + Max(0, minLead - Max(dict->lhmin, 2))),
655cdf0e10cSrcweir Max(dict->crhmin, Max(dict->crhmin, 2) + Max(0, minTrail - Max(dict->rhmin, 2))) );
656cdf0e10cSrcweir if (bFailed)
657cdf0e10cSrcweir {
658cdf0e10cSrcweir delete[] hyphens;
659cdf0e10cSrcweir delete[] lcword;
660cdf0e10cSrcweir
661cdf0e10cSrcweir if (rep)
662cdf0e10cSrcweir {
663cdf0e10cSrcweir for(int j = 0; j < n; j++)
664cdf0e10cSrcweir {
665cdf0e10cSrcweir if (rep[j]) free(rep[j]);
666cdf0e10cSrcweir }
667cdf0e10cSrcweir free(rep);
668cdf0e10cSrcweir }
669cdf0e10cSrcweir if (pos) free(pos);
670cdf0e10cSrcweir if (cut) free(cut);
671cdf0e10cSrcweir
672cdf0e10cSrcweir return NULL;
673cdf0e10cSrcweir }
674cdf0e10cSrcweir }
675cdf0e10cSrcweir // now backfill hyphens[] for any removed periods
676cdf0e10cSrcweir for (int c = n; c < wordlen; c++)
677cdf0e10cSrcweir hyphens[c] = '0';
678cdf0e10cSrcweir hyphens[wordlen] = '\0';
679cdf0e10cSrcweir // fprintf(stderr,"... %s\n",hyphens); fflush(stderr);
680cdf0e10cSrcweir
681cdf0e10cSrcweir sal_Int16 nHyphCount = 0;
682cdf0e10cSrcweir sal_Int16 i;
683cdf0e10cSrcweir
684cdf0e10cSrcweir for ( i = 0; i < encWord.getLength(); i++)
685cdf0e10cSrcweir {
686cdf0e10cSrcweir if (hyphens[i]&1 && (!rep || !rep[i]))
687cdf0e10cSrcweir nHyphCount++;
688cdf0e10cSrcweir }
689cdf0e10cSrcweir
690cdf0e10cSrcweir Sequence< sal_Int16 > aHyphPos(nHyphCount);
691cdf0e10cSrcweir sal_Int16 *pPos = aHyphPos.getArray();
692cdf0e10cSrcweir OUStringBuffer hyphenatedWordBuffer;
693cdf0e10cSrcweir OUString hyphenatedWord;
694cdf0e10cSrcweir nHyphCount = 0;
695cdf0e10cSrcweir
696cdf0e10cSrcweir for (i = 0; i < nWord.getLength(); i++)
697cdf0e10cSrcweir {
698cdf0e10cSrcweir hyphenatedWordBuffer.append(aWord[i]);
699cdf0e10cSrcweir // hyphenation position (not alternative)
700cdf0e10cSrcweir if (hyphens[i]&1 && (!rep || !rep[i]))
701cdf0e10cSrcweir {
702cdf0e10cSrcweir pPos[nHyphCount] = i;
703cdf0e10cSrcweir hyphenatedWordBuffer.append(sal_Unicode('='));
704cdf0e10cSrcweir nHyphCount++;
705cdf0e10cSrcweir }
706cdf0e10cSrcweir }
707cdf0e10cSrcweir
708cdf0e10cSrcweir hyphenatedWord = hyphenatedWordBuffer.makeStringAndClear();
709cdf0e10cSrcweir //fprintf(stderr,"result is %s\n",OU2A(hyphenatedWord));
710cdf0e10cSrcweir //fflush(stderr);
711cdf0e10cSrcweir
712b63233d8Sdamjan xRes = PossibleHyphens::CreatePossibleHyphens( aWord, LocaleToLanguage( aLocale ),
713cdf0e10cSrcweir hyphenatedWord, aHyphPos );
714cdf0e10cSrcweir
715cdf0e10cSrcweir delete[] hyphens;
716cdf0e10cSrcweir delete[] lcword;
717cdf0e10cSrcweir
718cdf0e10cSrcweir if (rep)
719cdf0e10cSrcweir {
720cdf0e10cSrcweir for(int j = 0; j < n; j++)
721cdf0e10cSrcweir {
722cdf0e10cSrcweir if (rep[j]) free(rep[j]);
723cdf0e10cSrcweir }
724cdf0e10cSrcweir free(rep);
725cdf0e10cSrcweir }
726cdf0e10cSrcweir if (pos) free(pos);
727cdf0e10cSrcweir if (cut) free(cut);
728cdf0e10cSrcweir
729cdf0e10cSrcweir return xRes;
730cdf0e10cSrcweir }
731cdf0e10cSrcweir
732cdf0e10cSrcweir return NULL;
733cdf0e10cSrcweir }
734cdf0e10cSrcweir
capitalType(const OUString & aTerm,CharClass * pCC)735cdf0e10cSrcweir sal_uInt16 SAL_CALL Hyphenator::capitalType(const OUString& aTerm, CharClass * pCC)
736cdf0e10cSrcweir {
737cdf0e10cSrcweir sal_Int32 tlen = aTerm.getLength();
738cdf0e10cSrcweir if ((pCC) && (tlen))
739cdf0e10cSrcweir {
740cdf0e10cSrcweir String aStr(aTerm);
741cdf0e10cSrcweir sal_Int32 nc = 0;
742cdf0e10cSrcweir for (xub_StrLen tindex = 0; tindex < tlen; tindex++)
743cdf0e10cSrcweir {
744cdf0e10cSrcweir if (pCC->getCharacterType(aStr,tindex) & ::com::sun::star::i18n::KCharacterType::UPPER)
745cdf0e10cSrcweir nc++;
746cdf0e10cSrcweir }
747cdf0e10cSrcweir
748cdf0e10cSrcweir if (nc == 0)
749cdf0e10cSrcweir return (sal_uInt16) CAPTYPE_NOCAP;
750cdf0e10cSrcweir if (nc == tlen)
751cdf0e10cSrcweir return (sal_uInt16) CAPTYPE_ALLCAP;
752cdf0e10cSrcweir if ((nc == 1) && (pCC->getCharacterType(aStr,0) & ::com::sun::star::i18n::KCharacterType::UPPER))
753cdf0e10cSrcweir return (sal_uInt16) CAPTYPE_INITCAP;
754cdf0e10cSrcweir
755cdf0e10cSrcweir return (sal_uInt16) CAPTYPE_MIXED;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir return (sal_uInt16) CAPTYPE_UNKNOWN;
758cdf0e10cSrcweir }
759cdf0e10cSrcweir
makeLowerCase(const OUString & aTerm,CharClass * pCC)760cdf0e10cSrcweir OUString SAL_CALL Hyphenator::makeLowerCase(const OUString& aTerm, CharClass * pCC)
761cdf0e10cSrcweir {
762cdf0e10cSrcweir if (pCC)
763cdf0e10cSrcweir return pCC->toLower_rtl(aTerm, 0, aTerm.getLength());
764cdf0e10cSrcweir return aTerm;
765cdf0e10cSrcweir }
766cdf0e10cSrcweir
makeUpperCase(const OUString & aTerm,CharClass * pCC)767cdf0e10cSrcweir OUString SAL_CALL Hyphenator::makeUpperCase(const OUString& aTerm, CharClass * pCC)
768cdf0e10cSrcweir {
769cdf0e10cSrcweir if (pCC)
770cdf0e10cSrcweir return pCC->toUpper_rtl(aTerm, 0, aTerm.getLength());
771cdf0e10cSrcweir return aTerm;
772cdf0e10cSrcweir }
773cdf0e10cSrcweir
774cdf0e10cSrcweir
makeInitCap(const OUString & aTerm,CharClass * pCC)775cdf0e10cSrcweir OUString SAL_CALL Hyphenator::makeInitCap(const OUString& aTerm, CharClass * pCC)
776cdf0e10cSrcweir {
777cdf0e10cSrcweir sal_Int32 tlen = aTerm.getLength();
778cdf0e10cSrcweir if ((pCC) && (tlen))
779cdf0e10cSrcweir {
780cdf0e10cSrcweir OUString bTemp = aTerm.copy(0,1);
781cdf0e10cSrcweir if (tlen > 1)
782cdf0e10cSrcweir return ( pCC->toUpper_rtl(bTemp, 0, 1) + pCC->toLower_rtl(aTerm,1,(tlen-1)) );
783cdf0e10cSrcweir
784cdf0e10cSrcweir return pCC->toUpper_rtl(bTemp, 0, 1);
785cdf0e10cSrcweir }
786cdf0e10cSrcweir return aTerm;
787cdf0e10cSrcweir }
788cdf0e10cSrcweir
789cdf0e10cSrcweir
Hyphenator_CreateInstance(const Reference<XMultiServiceFactory> &)790cdf0e10cSrcweir Reference< XInterface > SAL_CALL Hyphenator_CreateInstance(
791cdf0e10cSrcweir const Reference< XMultiServiceFactory > & /*rSMgr*/ )
792cdf0e10cSrcweir throw(Exception)
793cdf0e10cSrcweir {
794cdf0e10cSrcweir Reference< XInterface > xService = (cppu::OWeakObject*) new Hyphenator;
795cdf0e10cSrcweir return xService;
796cdf0e10cSrcweir }
797cdf0e10cSrcweir
798cdf0e10cSrcweir
addLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxLstnr)799cdf0e10cSrcweir sal_Bool SAL_CALL Hyphenator::addLinguServiceEventListener(
800cdf0e10cSrcweir const Reference< XLinguServiceEventListener >& rxLstnr )
801cdf0e10cSrcweir throw(RuntimeException)
802cdf0e10cSrcweir {
803cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
804cdf0e10cSrcweir
805cdf0e10cSrcweir sal_Bool bRes = sal_False;
806cdf0e10cSrcweir if (!bDisposing && rxLstnr.is())
807cdf0e10cSrcweir {
808cdf0e10cSrcweir bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr );
809cdf0e10cSrcweir }
810cdf0e10cSrcweir return bRes;
811cdf0e10cSrcweir }
812cdf0e10cSrcweir
813cdf0e10cSrcweir
removeLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxLstnr)814cdf0e10cSrcweir sal_Bool SAL_CALL Hyphenator::removeLinguServiceEventListener(
815cdf0e10cSrcweir const Reference< XLinguServiceEventListener >& rxLstnr )
816cdf0e10cSrcweir throw(RuntimeException)
817cdf0e10cSrcweir {
818cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
819cdf0e10cSrcweir
820cdf0e10cSrcweir sal_Bool bRes = sal_False;
821cdf0e10cSrcweir if (!bDisposing && rxLstnr.is())
822cdf0e10cSrcweir {
823cdf0e10cSrcweir bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr );
824cdf0e10cSrcweir }
825cdf0e10cSrcweir return bRes;
826cdf0e10cSrcweir }
827cdf0e10cSrcweir
828cdf0e10cSrcweir
getServiceDisplayName(const Locale &)829cdf0e10cSrcweir OUString SAL_CALL Hyphenator::getServiceDisplayName( const Locale& /*rLocale*/ )
830cdf0e10cSrcweir throw(RuntimeException)
831cdf0e10cSrcweir {
832cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
833cdf0e10cSrcweir return A2OU( "Libhyphen Hyphenator" );
834cdf0e10cSrcweir }
835cdf0e10cSrcweir
836cdf0e10cSrcweir
initialize(const Sequence<Any> & rArguments)837cdf0e10cSrcweir void SAL_CALL Hyphenator::initialize( const Sequence< Any >& rArguments )
838cdf0e10cSrcweir throw(Exception, RuntimeException)
839cdf0e10cSrcweir {
840cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
841cdf0e10cSrcweir
842cdf0e10cSrcweir if (!pPropHelper)
843cdf0e10cSrcweir {
844cdf0e10cSrcweir sal_Int32 nLen = rArguments.getLength();
845cdf0e10cSrcweir if (2 == nLen)
846cdf0e10cSrcweir {
847cdf0e10cSrcweir Reference< XPropertySet > xPropSet;
848cdf0e10cSrcweir rArguments.getConstArray()[0] >>= xPropSet;
849cdf0e10cSrcweir //rArguments.getConstArray()[1] >>= xDicList;
850cdf0e10cSrcweir
851cdf0e10cSrcweir //! Pointer allows for access of the non-UNO functions.
852cdf0e10cSrcweir //! And the reference to the UNO-functions while increasing
853cdf0e10cSrcweir //! the ref-count and will implicitly free the memory
854cdf0e10cSrcweir //! when the object is not longer used.
855b63233d8Sdamjan pPropHelper = new PropertyHelper_Hyphenation( (XHyphenator *) this, xPropSet );
856cdf0e10cSrcweir pPropHelper->AddAsPropListener(); //! after a reference is established
857cdf0e10cSrcweir }
858cdf0e10cSrcweir else
859cdf0e10cSrcweir {
860cdf0e10cSrcweir DBG_ERROR( "wrong number of arguments in sequence" );
861cdf0e10cSrcweir }
862cdf0e10cSrcweir }
863cdf0e10cSrcweir }
864cdf0e10cSrcweir
865cdf0e10cSrcweir
dispose()866cdf0e10cSrcweir void SAL_CALL Hyphenator::dispose()
867cdf0e10cSrcweir throw(RuntimeException)
868cdf0e10cSrcweir {
869cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
870cdf0e10cSrcweir
871cdf0e10cSrcweir if (!bDisposing)
872cdf0e10cSrcweir {
873cdf0e10cSrcweir bDisposing = sal_True;
874cdf0e10cSrcweir EventObject aEvtObj( (XHyphenator *) this );
875cdf0e10cSrcweir aEvtListeners.disposeAndClear( aEvtObj );
876cdf0e10cSrcweir }
877cdf0e10cSrcweir }
878cdf0e10cSrcweir
879cdf0e10cSrcweir
addEventListener(const Reference<XEventListener> & rxListener)880cdf0e10cSrcweir void SAL_CALL Hyphenator::addEventListener( const Reference< XEventListener >& rxListener )
881cdf0e10cSrcweir throw(RuntimeException)
882cdf0e10cSrcweir {
883cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
884cdf0e10cSrcweir
885cdf0e10cSrcweir if (!bDisposing && rxListener.is())
886cdf0e10cSrcweir aEvtListeners.addInterface( rxListener );
887cdf0e10cSrcweir }
888cdf0e10cSrcweir
889cdf0e10cSrcweir
removeEventListener(const Reference<XEventListener> & rxListener)890cdf0e10cSrcweir void SAL_CALL Hyphenator::removeEventListener( const Reference< XEventListener >& rxListener )
891cdf0e10cSrcweir throw(RuntimeException)
892cdf0e10cSrcweir {
893cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
894cdf0e10cSrcweir
895cdf0e10cSrcweir if (!bDisposing && rxListener.is())
896cdf0e10cSrcweir aEvtListeners.removeInterface( rxListener );
897cdf0e10cSrcweir }
898cdf0e10cSrcweir
899cdf0e10cSrcweir
900cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
901cdf0e10cSrcweir // Service specific part
902cdf0e10cSrcweir //
903cdf0e10cSrcweir
getImplementationName()904cdf0e10cSrcweir OUString SAL_CALL Hyphenator::getImplementationName()
905cdf0e10cSrcweir throw(RuntimeException)
906cdf0e10cSrcweir {
907cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
908cdf0e10cSrcweir
909cdf0e10cSrcweir return getImplementationName_Static();
910cdf0e10cSrcweir }
911cdf0e10cSrcweir
912cdf0e10cSrcweir
supportsService(const OUString & ServiceName)913cdf0e10cSrcweir sal_Bool SAL_CALL Hyphenator::supportsService( const OUString& ServiceName )
914cdf0e10cSrcweir throw(RuntimeException)
915cdf0e10cSrcweir {
916cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
917cdf0e10cSrcweir
918cdf0e10cSrcweir Sequence< OUString > aSNL = getSupportedServiceNames();
919cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray();
920cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
921cdf0e10cSrcweir if( pArray[i] == ServiceName )
922cdf0e10cSrcweir return sal_True;
923cdf0e10cSrcweir return sal_False;
924cdf0e10cSrcweir }
925cdf0e10cSrcweir
926cdf0e10cSrcweir
getSupportedServiceNames()927cdf0e10cSrcweir Sequence< OUString > SAL_CALL Hyphenator::getSupportedServiceNames()
928cdf0e10cSrcweir throw(RuntimeException)
929cdf0e10cSrcweir {
930cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
931cdf0e10cSrcweir
932cdf0e10cSrcweir return getSupportedServiceNames_Static();
933cdf0e10cSrcweir }
934cdf0e10cSrcweir
935cdf0e10cSrcweir
getSupportedServiceNames_Static()936cdf0e10cSrcweir Sequence< OUString > Hyphenator::getSupportedServiceNames_Static()
937cdf0e10cSrcweir throw()
938cdf0e10cSrcweir {
939cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
940cdf0e10cSrcweir
941cdf0e10cSrcweir Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
942cdf0e10cSrcweir aSNS.getArray()[0] = A2OU( SN_HYPHENATOR );
943cdf0e10cSrcweir return aSNS;
944cdf0e10cSrcweir }
945cdf0e10cSrcweir
Hyphenator_getFactory(const sal_Char * pImplName,XMultiServiceFactory * pServiceManager,void *)946cdf0e10cSrcweir void * SAL_CALL Hyphenator_getFactory( const sal_Char * pImplName,
947cdf0e10cSrcweir XMultiServiceFactory * pServiceManager, void * )
948cdf0e10cSrcweir {
949cdf0e10cSrcweir void * pRet = 0;
950cdf0e10cSrcweir if ( !Hyphenator::getImplementationName_Static().compareToAscii( pImplName ) )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir Reference< XSingleServiceFactory > xFactory =
953cdf0e10cSrcweir cppu::createOneInstanceFactory(
954cdf0e10cSrcweir pServiceManager,
955cdf0e10cSrcweir Hyphenator::getImplementationName_Static(),
956cdf0e10cSrcweir Hyphenator_CreateInstance,
957cdf0e10cSrcweir Hyphenator::getSupportedServiceNames_Static());
958cdf0e10cSrcweir // acquire, because we return an interface pointer instead of a reference
959cdf0e10cSrcweir xFactory->acquire();
960cdf0e10cSrcweir pRet = xFactory.get();
961cdf0e10cSrcweir }
962cdf0e10cSrcweir return pRet;
963cdf0e10cSrcweir }
964cdf0e10cSrcweir
965cdf0e10cSrcweir
966cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
967cdf0e10cSrcweir
968cdf0e10cSrcweir #undef CAPTYPE_UNKNOWN
969cdf0e10cSrcweir #undef CAPTYPE_NOCAP
970cdf0e10cSrcweir #undef CAPTYPE_INITCAP
971cdf0e10cSrcweir #undef CAPTYPE_ALLCAP
972cdf0e10cSrcweir #undef CAPTYPE_MIXED
973