1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_linguistic.hxx"
26
27 #include "linguistic/misc.hxx"
28
29 #include "sprophelp.hxx"
30 #include "linguistic/lngprops.hxx"
31 #include <tools/debug.hxx>
32
33 #include <com/sun/star/linguistic2/LinguServiceEvent.hpp>
34 #include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
35 #include <com/sun/star/linguistic2/XLinguServiceEventListener.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <osl/mutex.hxx>
38
39 //using namespace utl;
40 using namespace osl;
41 using namespace rtl;
42 using namespace com::sun::star;
43 using namespace com::sun::star::beans;
44 using namespace com::sun::star::lang;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::linguistic2;
47 using namespace linguistic;
48
49
50 #define A2OU(x) ::rtl::OUString::createFromAscii( x )
51
52 ///////////////////////////////////////////////////////////////////////////
53
54
PropertyChgHelper(const Reference<XInterface> & rxSource,Reference<XPropertySet> & rxPropSet,const char * pPropNames[],USHORT nPropCount)55 PropertyChgHelper::PropertyChgHelper(
56 const Reference< XInterface > & rxSource,
57 Reference< XPropertySet > &rxPropSet,
58 const char *pPropNames[], USHORT nPropCount ) :
59 xMyEvtObj (rxSource),
60 xPropSet (rxPropSet),
61 aPropNames (nPropCount),
62 aLngSvcEvtListeners (GetLinguMutex())
63 {
64 OUString *pName = aPropNames.getArray();
65 for (INT32 i = 0; i < nPropCount; ++i)
66 {
67 pName[i] = A2OU( pPropNames[i] );
68 }
69 }
70
71
PropertyChgHelper(const PropertyChgHelper & rHelper)72 PropertyChgHelper::PropertyChgHelper( const PropertyChgHelper &rHelper ) :
73 aLngSvcEvtListeners (GetLinguMutex())
74 {
75 xPropSet = rHelper.xPropSet;
76 aPropNames = rHelper.aPropNames;
77 AddAsPropListener();
78
79 xMyEvtObj = rHelper.xMyEvtObj;
80 }
81
82
~PropertyChgHelper()83 PropertyChgHelper::~PropertyChgHelper()
84 {
85 }
86
87
AddAsPropListener()88 void PropertyChgHelper::AddAsPropListener()
89 {
90 if (xPropSet.is())
91 {
92 INT32 nLen = aPropNames.getLength();
93 const OUString *pPropName = aPropNames.getConstArray();
94 for (INT32 i = 0; i < nLen; ++i)
95 {
96 if (pPropName[i].getLength())
97 xPropSet->addPropertyChangeListener( pPropName[i], this );
98 }
99 }
100 }
101
RemoveAsPropListener()102 void PropertyChgHelper::RemoveAsPropListener()
103 {
104 if (xPropSet.is())
105 {
106 INT32 nLen = aPropNames.getLength();
107 const OUString *pPropName = aPropNames.getConstArray();
108 for (INT32 i = 0; i < nLen; ++i)
109 {
110 if (pPropName[i].getLength())
111 xPropSet->removePropertyChangeListener( pPropName[i], this );
112 }
113 }
114 }
115
116
LaunchEvent(const LinguServiceEvent & rEvt)117 void PropertyChgHelper::LaunchEvent( const LinguServiceEvent &rEvt )
118 {
119 cppu::OInterfaceIteratorHelper aIt( aLngSvcEvtListeners );
120 while (aIt.hasMoreElements())
121 {
122 Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY );
123 if (xRef.is())
124 xRef->processLinguServiceEvent( rEvt );
125 }
126 }
127
128
disposing(const EventObject & rSource)129 void SAL_CALL PropertyChgHelper::disposing( const EventObject& rSource )
130 throw(RuntimeException)
131 {
132 MutexGuard aGuard( GetLinguMutex() );
133 if (rSource.Source == xPropSet)
134 {
135 RemoveAsPropListener();
136 xPropSet = NULL;
137 aPropNames.realloc( 0 );
138 }
139 }
140
141
142 sal_Bool SAL_CALL
addLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxListener)143 PropertyChgHelper::addLinguServiceEventListener(
144 const Reference< XLinguServiceEventListener >& rxListener )
145 throw(RuntimeException)
146 {
147 MutexGuard aGuard( GetLinguMutex() );
148
149 BOOL bRes = FALSE;
150 if (rxListener.is())
151 {
152 INT32 nCount = aLngSvcEvtListeners.getLength();
153 bRes = aLngSvcEvtListeners.addInterface( rxListener ) != nCount;
154 }
155 return bRes;
156 }
157
158
159 sal_Bool SAL_CALL
removeLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxListener)160 PropertyChgHelper::removeLinguServiceEventListener(
161 const Reference< XLinguServiceEventListener >& rxListener )
162 throw(RuntimeException)
163 {
164 MutexGuard aGuard( GetLinguMutex() );
165
166 BOOL bRes = FALSE;
167 if (rxListener.is())
168 {
169 INT32 nCount = aLngSvcEvtListeners.getLength();
170 bRes = aLngSvcEvtListeners.removeInterface( rxListener ) != nCount;
171 }
172 return bRes;
173 }
174
175 ///////////////////////////////////////////////////////////////////////////
176
177 static const char *aSP[] =
178 {
179 UPN_IS_GERMAN_PRE_REFORM,
180 UPN_IS_IGNORE_CONTROL_CHARACTERS,
181 UPN_IS_USE_DICTIONARY_LIST,
182 UPN_IS_SPELL_UPPER_CASE,
183 UPN_IS_SPELL_WITH_DIGITS,
184 UPN_IS_SPELL_CAPITALIZATION
185 };
186
187
PropertyHelper_Spell(const Reference<XInterface> & rxSource,Reference<XPropertySet> & rxPropSet)188 PropertyHelper_Spell::PropertyHelper_Spell(
189 const Reference< XInterface > & rxSource,
190 Reference< XPropertySet > &rxPropSet ) :
191 PropertyChgHelper ( rxSource, rxPropSet, aSP, sizeof(aSP) / sizeof(aSP[0]) )
192 {
193 SetDefault();
194 INT32 nLen = GetPropNames().getLength();
195 if (rxPropSet.is() && nLen)
196 {
197 const OUString *pPropName = GetPropNames().getConstArray();
198 for (INT32 i = 0; i < nLen; ++i)
199 {
200 BOOL *pbVal = NULL,
201 *pbResVal = NULL;
202
203 if (A2OU( UPN_IS_GERMAN_PRE_REFORM ) == pPropName[i])
204 {
205 pbVal = &bIsGermanPreReform;
206 pbResVal = &bResIsGermanPreReform;
207 }
208 else if (A2OU( UPN_IS_IGNORE_CONTROL_CHARACTERS ) == pPropName[i])
209 {
210 pbVal = &bIsIgnoreControlCharacters;
211 pbResVal = &bResIsIgnoreControlCharacters;
212 }
213 else if (A2OU( UPN_IS_USE_DICTIONARY_LIST ) == pPropName[i])
214 {
215 pbVal = &bIsUseDictionaryList;
216 pbResVal = &bResIsUseDictionaryList;
217 }
218 else if (A2OU( UPN_IS_SPELL_UPPER_CASE ) == pPropName[i])
219 {
220 pbVal = &bIsSpellUpperCase;
221 pbResVal = &bResIsSpellUpperCase;
222 }
223 else if (A2OU( UPN_IS_SPELL_WITH_DIGITS ) == pPropName[i])
224 {
225 pbVal = &bIsSpellWithDigits;
226 pbResVal = &bResIsSpellWithDigits;
227 }
228 else if (A2OU( UPN_IS_SPELL_CAPITALIZATION ) == pPropName[i])
229 {
230 pbVal = &bIsSpellCapitalization;
231 pbResVal = &bResIsSpellCapitalization;
232 }
233
234 if (pbVal && pbResVal)
235 {
236 rxPropSet->getPropertyValue( pPropName[i] ) >>= *pbVal;
237 *pbResVal = *pbVal;
238 }
239 }
240 }
241 }
242
243
~PropertyHelper_Spell()244 PropertyHelper_Spell::~PropertyHelper_Spell()
245 {
246 }
247
248
SetDefault()249 void PropertyHelper_Spell::SetDefault()
250 {
251 bResIsGermanPreReform = bIsGermanPreReform = FALSE;
252 bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters = TRUE;
253 bResIsUseDictionaryList = bIsUseDictionaryList = TRUE;
254 bResIsSpellUpperCase = bIsSpellUpperCase = FALSE;
255 bResIsSpellWithDigits = bIsSpellWithDigits = FALSE;
256 bResIsSpellCapitalization = bIsSpellCapitalization = TRUE;
257 }
258
259
260 void SAL_CALL
propertyChange(const PropertyChangeEvent & rEvt)261 PropertyHelper_Spell::propertyChange( const PropertyChangeEvent& rEvt )
262 throw(RuntimeException)
263 {
264 MutexGuard aGuard( GetLinguMutex() );
265
266 if (GetPropSet().is() && rEvt.Source == GetPropSet())
267 {
268 INT16 nLngSvcFlags = 0;
269 BOOL bSCWA = FALSE, // SPELL_CORRECT_WORDS_AGAIN ?
270 bSWWA = FALSE; // SPELL_WRONG_WORDS_AGAIN ?
271
272 BOOL *pbVal = NULL;
273 switch (rEvt.PropertyHandle)
274 {
275 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
276 {
277 pbVal = &bIsIgnoreControlCharacters;
278 break;
279 }
280 case UPH_IS_GERMAN_PRE_REFORM :
281 {
282 pbVal = &bIsGermanPreReform;
283 bSCWA = bSWWA = TRUE;
284 break;
285 }
286 case UPH_IS_USE_DICTIONARY_LIST :
287 {
288 pbVal = &bIsUseDictionaryList;
289 bSCWA = bSWWA = TRUE;
290 break;
291 }
292 case UPH_IS_SPELL_UPPER_CASE :
293 {
294 pbVal = &bIsSpellUpperCase;
295 bSCWA = FALSE == *pbVal; // FALSE->TRUE change?
296 bSWWA = !bSCWA; // TRUE->FALSE change?
297 break;
298 }
299 case UPH_IS_SPELL_WITH_DIGITS :
300 {
301 pbVal = &bIsSpellWithDigits;
302 bSCWA = FALSE == *pbVal; // FALSE->TRUE change?
303 bSWWA = !bSCWA; // TRUE->FALSE change?
304 break;
305 }
306 case UPH_IS_SPELL_CAPITALIZATION :
307 {
308 pbVal = &bIsSpellCapitalization;
309 bSCWA = FALSE == *pbVal; // FALSE->TRUE change?
310 bSWWA = !bSCWA; // TRUE->FALSE change?
311 break;
312 }
313 default:
314 DBG_ERROR( "unknown property" );
315 }
316 if (pbVal)
317 rEvt.NewValue >>= *pbVal;
318
319 if (bSCWA)
320 nLngSvcFlags |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
321 if (bSWWA)
322 nLngSvcFlags |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
323 if (nLngSvcFlags)
324 {
325 LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags );
326 LaunchEvent( aEvt );
327 }
328 }
329 }
330
331
SetTmpPropVals(const PropertyValues & rPropVals)332 void PropertyHelper_Spell::SetTmpPropVals( const PropertyValues &rPropVals )
333 {
334 // set return value to default value unless there is an
335 // explicitly supplied temporary value
336 bResIsGermanPreReform = bIsGermanPreReform;
337 bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters;
338 bResIsUseDictionaryList = bIsUseDictionaryList;
339 bResIsSpellUpperCase = bIsSpellUpperCase;
340 bResIsSpellWithDigits = bIsSpellWithDigits;
341 bResIsSpellCapitalization = bIsSpellCapitalization;
342 //
343 INT32 nLen = rPropVals.getLength();
344 if (nLen)
345 {
346 const PropertyValue *pVal = rPropVals.getConstArray();
347 for (INT32 i = 0; i < nLen; ++i)
348 {
349 BOOL *pbResVal = NULL;
350 switch (pVal[i].Handle)
351 {
352 case UPH_IS_GERMAN_PRE_REFORM : pbResVal = &bResIsGermanPreReform; break;
353 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbResVal = &bResIsIgnoreControlCharacters; break;
354 case UPH_IS_USE_DICTIONARY_LIST : pbResVal = &bResIsUseDictionaryList; break;
355 case UPH_IS_SPELL_UPPER_CASE : pbResVal = &bResIsSpellUpperCase; break;
356 case UPH_IS_SPELL_WITH_DIGITS : pbResVal = &bResIsSpellWithDigits; break;
357 case UPH_IS_SPELL_CAPITALIZATION : pbResVal = &bResIsSpellCapitalization; break;
358 default:
359 DBG_ERROR( "unknown property" );
360 }
361 if (pbResVal)
362 pVal[i].Value >>= *pbResVal;
363 }
364 }
365 }
366
367 ///////////////////////////////////////////////////////////////////////////
368
369