merge the formfield patch from ooo-build
[ooovba.git] / linguistic / source / spelldta.cxx
blob5004e84f46325309921c52d42fcc04f3c3a0233d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: spelldta.cxx,v $
10 * $Revision: 1.8 $
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_linguistic.hxx"
33 #include <com/sun/star/uno/Reference.h>
35 #include <com/sun/star/linguistic2/SpellFailure.hpp>
36 #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
37 #include <tools/debug.hxx>
38 #include <unotools/processfactory.hxx>
39 #include <osl/mutex.hxx>
41 #include <vector>
43 #include "spelldta.hxx"
44 #include "lngsvcmgr.hxx"
47 using namespace utl;
48 using namespace osl;
49 using namespace rtl;
50 using namespace com::sun::star;
51 using namespace com::sun::star::beans;
52 using namespace com::sun::star::lang;
53 using namespace com::sun::star::uno;
54 using namespace com::sun::star::linguistic2;
56 namespace linguistic
59 ///////////////////////////////////////////////////////////////////////////
62 #define MAX_PROPOSALS 40
64 Reference< XSpellAlternatives > MergeProposals(
65 Reference< XSpellAlternatives > &rxAlt1,
66 Reference< XSpellAlternatives > &rxAlt2)
68 Reference< XSpellAlternatives > xMerged;
70 if (!rxAlt1.is())
71 xMerged = rxAlt2;
72 else if (!rxAlt2.is())
73 xMerged = rxAlt1;
74 else
76 INT32 nAltCount1 = rxAlt1->getAlternativesCount();
77 Sequence< OUString > aAlt1( rxAlt1->getAlternatives() );
78 const OUString *pAlt1 = aAlt1.getConstArray();
80 INT32 nAltCount2 = rxAlt2->getAlternativesCount();
81 Sequence< OUString > aAlt2( rxAlt2->getAlternatives() );
82 const OUString *pAlt2 = aAlt2.getConstArray();
84 INT32 nCountNew = Min( nAltCount1 + nAltCount2, (INT32) MAX_PROPOSALS );
85 Sequence< OUString > aAltNew( nCountNew );
86 OUString *pAltNew = aAltNew.getArray();
88 INT32 nIndex = 0;
89 INT32 i = 0;
90 for (int j = 0; j < 2; j++)
92 INT32 nCount = j == 0 ? nAltCount1 : nAltCount2;
93 const OUString *pAlt = j == 0 ? pAlt1 : pAlt2;
94 for (i = 0; i < nCount && nIndex < MAX_PROPOSALS; i++)
96 if (pAlt[i].getLength())
97 pAltNew[ nIndex++ ] = pAlt[ i ];
100 DBG_ASSERT(nIndex == nCountNew, "lng : wrong number of proposals");
102 SpellAlternatives *pSpellAlt = new SpellAlternatives;
103 pSpellAlt->SetWordLanguage( rxAlt1->getWord(),
104 LocaleToLanguage( rxAlt1->getLocale() ) );
105 pSpellAlt->SetFailureType( rxAlt1->getFailureType() );
106 pSpellAlt->SetAlternatives( aAltNew );
107 xMerged = pSpellAlt;
110 return xMerged;
114 BOOL SeqHasEntry(
115 const Sequence< OUString > &rSeq,
116 const OUString &rTxt)
118 BOOL bRes = FALSE;
119 INT32 nLen = rSeq.getLength();
120 const OUString *pEntry = rSeq.getConstArray();
121 for (INT32 i = 0; i < nLen && !bRes; ++i)
123 if (rTxt == pEntry[i])
124 bRes = TRUE;
126 return bRes;
130 void SearchSimilarText( const OUString &rText, INT16 nLanguage,
131 Reference< XDictionaryList > &xDicList,
132 std::vector< OUString > & rDicListProps )
134 if (!xDicList.is())
135 return;
137 const uno::Sequence< Reference< XDictionary > >
138 aDics( xDicList->getDictionaries() );
139 const Reference< XDictionary >
140 *pDic = aDics.getConstArray();
141 INT32 nDics = xDicList->getCount();
143 for (INT32 i = 0; i < nDics; i++)
145 Reference< XDictionary > xDic( pDic[i], UNO_QUERY );
147 INT16 nLang = LocaleToLanguage( xDic->getLocale() );
149 if ( xDic.is() && xDic->isActive()
150 && (nLang == nLanguage || nLang == LANGUAGE_NONE) )
152 #if OSL_DEBUG_LEVEL > 1
153 DictionaryType eType = xDic->getDictionaryType();
154 (void) eType;
155 DBG_ASSERT( eType != DictionaryType_MIXED, "unexpected dictionary type" );
156 #endif
157 const Sequence< Reference< XDictionaryEntry > > aEntries = xDic->getEntries();
158 const Reference< XDictionaryEntry > *pEntries = aEntries.getConstArray();
159 INT32 nLen = aEntries.getLength();
160 for (INT32 k = 0; k < nLen; ++k)
162 String aEntryTxt;
163 if (pEntries[k].is())
165 aEntryTxt = pEntries[k]->getDictionaryWord();
166 // remove characters used to determine hyphenation positions
167 aEntryTxt.EraseAllChars( '=' );
169 if (aEntryTxt.Len() > 0 && LevDistance( rText, aEntryTxt ) <= 2)
170 rDicListProps.push_back( aEntryTxt );
177 void SeqRemoveNegEntries( Sequence< OUString > &rSeq,
178 Reference< XDictionaryList > &rxDicList,
179 INT16 nLanguage )
181 static const OUString aEmpty;
182 BOOL bSthRemoved = FALSE;
183 INT32 nLen = rSeq.getLength();
184 OUString *pEntries = rSeq.getArray();
185 for (INT32 i = 0; i < nLen; ++i)
187 Reference< XDictionaryEntry > xNegEntry( SearchDicList( rxDicList,
188 pEntries[i], nLanguage, FALSE, TRUE ) );
189 if (xNegEntry.is())
191 pEntries[i] = aEmpty;
192 bSthRemoved = TRUE;
195 if (bSthRemoved)
197 Sequence< OUString > aNew;
198 // merge sequence without duplicates and empty strings in new empty sequence
199 aNew = MergeProposalSeqs( aNew, rSeq, FALSE );
200 rSeq = aNew;
205 Sequence< OUString > MergeProposalSeqs(
206 Sequence< OUString > &rAlt1,
207 Sequence< OUString > &rAlt2,
208 BOOL bAllowDuplicates )
210 Sequence< OUString > aMerged;
212 if (0 == rAlt1.getLength() && bAllowDuplicates)
213 aMerged = rAlt2;
214 else if (0 == rAlt2.getLength() && bAllowDuplicates)
215 aMerged = rAlt1;
216 else
218 INT32 nAltCount1 = rAlt1.getLength();
219 const OUString *pAlt1 = rAlt1.getConstArray();
220 INT32 nAltCount2 = rAlt2.getLength();
221 const OUString *pAlt2 = rAlt2.getConstArray();
223 INT32 nCountNew = Min( nAltCount1 + nAltCount2, (INT32) MAX_PROPOSALS );
224 aMerged.realloc( nCountNew );
225 OUString *pMerged = aMerged.getArray();
227 INT32 nIndex = 0;
228 INT32 i = 0;
229 for (int j = 0; j < 2; j++)
231 INT32 nCount = j == 0 ? nAltCount1 : nAltCount2;
232 const OUString *pAlt = j == 0 ? pAlt1 : pAlt2;
233 for (i = 0; i < nCount && nIndex < MAX_PROPOSALS; i++)
235 if (pAlt[i].getLength() &&
236 (bAllowDuplicates || !SeqHasEntry(aMerged, pAlt[i] )))
237 pMerged[ nIndex++ ] = pAlt[ i ];
240 //DBG_ASSERT(nIndex == nCountNew, "wrong number of proposals");
241 aMerged.realloc( nIndex );
244 return aMerged;
247 ///////////////////////////////////////////////////////////////////////////
250 SpellAlternatives::SpellAlternatives()
252 nLanguage = LANGUAGE_NONE;
253 nType = SpellFailure::IS_NEGATIVE_WORD;
257 SpellAlternatives::SpellAlternatives(
258 const OUString &rWord, INT16 nLang,
259 INT16 nFailureType, const OUString &rRplcWord ) :
260 aAlt ( Sequence< OUString >(1) ),
261 aWord (rWord),
262 nType (nFailureType),
263 nLanguage (nLang)
265 if (rRplcWord.getLength())
266 aAlt.getArray()[ 0 ] = rRplcWord;
267 else
268 aAlt.realloc( 0 );
272 SpellAlternatives::SpellAlternatives(
273 const OUString &rWord, INT16 nLang, INT16 nFailureType,
274 const Sequence< OUString > &rAlternatives ) :
275 aAlt (rAlternatives),
276 aWord (rWord),
277 nType (nFailureType),
278 nLanguage (nLang)
283 SpellAlternatives::~SpellAlternatives()
288 OUString SAL_CALL SpellAlternatives::getWord()
289 throw(RuntimeException)
291 MutexGuard aGuard( GetLinguMutex() );
292 return aWord;
296 Locale SAL_CALL SpellAlternatives::getLocale()
297 throw(RuntimeException)
299 MutexGuard aGuard( GetLinguMutex() );
300 return CreateLocale( nLanguage );
304 sal_Int16 SAL_CALL SpellAlternatives::getFailureType()
305 throw(RuntimeException)
307 MutexGuard aGuard( GetLinguMutex() );
308 return nType;
312 sal_Int16 SAL_CALL SpellAlternatives::getAlternativesCount()
313 throw(RuntimeException)
315 MutexGuard aGuard( GetLinguMutex() );
316 return (INT16) aAlt.getLength();
320 Sequence< OUString > SAL_CALL SpellAlternatives::getAlternatives()
321 throw(RuntimeException)
323 MutexGuard aGuard( GetLinguMutex() );
324 return aAlt;
328 void SAL_CALL SpellAlternatives::setAlternatives( const uno::Sequence< OUString >& rAlternatives )
329 throw (uno::RuntimeException)
331 MutexGuard aGuard( GetLinguMutex() );
332 aAlt = rAlternatives;
336 void SAL_CALL SpellAlternatives::setFailureType( sal_Int16 nFailureType )
337 throw (uno::RuntimeException)
339 MutexGuard aGuard( GetLinguMutex() );
340 nType = nFailureType;
344 void SpellAlternatives::SetWordLanguage(const OUString &rWord, INT16 nLang)
346 MutexGuard aGuard( GetLinguMutex() );
347 aWord = rWord;
348 nLanguage = nLang;
352 void SpellAlternatives::SetFailureType(INT16 nTypeP)
354 MutexGuard aGuard( GetLinguMutex() );
355 nType = nTypeP;
359 void SpellAlternatives::SetAlternatives( const Sequence< OUString > &rAlt )
361 MutexGuard aGuard( GetLinguMutex() );
362 aAlt = rAlt;
366 ///////////////////////////////////////////////////////////////////////////
368 } // namespace linguistic