Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <com/sun/star/uno/Reference.h>
30 : : #include <com/sun/star/linguistic2/SpellFailure.hpp>
31 : : #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
32 : : #include <comphelper/string.hxx>
33 : : #include <tools/debug.hxx>
34 : : #include <osl/mutex.hxx>
35 : :
36 : : #include <vector>
37 : :
38 : : #include "linguistic/spelldta.hxx"
39 : : #include "lngsvcmgr.hxx"
40 : :
41 : :
42 : : using namespace utl;
43 : : using namespace osl;
44 : : using namespace com::sun::star;
45 : : using namespace com::sun::star::beans;
46 : : using namespace com::sun::star::lang;
47 : : using namespace com::sun::star::uno;
48 : : using namespace com::sun::star::linguistic2;
49 : :
50 : : using ::rtl::OUString;
51 : :
52 : : namespace linguistic
53 : : {
54 : :
55 : : #define MAX_PROPOSALS 40
56 : :
57 : 0 : sal_Bool SeqHasEntry(
58 : : const Sequence< OUString > &rSeq,
59 : : const OUString &rTxt)
60 : : {
61 : 0 : sal_Bool bRes = sal_False;
62 : 0 : sal_Int32 nLen = rSeq.getLength();
63 : 0 : const OUString *pEntry = rSeq.getConstArray();
64 [ # # ][ # # ]: 0 : for (sal_Int32 i = 0; i < nLen && !bRes; ++i)
[ # # ]
65 : : {
66 [ # # ]: 0 : if (rTxt == pEntry[i])
67 : 0 : bRes = sal_True;
68 : : }
69 : 0 : return bRes;
70 : : }
71 : :
72 : :
73 : 0 : void SearchSimilarText( const OUString &rText, sal_Int16 nLanguage,
74 : : Reference< XDictionaryList > &xDicList,
75 : : std::vector< OUString > & rDicListProps )
76 : : {
77 [ # # ]: 0 : if (!xDicList.is())
78 : 0 : return;
79 : :
80 : : const uno::Sequence< Reference< XDictionary > >
81 [ # # ][ # # ]: 0 : aDics( xDicList->getDictionaries() );
82 : : const Reference< XDictionary >
83 : 0 : *pDic = aDics.getConstArray();
84 [ # # ][ # # ]: 0 : sal_Int32 nDics = xDicList->getCount();
85 : :
86 [ # # ]: 0 : for (sal_Int32 i = 0; i < nDics; i++)
87 : : {
88 [ # # ]: 0 : Reference< XDictionary > xDic( pDic[i], UNO_QUERY );
89 : :
90 [ # # ][ # # ]: 0 : sal_Int16 nLang = LocaleToLanguage( xDic->getLocale() );
[ # # ]
91 : :
92 [ # # ][ # # ]: 0 : if ( xDic.is() && xDic->isActive()
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
93 : : && (nLang == nLanguage || nLang == LANGUAGE_NONE) )
94 : : {
95 : : #if OSL_DEBUG_LEVEL > 1
96 : : DictionaryType eType = xDic->getDictionaryType();
97 : : (void) eType;
98 : : DBG_ASSERT( eType != DictionaryType_MIXED, "unexpected dictionary type" );
99 : : #endif
100 [ # # ][ # # ]: 0 : const Sequence< Reference< XDictionaryEntry > > aEntries = xDic->getEntries();
101 : 0 : const Reference< XDictionaryEntry > *pEntries = aEntries.getConstArray();
102 : 0 : sal_Int32 nLen = aEntries.getLength();
103 [ # # ]: 0 : for (sal_Int32 k = 0; k < nLen; ++k)
104 : : {
105 [ # # ]: 0 : String aEntryTxt;
106 [ # # ]: 0 : if (pEntries[k].is())
107 : : {
108 : : // remove characters used to determine hyphenation positions
109 [ # # ][ # # ]: 0 : aEntryTxt = comphelper::string::remove(pEntries[k]->getDictionaryWord(), '=');
[ # # ]
110 : : }
111 [ # # ][ # # ]: 0 : if (aEntryTxt.Len() > 0 && LevDistance( rText, aEntryTxt ) <= 2)
[ # # ][ # # ]
[ # # ]
[ # # # # ]
112 [ # # ][ # # ]: 0 : rDicListProps.push_back( aEntryTxt );
113 [ # # ][ # # ]: 0 : }
114 : : }
115 [ # # ]: 0 : }
116 : : }
117 : :
118 : :
119 : 0 : void SeqRemoveNegEntries( Sequence< OUString > &rSeq,
120 : : Reference< XDictionaryList > &rxDicList,
121 : : sal_Int16 nLanguage )
122 : : {
123 [ # # ][ # # ]: 0 : static const OUString aEmpty;
124 : 0 : sal_Bool bSthRemoved = sal_False;
125 : 0 : sal_Int32 nLen = rSeq.getLength();
126 : 0 : OUString *pEntries = rSeq.getArray();
127 [ # # ]: 0 : for (sal_Int32 i = 0; i < nLen; ++i)
128 : : {
129 : : Reference< XDictionaryEntry > xNegEntry( SearchDicList( rxDicList,
130 [ # # ]: 0 : pEntries[i], nLanguage, sal_False, sal_True ) );
131 [ # # ]: 0 : if (xNegEntry.is())
132 : : {
133 : 0 : pEntries[i] = aEmpty;
134 : 0 : bSthRemoved = sal_True;
135 : : }
136 : 0 : }
137 [ # # ]: 0 : if (bSthRemoved)
138 : : {
139 [ # # ]: 0 : Sequence< OUString > aNew;
140 : : // merge sequence without duplicates and empty strings in new empty sequence
141 [ # # ][ # # ]: 0 : aNew = MergeProposalSeqs( aNew, rSeq, sal_False );
[ # # ]
142 [ # # ][ # # ]: 0 : rSeq = aNew;
143 : : }
144 : 0 : }
145 : :
146 : :
147 : 0 : Sequence< OUString > MergeProposalSeqs(
148 : : Sequence< OUString > &rAlt1,
149 : : Sequence< OUString > &rAlt2,
150 : : sal_Bool bAllowDuplicates )
151 : : {
152 : 0 : Sequence< OUString > aMerged;
153 : :
154 [ # # ][ # # ]: 0 : if (0 == rAlt1.getLength() && bAllowDuplicates)
[ # # ]
155 [ # # ]: 0 : aMerged = rAlt2;
156 [ # # ][ # # ]: 0 : else if (0 == rAlt2.getLength() && bAllowDuplicates)
[ # # ]
157 [ # # ]: 0 : aMerged = rAlt1;
158 : : else
159 : : {
160 : 0 : sal_Int32 nAltCount1 = rAlt1.getLength();
161 : 0 : const OUString *pAlt1 = rAlt1.getConstArray();
162 : 0 : sal_Int32 nAltCount2 = rAlt2.getLength();
163 : 0 : const OUString *pAlt2 = rAlt2.getConstArray();
164 : :
165 : 0 : sal_Int32 nCountNew = Min( nAltCount1 + nAltCount2, (sal_Int32) MAX_PROPOSALS );
166 [ # # ]: 0 : aMerged.realloc( nCountNew );
167 [ # # ]: 0 : OUString *pMerged = aMerged.getArray();
168 : :
169 : 0 : sal_Int32 nIndex = 0;
170 : 0 : sal_Int32 i = 0;
171 [ # # ]: 0 : for (int j = 0; j < 2; j++)
172 : : {
173 [ # # ]: 0 : sal_Int32 nCount = j == 0 ? nAltCount1 : nAltCount2;
174 [ # # ]: 0 : const OUString *pAlt = j == 0 ? pAlt1 : pAlt2;
175 [ # # ][ # # ]: 0 : for (i = 0; i < nCount && nIndex < MAX_PROPOSALS; i++)
[ # # ]
176 : : {
177 [ # # ][ # # ]: 0 : if (!pAlt[i].isEmpty() &&
[ # # ][ # # ]
178 [ # # ]: 0 : (bAllowDuplicates || !SeqHasEntry(aMerged, pAlt[i] )))
179 : 0 : pMerged[ nIndex++ ] = pAlt[ i ];
180 : : }
181 : : }
182 [ # # ]: 0 : aMerged.realloc( nIndex );
183 : : }
184 : :
185 : 0 : return aMerged;
186 : : }
187 : :
188 : :
189 : :
190 [ # # ]: 0 : SpellAlternatives::SpellAlternatives()
191 : : {
192 : 0 : nLanguage = LANGUAGE_NONE;
193 : 0 : nType = SpellFailure::IS_NEGATIVE_WORD;
194 : 0 : }
195 : :
196 : :
197 : 0 : SpellAlternatives::SpellAlternatives(
198 : : const OUString &rWord, sal_Int16 nLang, sal_Int16 nFailureType,
199 : : const Sequence< OUString > &rAlternatives ) :
200 : : aAlt (rAlternatives),
201 : : aWord (rWord),
202 : : nType (nFailureType),
203 [ # # ]: 0 : nLanguage (nLang)
204 : : {
205 : 0 : }
206 : :
207 : :
208 [ # # ]: 0 : SpellAlternatives::~SpellAlternatives()
209 : : {
210 [ # # ]: 0 : }
211 : :
212 : :
213 : 0 : OUString SAL_CALL SpellAlternatives::getWord()
214 : : throw(RuntimeException)
215 : : {
216 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
217 [ # # ]: 0 : return aWord;
218 : : }
219 : :
220 : :
221 : 0 : Locale SAL_CALL SpellAlternatives::getLocale()
222 : : throw(RuntimeException)
223 : : {
224 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
225 [ # # ][ # # ]: 0 : return CreateLocale( nLanguage );
226 : : }
227 : :
228 : :
229 : 0 : sal_Int16 SAL_CALL SpellAlternatives::getFailureType()
230 : : throw(RuntimeException)
231 : : {
232 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
233 [ # # ]: 0 : return nType;
234 : : }
235 : :
236 : :
237 : 0 : sal_Int16 SAL_CALL SpellAlternatives::getAlternativesCount()
238 : : throw(RuntimeException)
239 : : {
240 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
241 [ # # ]: 0 : return (sal_Int16) aAlt.getLength();
242 : : }
243 : :
244 : :
245 : 0 : Sequence< OUString > SAL_CALL SpellAlternatives::getAlternatives()
246 : : throw(RuntimeException)
247 : : {
248 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
249 [ # # ][ # # ]: 0 : return aAlt;
250 : : }
251 : :
252 : :
253 : 0 : void SAL_CALL SpellAlternatives::setAlternatives( const uno::Sequence< OUString >& rAlternatives )
254 : : throw (uno::RuntimeException)
255 : : {
256 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
257 [ # # ][ # # ]: 0 : aAlt = rAlternatives;
258 : 0 : }
259 : :
260 : :
261 : 0 : void SAL_CALL SpellAlternatives::setFailureType( sal_Int16 nFailureType )
262 : : throw (uno::RuntimeException)
263 : : {
264 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
265 [ # # ]: 0 : nType = nFailureType;
266 : 0 : }
267 : :
268 : :
269 : 0 : void SpellAlternatives::SetWordLanguage(const OUString &rWord, sal_Int16 nLang)
270 : : {
271 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
272 : 0 : aWord = rWord;
273 [ # # ]: 0 : nLanguage = nLang;
274 : 0 : }
275 : :
276 : :
277 : 0 : void SpellAlternatives::SetFailureType(sal_Int16 nTypeP)
278 : : {
279 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
280 [ # # ]: 0 : nType = nTypeP;
281 : 0 : }
282 : :
283 : :
284 : 0 : void SpellAlternatives::SetAlternatives( const Sequence< OUString > &rAlt )
285 : : {
286 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
287 [ # # ][ # # ]: 0 : aAlt = rAlt;
288 : 0 : }
289 : :
290 : :
291 : 0 : com::sun::star::uno::Reference < com::sun::star::linguistic2::XSpellAlternatives > SpellAlternatives::CreateSpellAlternatives(
292 : : const ::rtl::OUString &rWord, sal_Int16 nLang, sal_Int16 nTypeP, const ::com::sun::star::uno::Sequence< ::rtl::OUString > &rAlt )
293 : : {
294 [ # # ]: 0 : SpellAlternatives* pAlt = new SpellAlternatives;
295 : 0 : pAlt->SetWordLanguage( rWord, nLang );
296 : 0 : pAlt->SetFailureType( nTypeP );
297 : 0 : pAlt->SetAlternatives( rAlt );
298 [ # # ]: 0 : return Reference < XSpellAlternatives >(pAlt);
299 : : }
300 : :
301 : :
302 : : } // namespace linguistic
303 : :
304 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|