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: spelldta.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_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>
43 #include "spelldta.hxx"
44 #include "lngsvcmgr.hxx"
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
;
59 ///////////////////////////////////////////////////////////////////////////
62 #define MAX_PROPOSALS 40
64 Reference
< XSpellAlternatives
> MergeProposals(
65 Reference
< XSpellAlternatives
> &rxAlt1
,
66 Reference
< XSpellAlternatives
> &rxAlt2
)
68 Reference
< XSpellAlternatives
> xMerged
;
72 else if (!rxAlt2
.is())
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();
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
);
115 const Sequence
< OUString
> &rSeq
,
116 const OUString
&rTxt
)
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
])
130 void SearchSimilarText( const OUString
&rText
, INT16 nLanguage
,
131 Reference
< XDictionaryList
> &xDicList
,
132 std::vector
< OUString
> & rDicListProps
)
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();
155 DBG_ASSERT( eType
!= DictionaryType_MIXED
, "unexpected dictionary type" );
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
)
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
,
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
) );
191 pEntries
[i
] = aEmpty
;
197 Sequence
< OUString
> aNew
;
198 // merge sequence without duplicates and empty strings in new empty sequence
199 aNew
= MergeProposalSeqs( aNew
, rSeq
, FALSE
);
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
)
214 else if (0 == rAlt2
.getLength() && bAllowDuplicates
)
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();
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
);
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) ),
262 nType (nFailureType
),
265 if (rRplcWord
.getLength())
266 aAlt
.getArray()[ 0 ] = rRplcWord
;
272 SpellAlternatives::SpellAlternatives(
273 const OUString
&rWord
, INT16 nLang
, INT16 nFailureType
,
274 const Sequence
< OUString
> &rAlternatives
) :
275 aAlt (rAlternatives
),
277 nType (nFailureType
),
283 SpellAlternatives::~SpellAlternatives()
288 OUString SAL_CALL
SpellAlternatives::getWord()
289 throw(RuntimeException
)
291 MutexGuard
aGuard( GetLinguMutex() );
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() );
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() );
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() );
352 void SpellAlternatives::SetFailureType(INT16 nTypeP
)
354 MutexGuard
aGuard( GetLinguMutex() );
359 void SpellAlternatives::SetAlternatives( const Sequence
< OUString
> &rAlt
)
361 MutexGuard
aGuard( GetLinguMutex() );
366 ///////////////////////////////////////////////////////////////////////////
368 } // namespace linguistic