xref: /aoo41x/main/linguistic/source/spelldta.cxx (revision 3b8558fd)
1*3b8558fdSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*3b8558fdSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*3b8558fdSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*3b8558fdSAndrew Rist  * distributed with this work for additional information
6*3b8558fdSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*3b8558fdSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*3b8558fdSAndrew Rist  * "License"); you may not use this file except in compliance
9*3b8558fdSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*3b8558fdSAndrew Rist  *
11*3b8558fdSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*3b8558fdSAndrew Rist  *
13*3b8558fdSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*3b8558fdSAndrew Rist  * software distributed under the License is distributed on an
15*3b8558fdSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*3b8558fdSAndrew Rist  * KIND, either express or implied.  See the License for the
17*3b8558fdSAndrew Rist  * specific language governing permissions and limitations
18*3b8558fdSAndrew Rist  * under the License.
19*3b8558fdSAndrew Rist  *
20*3b8558fdSAndrew Rist  *************************************************************/
21*3b8558fdSAndrew Rist 
22*3b8558fdSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_linguistic.hxx"
26cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <com/sun/star/linguistic2/SpellFailure.hpp>
29cdf0e10cSrcweir #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
30cdf0e10cSrcweir #include <tools/debug.hxx>
31cdf0e10cSrcweir #include <unotools/processfactory.hxx>
32cdf0e10cSrcweir #include <osl/mutex.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <vector>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "linguistic/spelldta.hxx"
37cdf0e10cSrcweir #include "lngsvcmgr.hxx"
38cdf0e10cSrcweir 
39cdf0e10cSrcweir 
40cdf0e10cSrcweir using namespace utl;
41cdf0e10cSrcweir using namespace osl;
42cdf0e10cSrcweir using namespace rtl;
43cdf0e10cSrcweir using namespace com::sun::star;
44cdf0e10cSrcweir using namespace com::sun::star::beans;
45cdf0e10cSrcweir using namespace com::sun::star::lang;
46cdf0e10cSrcweir using namespace com::sun::star::uno;
47cdf0e10cSrcweir using namespace com::sun::star::linguistic2;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir namespace linguistic
50cdf0e10cSrcweir {
51cdf0e10cSrcweir 
52cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir #define MAX_PROPOSALS	40
56cdf0e10cSrcweir 
MergeProposals(Reference<XSpellAlternatives> & rxAlt1,Reference<XSpellAlternatives> & rxAlt2)57cdf0e10cSrcweir Reference< XSpellAlternatives > MergeProposals(
58cdf0e10cSrcweir 			Reference< XSpellAlternatives > &rxAlt1,
59cdf0e10cSrcweir 			Reference< XSpellAlternatives > &rxAlt2)
60cdf0e10cSrcweir {
61cdf0e10cSrcweir 	Reference< XSpellAlternatives > xMerged;
62cdf0e10cSrcweir 
63cdf0e10cSrcweir 	if (!rxAlt1.is())
64cdf0e10cSrcweir 		xMerged = rxAlt2;
65cdf0e10cSrcweir 	else if (!rxAlt2.is())
66cdf0e10cSrcweir 		xMerged = rxAlt1;
67cdf0e10cSrcweir 	else
68cdf0e10cSrcweir 	{
69cdf0e10cSrcweir 		sal_Int32 nAltCount1 = rxAlt1->getAlternativesCount();
70cdf0e10cSrcweir 		Sequence< OUString > aAlt1( rxAlt1->getAlternatives() );
71cdf0e10cSrcweir 		const OUString *pAlt1 = aAlt1.getConstArray();
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 		sal_Int32 nAltCount2 = rxAlt2->getAlternativesCount();
74cdf0e10cSrcweir 		Sequence< OUString > aAlt2( rxAlt2->getAlternatives() );
75cdf0e10cSrcweir 		const OUString *pAlt2 = aAlt2.getConstArray();
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 		sal_Int32 nCountNew = Min( nAltCount1 + nAltCount2, (sal_Int32) MAX_PROPOSALS );
78cdf0e10cSrcweir 		Sequence< OUString > aAltNew( nCountNew );
79cdf0e10cSrcweir 		OUString *pAltNew = aAltNew.getArray();
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 		sal_Int32 nIndex = 0;
82cdf0e10cSrcweir 		sal_Int32 i = 0;
83cdf0e10cSrcweir 		for (int j = 0;  j < 2;  j++)
84cdf0e10cSrcweir 		{
85cdf0e10cSrcweir 			sal_Int32 			nCount 	= j == 0 ? nAltCount1 : nAltCount2;
86cdf0e10cSrcweir 			const OUString  *pAlt 	= j == 0 ? pAlt1 : pAlt2;
87cdf0e10cSrcweir 			for (i = 0;  i < nCount  &&  nIndex < MAX_PROPOSALS;  i++)
88cdf0e10cSrcweir 			{
89cdf0e10cSrcweir 				if (pAlt[i].getLength())
90cdf0e10cSrcweir 					pAltNew[ nIndex++ ] = pAlt[ i ];
91cdf0e10cSrcweir 			}
92cdf0e10cSrcweir 		}
93cdf0e10cSrcweir 		DBG_ASSERT(nIndex == nCountNew, "lng : wrong number of proposals");
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 		SpellAlternatives *pSpellAlt = new SpellAlternatives;
96cdf0e10cSrcweir 		pSpellAlt->SetWordLanguage( rxAlt1->getWord(),
97cdf0e10cSrcweir 							LocaleToLanguage( rxAlt1->getLocale() ) );
98cdf0e10cSrcweir 		pSpellAlt->SetFailureType( rxAlt1->getFailureType() );
99cdf0e10cSrcweir 		pSpellAlt->SetAlternatives( aAltNew );
100cdf0e10cSrcweir 		xMerged = pSpellAlt;
101cdf0e10cSrcweir 	}
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 	return xMerged;
104cdf0e10cSrcweir }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 
SeqHasEntry(const Sequence<OUString> & rSeq,const OUString & rTxt)107cdf0e10cSrcweir sal_Bool SeqHasEntry(
108cdf0e10cSrcweir         const Sequence< OUString > &rSeq,
109cdf0e10cSrcweir         const OUString &rTxt)
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     sal_Bool bRes = sal_False;
112cdf0e10cSrcweir     sal_Int32 nLen = rSeq.getLength();
113cdf0e10cSrcweir     const OUString *pEntry = rSeq.getConstArray();
114cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < nLen  &&  !bRes;  ++i)
115cdf0e10cSrcweir     {
116cdf0e10cSrcweir         if (rTxt == pEntry[i])
117cdf0e10cSrcweir             bRes = sal_True;
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir     return bRes;
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 
SearchSimilarText(const OUString & rText,sal_Int16 nLanguage,Reference<XDictionaryList> & xDicList,std::vector<OUString> & rDicListProps)123cdf0e10cSrcweir void SearchSimilarText( const OUString &rText, sal_Int16 nLanguage,
124cdf0e10cSrcweir         Reference< XDictionaryList > &xDicList,
125cdf0e10cSrcweir         std::vector< OUString > & rDicListProps )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     if (!xDicList.is())
128cdf0e10cSrcweir         return;
129cdf0e10cSrcweir 
130cdf0e10cSrcweir     const uno::Sequence< Reference< XDictionary > >
131cdf0e10cSrcweir             aDics( xDicList->getDictionaries() );
132cdf0e10cSrcweir     const Reference< XDictionary >
133cdf0e10cSrcweir             *pDic = aDics.getConstArray();
134cdf0e10cSrcweir     sal_Int32 nDics = xDicList->getCount();
135cdf0e10cSrcweir 
136cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < nDics;  i++)
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir         Reference< XDictionary > xDic( pDic[i], UNO_QUERY );
139cdf0e10cSrcweir 
140cdf0e10cSrcweir         sal_Int16           nLang = LocaleToLanguage( xDic->getLocale() );
141cdf0e10cSrcweir 
142cdf0e10cSrcweir         if ( xDic.is() && xDic->isActive()
143cdf0e10cSrcweir             && (nLang == nLanguage  ||  nLang == LANGUAGE_NONE) )
144cdf0e10cSrcweir         {
145cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
146cdf0e10cSrcweir             DictionaryType  eType = xDic->getDictionaryType();
147cdf0e10cSrcweir 			(void) eType;
148cdf0e10cSrcweir             DBG_ASSERT( eType != DictionaryType_MIXED, "unexpected dictionary type" );
149cdf0e10cSrcweir #endif
150cdf0e10cSrcweir             const Sequence< Reference< XDictionaryEntry > > aEntries = xDic->getEntries();
151cdf0e10cSrcweir             const Reference< XDictionaryEntry > *pEntries = aEntries.getConstArray();
152cdf0e10cSrcweir             sal_Int32 nLen = aEntries.getLength();
153cdf0e10cSrcweir             for (sal_Int32 k = 0;  k < nLen;  ++k)
154cdf0e10cSrcweir             {
155cdf0e10cSrcweir 				String aEntryTxt;
156cdf0e10cSrcweir 				if (pEntries[k].is())
157cdf0e10cSrcweir 				{
158cdf0e10cSrcweir 					aEntryTxt = pEntries[k]->getDictionaryWord();
159cdf0e10cSrcweir 					// remove characters used to determine hyphenation positions
160cdf0e10cSrcweir 					aEntryTxt.EraseAllChars( '=' );
161cdf0e10cSrcweir 				}
162cdf0e10cSrcweir                 if (aEntryTxt.Len() > 0  &&  LevDistance( rText, aEntryTxt ) <= 2)
163cdf0e10cSrcweir                     rDicListProps.push_back( aEntryTxt );
164cdf0e10cSrcweir             }
165cdf0e10cSrcweir         }
166cdf0e10cSrcweir     }
167cdf0e10cSrcweir }
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 
SeqRemoveNegEntries(Sequence<OUString> & rSeq,Reference<XDictionaryList> & rxDicList,sal_Int16 nLanguage)170cdf0e10cSrcweir void SeqRemoveNegEntries( Sequence< OUString > &rSeq,
171cdf0e10cSrcweir         Reference< XDictionaryList > &rxDicList,
172cdf0e10cSrcweir         sal_Int16 nLanguage )
173cdf0e10cSrcweir {
174cdf0e10cSrcweir     static const OUString aEmpty;
175cdf0e10cSrcweir     sal_Bool bSthRemoved = sal_False;
176cdf0e10cSrcweir     sal_Int32 nLen = rSeq.getLength();
177cdf0e10cSrcweir     OUString *pEntries = rSeq.getArray();
178cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < nLen;  ++i)
179cdf0e10cSrcweir     {
180cdf0e10cSrcweir         Reference< XDictionaryEntry > xNegEntry( SearchDicList( rxDicList,
181cdf0e10cSrcweir                     pEntries[i], nLanguage, sal_False, sal_True ) );
182cdf0e10cSrcweir         if (xNegEntry.is())
183cdf0e10cSrcweir         {
184cdf0e10cSrcweir             pEntries[i] = aEmpty;
185cdf0e10cSrcweir             bSthRemoved = sal_True;
186cdf0e10cSrcweir         }
187cdf0e10cSrcweir     }
188cdf0e10cSrcweir     if (bSthRemoved)
189cdf0e10cSrcweir     {
190cdf0e10cSrcweir         Sequence< OUString > aNew;
191cdf0e10cSrcweir         // merge sequence without duplicates and empty strings in new empty sequence
192cdf0e10cSrcweir         aNew = MergeProposalSeqs( aNew, rSeq, sal_False );
193cdf0e10cSrcweir         rSeq = aNew;
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 
MergeProposalSeqs(Sequence<OUString> & rAlt1,Sequence<OUString> & rAlt2,sal_Bool bAllowDuplicates)198cdf0e10cSrcweir Sequence< OUString > MergeProposalSeqs(
199cdf0e10cSrcweir             Sequence< OUString > &rAlt1,
200cdf0e10cSrcweir             Sequence< OUString > &rAlt2,
201cdf0e10cSrcweir             sal_Bool bAllowDuplicates )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir     Sequence< OUString > aMerged;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     if (0 == rAlt1.getLength() && bAllowDuplicates)
206cdf0e10cSrcweir         aMerged = rAlt2;
207cdf0e10cSrcweir     else if (0 == rAlt2.getLength() && bAllowDuplicates)
208cdf0e10cSrcweir         aMerged = rAlt1;
209cdf0e10cSrcweir     else
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         sal_Int32 nAltCount1 = rAlt1.getLength();
212cdf0e10cSrcweir         const OUString *pAlt1 = rAlt1.getConstArray();
213cdf0e10cSrcweir         sal_Int32 nAltCount2 = rAlt2.getLength();
214cdf0e10cSrcweir         const OUString *pAlt2 = rAlt2.getConstArray();
215cdf0e10cSrcweir 
216cdf0e10cSrcweir         sal_Int32 nCountNew = Min( nAltCount1 + nAltCount2, (sal_Int32) MAX_PROPOSALS );
217cdf0e10cSrcweir         aMerged.realloc( nCountNew );
218cdf0e10cSrcweir         OUString *pMerged = aMerged.getArray();
219cdf0e10cSrcweir 
220cdf0e10cSrcweir         sal_Int32 nIndex = 0;
221cdf0e10cSrcweir         sal_Int32 i = 0;
222cdf0e10cSrcweir         for (int j = 0;  j < 2;  j++)
223cdf0e10cSrcweir         {
224cdf0e10cSrcweir             sal_Int32           nCount  = j == 0 ? nAltCount1 : nAltCount2;
225cdf0e10cSrcweir             const OUString  *pAlt   = j == 0 ? pAlt1 : pAlt2;
226cdf0e10cSrcweir             for (i = 0;  i < nCount  &&  nIndex < MAX_PROPOSALS;  i++)
227cdf0e10cSrcweir             {
228cdf0e10cSrcweir                 if (pAlt[i].getLength() &&
229cdf0e10cSrcweir                     (bAllowDuplicates || !SeqHasEntry(aMerged, pAlt[i] )))
230cdf0e10cSrcweir                     pMerged[ nIndex++ ] = pAlt[ i ];
231cdf0e10cSrcweir             }
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir         //DBG_ASSERT(nIndex == nCountNew, "wrong number of proposals");
234cdf0e10cSrcweir         aMerged.realloc( nIndex );
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     return aMerged;
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 
SpellAlternatives()243cdf0e10cSrcweir SpellAlternatives::SpellAlternatives()
244cdf0e10cSrcweir {
245cdf0e10cSrcweir 	nLanguage	= LANGUAGE_NONE;
246cdf0e10cSrcweir 	nType 		= SpellFailure::IS_NEGATIVE_WORD;
247cdf0e10cSrcweir }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 
SpellAlternatives(const OUString & rWord,sal_Int16 nLang,sal_Int16 nFailureType,const OUString & rRplcWord)250cdf0e10cSrcweir SpellAlternatives::SpellAlternatives(
251cdf0e10cSrcweir 			const OUString &rWord, sal_Int16 nLang,
252cdf0e10cSrcweir 			sal_Int16 nFailureType, const OUString &rRplcWord ) :
253cdf0e10cSrcweir     aAlt        ( Sequence< OUString >(1) ),
254cdf0e10cSrcweir 	aWord		(rWord),
255cdf0e10cSrcweir     nType       (nFailureType),
256cdf0e10cSrcweir     nLanguage   (nLang)
257cdf0e10cSrcweir {
258cdf0e10cSrcweir 	if (rRplcWord.getLength())
259cdf0e10cSrcweir 		aAlt.getArray()[ 0 ] = rRplcWord;
260cdf0e10cSrcweir 	else
261cdf0e10cSrcweir 		aAlt.realloc( 0 );
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 
SpellAlternatives(const OUString & rWord,sal_Int16 nLang,sal_Int16 nFailureType,const Sequence<OUString> & rAlternatives)265cdf0e10cSrcweir SpellAlternatives::SpellAlternatives(
266cdf0e10cSrcweir         const OUString &rWord, sal_Int16 nLang, sal_Int16 nFailureType,
267cdf0e10cSrcweir         const Sequence< OUString > &rAlternatives ) :
268cdf0e10cSrcweir     aAlt        (rAlternatives),
269cdf0e10cSrcweir     aWord       (rWord),
270cdf0e10cSrcweir     nType       (nFailureType),
271cdf0e10cSrcweir     nLanguage   (nLang)
272cdf0e10cSrcweir {
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 
~SpellAlternatives()276cdf0e10cSrcweir SpellAlternatives::~SpellAlternatives()
277cdf0e10cSrcweir {
278cdf0e10cSrcweir }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir 
getWord()281cdf0e10cSrcweir OUString SAL_CALL SpellAlternatives::getWord()
282cdf0e10cSrcweir 		throw(RuntimeException)
283cdf0e10cSrcweir {
284cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
285cdf0e10cSrcweir 	return aWord;
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 
getLocale()289cdf0e10cSrcweir Locale SAL_CALL SpellAlternatives::getLocale()
290cdf0e10cSrcweir 		throw(RuntimeException)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
293cdf0e10cSrcweir 	return CreateLocale( nLanguage );
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 
getFailureType()297cdf0e10cSrcweir sal_Int16 SAL_CALL SpellAlternatives::getFailureType()
298cdf0e10cSrcweir 		throw(RuntimeException)
299cdf0e10cSrcweir {
300cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
301cdf0e10cSrcweir 	return nType;
302cdf0e10cSrcweir }
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 
getAlternativesCount()305cdf0e10cSrcweir sal_Int16 SAL_CALL SpellAlternatives::getAlternativesCount()
306cdf0e10cSrcweir 		throw(RuntimeException)
307cdf0e10cSrcweir {
308cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
309cdf0e10cSrcweir 	return (sal_Int16) aAlt.getLength();
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 
getAlternatives()313cdf0e10cSrcweir Sequence< OUString > SAL_CALL SpellAlternatives::getAlternatives()
314cdf0e10cSrcweir 		throw(RuntimeException)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
317cdf0e10cSrcweir 	return aAlt;
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 
setAlternatives(const uno::Sequence<OUString> & rAlternatives)321cdf0e10cSrcweir void SAL_CALL SpellAlternatives::setAlternatives( const uno::Sequence< OUString >& rAlternatives )
322cdf0e10cSrcweir throw (uno::RuntimeException)
323cdf0e10cSrcweir {
324cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
325cdf0e10cSrcweir     aAlt = rAlternatives;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 
setFailureType(sal_Int16 nFailureType)329cdf0e10cSrcweir void SAL_CALL SpellAlternatives::setFailureType( sal_Int16 nFailureType )
330cdf0e10cSrcweir throw (uno::RuntimeException)
331cdf0e10cSrcweir {
332cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
333cdf0e10cSrcweir     nType = nFailureType;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 
SetWordLanguage(const OUString & rWord,sal_Int16 nLang)337cdf0e10cSrcweir void SpellAlternatives::SetWordLanguage(const OUString &rWord, sal_Int16 nLang)
338cdf0e10cSrcweir {
339cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
340cdf0e10cSrcweir 	aWord = rWord;
341cdf0e10cSrcweir 	nLanguage = nLang;
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 
SetFailureType(sal_Int16 nTypeP)345cdf0e10cSrcweir void SpellAlternatives::SetFailureType(sal_Int16 nTypeP)
346cdf0e10cSrcweir {
347cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
348cdf0e10cSrcweir 	nType = nTypeP;
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 
SetAlternatives(const Sequence<OUString> & rAlt)352cdf0e10cSrcweir void SpellAlternatives::SetAlternatives( const Sequence< OUString > &rAlt )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir 	MutexGuard	aGuard( GetLinguMutex() );
355cdf0e10cSrcweir 	aAlt = rAlt;
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 
359cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
360cdf0e10cSrcweir 
361cdf0e10cSrcweir }	// namespace linguistic
362cdf0e10cSrcweir 
363