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