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 <tools/debug.hxx>
28 
29 #include <com/sun/star/linguistic2/LinguServiceEvent.hpp>
30 #include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
31 #include <com/sun/star/linguistic2/XLinguServiceEventListener.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <osl/mutex.hxx>
34 
35 #include <linguistic/misc.hxx>
36 #include <linguistic/lngprops.hxx>
37 
38 #include <linguistic/lngprophelp.hxx>
39 
40 
41 //using namespace utl;
42 using namespace osl;
43 using namespace rtl;
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 using namespace linguistic;
50 
51 namespace linguistic
52 {
53 
54 ///////////////////////////////////////////////////////////////////////////
55 
56 static const char *aCH[] =
57 {
58 	UPN_IS_IGNORE_CONTROL_CHARACTERS,
59 	UPN_IS_USE_DICTIONARY_LIST,
60 };
61 
62 static int nCHCount = sizeof(aCH) / sizeof(aCH[0]);
63 
64 
PropertyChgHelper(const Reference<XInterface> & rxSource,Reference<XPropertySet> & rxPropSet,int nAllowedEvents)65 PropertyChgHelper::PropertyChgHelper(
66 		const Reference< XInterface > &rxSource,
67 		Reference< XPropertySet > &rxPropSet,
68 		int nAllowedEvents ) :
69     PropertyChgHelperBase(),
70     aPropNames          (nCHCount),
71     xMyEvtObj           (rxSource),
72     aLngSvcEvtListeners (GetLinguMutex()),
73     xPropSet            (rxPropSet),
74     nEvtFlags           (nAllowedEvents)
75 {
76 	OUString *pName = aPropNames.getArray();
77 	for (sal_Int32 i = 0;  i < nCHCount;  ++i)
78 	{
79 		pName[i] = A2OU( aCH[i] );
80 	}
81 
82 	SetDefaultValues();
83 }
84 
85 
PropertyChgHelper(const PropertyChgHelper & rHelper)86 PropertyChgHelper::PropertyChgHelper( const PropertyChgHelper &rHelper ) :
87     PropertyChgHelperBase(),
88     aLngSvcEvtListeners (GetLinguMutex())
89 {
90 	RemoveAsPropListener();
91     aPropNames  = rHelper.aPropNames;
92     xMyEvtObj   = rHelper.xMyEvtObj;
93     xPropSet    = rHelper.xPropSet;
94     nEvtFlags   = rHelper.nEvtFlags;
95     AddAsPropListener();
96 
97 	SetDefaultValues();
98 	GetCurrentValues();
99 }
100 
101 
~PropertyChgHelper()102 PropertyChgHelper::~PropertyChgHelper()
103 {
104 }
105 
106 
AddPropNames(const char * pNewNames[],sal_Int32 nCount)107 void PropertyChgHelper::AddPropNames( const char *pNewNames[], sal_Int32 nCount )
108 {
109 	if (pNewNames && nCount)
110 	{
111 		sal_Int32 nLen = GetPropNames().getLength();
112 		GetPropNames().realloc( nLen + nCount );
113 		OUString *pName = GetPropNames().getArray();
114 		for (sal_Int32 i = 0;  i < nCount;  ++i)
115 		{
116 			pName[ nLen + i ] = A2OU( pNewNames[ i ] );
117 		}
118 	}
119 }
120 
121 
SetDefaultValues()122 void PropertyChgHelper::SetDefaultValues()
123 {
124 	bResIsIgnoreControlCharacters	= bIsIgnoreControlCharacters	= sal_True;
125 	bResIsUseDictionaryList			= bIsUseDictionaryList			= sal_True;
126 }
127 
128 
GetCurrentValues()129 void PropertyChgHelper::GetCurrentValues()
130 {
131 	sal_Int32 nLen = GetPropNames().getLength();
132 	if (GetPropSet().is() && nLen)
133 	{
134 		const OUString *pPropName = GetPropNames().getConstArray();
135 		for (sal_Int32 i = 0;  i < nLen;  ++i)
136 		{
137 			sal_Bool *pbVal		= NULL,
138 				 *pbResVal	= NULL;
139 
140             if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_IS_IGNORE_CONTROL_CHARACTERS ) ))
141 			{
142 				pbVal	 = &bIsIgnoreControlCharacters;
143 				pbResVal = &bResIsIgnoreControlCharacters;
144 			}
145             else if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_IS_USE_DICTIONARY_LIST ) ))
146 			{
147 				pbVal	 = &bIsUseDictionaryList;
148 				pbResVal = &bResIsUseDictionaryList;
149 			}
150 
151 			if (pbVal && pbResVal)
152 			{
153 				GetPropSet()->getPropertyValue( pPropName[i] ) >>= *pbVal;
154 				*pbResVal = *pbVal;
155 			}
156 		}
157 	}
158 }
159 
160 
SetTmpPropVals(const PropertyValues & rPropVals)161 void PropertyChgHelper::SetTmpPropVals( const PropertyValues &rPropVals )
162 {
163 	// return value is default value unless there is an explicitly supplied
164 	// temporary value
165 	bResIsIgnoreControlCharacters	= bIsIgnoreControlCharacters;
166 	bResIsUseDictionaryList			= bIsUseDictionaryList;
167 	//
168 	sal_Int32 nLen = rPropVals.getLength();
169 	if (nLen)
170 	{
171 		const PropertyValue *pVal = rPropVals.getConstArray();
172 		for (sal_Int32 i = 0;  i < nLen;  ++i)
173 		{
174 			sal_Bool  *pbResVal = NULL;
175 			switch (pVal[i].Handle)
176 			{
177 				case UPH_IS_IGNORE_CONTROL_CHARACTERS :
178 						pbResVal = &bResIsIgnoreControlCharacters; break;
179 				case UPH_IS_USE_DICTIONARY_LIST		:
180 						pbResVal = &bResIsUseDictionaryList; break;
181 				default:
182 						;
183                     //DBG_ASSERT( 0, "unknown property" );
184 			}
185 			if (pbResVal)
186 				pVal[i].Value >>= *pbResVal;
187 		}
188 	}
189 }
190 
191 
propertyChange_Impl(const PropertyChangeEvent & rEvt)192 sal_Bool PropertyChgHelper::propertyChange_Impl( const PropertyChangeEvent& rEvt )
193 {
194 	sal_Bool bRes = sal_False;
195 
196 	if (GetPropSet().is()  &&  rEvt.Source == GetPropSet())
197 	{
198 		sal_Int16 nLngSvcFlags = (nEvtFlags & AE_HYPHENATOR) ?
199 					LinguServiceEventFlags::HYPHENATE_AGAIN : 0;
200 		sal_Bool bSCWA = sal_False,	// SPELL_CORRECT_WORDS_AGAIN ?
201 			 bSWWA = sal_False;	// SPELL_WRONG_WORDS_AGAIN ?
202 
203 		sal_Bool  *pbVal = NULL;
204 		switch (rEvt.PropertyHandle)
205 		{
206 			case UPH_IS_IGNORE_CONTROL_CHARACTERS :
207 			{
208 				pbVal = &bIsIgnoreControlCharacters;
209 				nLngSvcFlags = 0;
210 				break;
211 			}
212 			case UPH_IS_USE_DICTIONARY_LIST		  :
213 			{
214 				pbVal = &bIsUseDictionaryList;
215 				bSCWA = bSWWA = sal_True;
216 				break;
217 			}
218 			default:
219 			{
220 				bRes = sal_False;
221                 //DBG_ASSERT( 0, "unknown property" );
222 			}
223 		}
224 		if (pbVal)
225 			rEvt.NewValue >>= *pbVal;
226 
227 		bRes = 0 != pbVal;	// sth changed?
228 		if (bRes)
229 		{
230 			sal_Bool bSpellEvts = (nEvtFlags & AE_SPELLCHECKER) ? sal_True : sal_False;
231 			if (bSCWA && bSpellEvts)
232 				nLngSvcFlags |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
233 			if (bSWWA && bSpellEvts)
234 				nLngSvcFlags |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
235 			if (nLngSvcFlags)
236 			{
237 				LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags );
238 				LaunchEvent( aEvt );
239 			}
240 		}
241 	}
242 
243 	return bRes;
244 }
245 
246 
247 void SAL_CALL
propertyChange(const PropertyChangeEvent & rEvt)248 	PropertyChgHelper::propertyChange( const PropertyChangeEvent& rEvt )
249 		throw(RuntimeException)
250 {
251 	MutexGuard	aGuard( GetLinguMutex() );
252 	propertyChange_Impl( rEvt );
253 }
254 
255 
AddAsPropListener()256 void PropertyChgHelper::AddAsPropListener()
257 {
258 	if (xPropSet.is())
259 	{
260 		sal_Int32 nLen = aPropNames.getLength();
261 		const OUString *pPropName = aPropNames.getConstArray();
262 		for (sal_Int32 i = 0;  i < nLen;  ++i)
263 		{
264 			if (pPropName[i].getLength())
265 				xPropSet->addPropertyChangeListener( pPropName[i], this );
266 		}
267 	}
268 }
269 
RemoveAsPropListener()270 void PropertyChgHelper::RemoveAsPropListener()
271 {
272 	if (xPropSet.is())
273 	{
274 		sal_Int32 nLen = aPropNames.getLength();
275 		const OUString *pPropName = aPropNames.getConstArray();
276 		for (sal_Int32 i = 0;  i < nLen;  ++i)
277 		{
278 			if (pPropName[i].getLength())
279 				xPropSet->removePropertyChangeListener( pPropName[i], this );
280 		}
281 	}
282 }
283 
284 
LaunchEvent(const LinguServiceEvent & rEvt)285 void PropertyChgHelper::LaunchEvent( const LinguServiceEvent &rEvt )
286 {
287 	cppu::OInterfaceIteratorHelper aIt( aLngSvcEvtListeners );
288 	while (aIt.hasMoreElements())
289 	{
290 		Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY );
291 		if (xRef.is())
292 			xRef->processLinguServiceEvent( rEvt );
293 	}
294 }
295 
296 
disposing(const EventObject & rSource)297 void SAL_CALL PropertyChgHelper::disposing( const EventObject& rSource )
298 		throw(RuntimeException)
299 {
300 	MutexGuard	aGuard( GetLinguMutex() );
301 	if (rSource.Source == xPropSet)
302 	{
303 		RemoveAsPropListener();
304 		xPropSet = NULL;
305 		aPropNames.realloc( 0 );
306 	}
307 }
308 
309 
310 sal_Bool SAL_CALL
addLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxListener)311 	PropertyChgHelper::addLinguServiceEventListener(
312 			const Reference< XLinguServiceEventListener >& rxListener )
313 		throw(RuntimeException)
314 {
315 	MutexGuard	aGuard( GetLinguMutex() );
316 
317 	sal_Bool bRes = sal_False;
318 	if (rxListener.is())
319 	{
320 		sal_Int32	nCount = aLngSvcEvtListeners.getLength();
321 		bRes = aLngSvcEvtListeners.addInterface( rxListener ) != nCount;
322 	}
323 	return bRes;
324 }
325 
326 
327 sal_Bool SAL_CALL
removeLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxListener)328 	PropertyChgHelper::removeLinguServiceEventListener(
329 			const Reference< XLinguServiceEventListener >& rxListener )
330 		throw(RuntimeException)
331 {
332 	MutexGuard	aGuard( GetLinguMutex() );
333 
334 	sal_Bool bRes = sal_False;
335 	if (rxListener.is())
336 	{
337 		sal_Int32	nCount = aLngSvcEvtListeners.getLength();
338 		bRes = aLngSvcEvtListeners.removeInterface( rxListener ) != nCount;
339 	}
340 	return bRes;
341 }
342 
343 ///////////////////////////////////////////////////////////////////////////
344 
345 
PropertyHelper_Thes(const Reference<XInterface> & rxSource,Reference<XPropertySet> & rxPropSet)346 PropertyHelper_Thes::PropertyHelper_Thes(
347 		const Reference< XInterface > &rxSource,
348 		Reference< XPropertySet > &rxPropSet ) :
349 	PropertyChgHelper	( rxSource, rxPropSet, 0 )
350 {
351 	SetDefaultValues();
352 	GetCurrentValues();
353 }
354 
355 
~PropertyHelper_Thes()356 PropertyHelper_Thes::~PropertyHelper_Thes()
357 {
358 }
359 
360 
361 void SAL_CALL
propertyChange(const PropertyChangeEvent & rEvt)362 	PropertyHelper_Thes::propertyChange( const PropertyChangeEvent& rEvt )
363 		throw(RuntimeException)
364 {
365 	MutexGuard	aGuard( GetLinguMutex() );
366     PropertyChgHelper::propertyChange_Impl( rEvt );
367 }
368 
369 
370 ///////////////////////////////////////////////////////////////////////////
371 
372 // list of properties from the property set to be used
373 // and listened to
374 static const char *aSP[] =
375 {
376 	UPN_IS_SPELL_UPPER_CASE,
377 	UPN_IS_SPELL_WITH_DIGITS,
378     UPN_IS_SPELL_CAPITALIZATION
379 };
380 
381 
PropertyHelper_Spell(const Reference<XInterface> & rxSource,Reference<XPropertySet> & rxPropSet)382 PropertyHelper_Spell::PropertyHelper_Spell(
383 		const Reference< XInterface > & rxSource,
384 		Reference< XPropertySet > &rxPropSet ) :
385 	PropertyChgHelper	( rxSource, rxPropSet, AE_SPELLCHECKER )
386 {
387 	AddPropNames( aSP, sizeof(aSP) / sizeof(aSP[0]) );
388 	SetDefaultValues();
389 	GetCurrentValues();
390 
391     nResMaxNumberOfSuggestions = GetDefaultNumberOfSuggestions();
392 }
393 
394 
~PropertyHelper_Spell()395 PropertyHelper_Spell::~PropertyHelper_Spell()
396 {
397 }
398 
399 
SetDefaultValues()400 void PropertyHelper_Spell::SetDefaultValues()
401 {
402 	PropertyChgHelper::SetDefaultValues();
403 
404 	bResIsSpellUpperCase		= bIsSpellUpperCase			= sal_False;
405 	bResIsSpellWithDigits		= bIsSpellWithDigits		= sal_False;
406 	bResIsSpellCapitalization	= bIsSpellCapitalization	= sal_True;
407 }
408 
409 
GetCurrentValues()410 void PropertyHelper_Spell::GetCurrentValues()
411 {
412 	PropertyChgHelper::GetCurrentValues();
413 
414 	sal_Int32 nLen = GetPropNames().getLength();
415 	if (GetPropSet().is() && nLen)
416 	{
417 		const OUString *pPropName = GetPropNames().getConstArray();
418 		for (sal_Int32 i = 0;  i < nLen;  ++i)
419 		{
420 			sal_Bool *pbVal		= NULL,
421 				 *pbResVal	= NULL;
422 
423             if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_IS_SPELL_UPPER_CASE ) ))
424 			{
425 				pbVal	 = &bIsSpellUpperCase;
426 				pbResVal = &bResIsSpellUpperCase;
427 			}
428             else if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_IS_SPELL_WITH_DIGITS ) ))
429 			{
430 				pbVal	 = &bIsSpellWithDigits;
431 				pbResVal = &bResIsSpellWithDigits;
432 			}
433             else if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_IS_SPELL_CAPITALIZATION ) ))
434 			{
435 				pbVal	 = &bIsSpellCapitalization;
436 				pbResVal = &bResIsSpellCapitalization;
437 			}
438 
439 			if (pbVal && pbResVal)
440 			{
441 				GetPropSet()->getPropertyValue( pPropName[i] ) >>= *pbVal;
442 				*pbResVal = *pbVal;
443 			}
444 		}
445 	}
446 }
447 
448 
propertyChange_Impl(const PropertyChangeEvent & rEvt)449 sal_Bool PropertyHelper_Spell::propertyChange_Impl( const PropertyChangeEvent& rEvt )
450 {
451 	sal_Bool bRes = PropertyChgHelper::propertyChange_Impl( rEvt );
452 
453 	if (!bRes  &&  GetPropSet().is()  &&  rEvt.Source == GetPropSet())
454 	{
455 		sal_Int16 nLngSvcFlags = 0;
456 		sal_Bool bSCWA = sal_False,	// SPELL_CORRECT_WORDS_AGAIN ?
457 			 bSWWA = sal_False;	// SPELL_WRONG_WORDS_AGAIN ?
458 
459 		sal_Bool *pbVal = NULL;
460 		switch (rEvt.PropertyHandle)
461 		{
462 			case UPH_IS_SPELL_UPPER_CASE		  :
463 			{
464 				pbVal = &bIsSpellUpperCase;
465 				bSCWA = sal_False == *pbVal;	// sal_False->sal_True change?
466 				bSWWA = !bSCWA;				// sal_True->sal_False change?
467 				break;
468 			}
469 			case UPH_IS_SPELL_WITH_DIGITS		  :
470 			{
471 				pbVal = &bIsSpellWithDigits;
472 				bSCWA = sal_False == *pbVal;	// sal_False->sal_True change?
473 				bSWWA = !bSCWA;				// sal_True->sal_False change?
474 				break;
475 			}
476 			case UPH_IS_SPELL_CAPITALIZATION	  :
477 			{
478 				pbVal = &bIsSpellCapitalization;
479 				bSCWA = sal_False == *pbVal;	// sal_False->sal_True change?
480 				bSWWA = !bSCWA;				// sal_True->sal_False change?
481 				break;
482 			}
483 			default:
484                 DBG_ASSERT( 0, "unknown property" );
485 		}
486 		if (pbVal)
487 			rEvt.NewValue >>= *pbVal;
488 
489 		bRes = (pbVal != 0);
490 		if (bRes)
491 		{
492 			if (bSCWA)
493 				nLngSvcFlags |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
494 			if (bSWWA)
495 				nLngSvcFlags |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
496 			if (nLngSvcFlags)
497 			{
498 				LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags );
499 				LaunchEvent( aEvt );
500 			}
501 		}
502 	}
503 
504 	return bRes;
505 }
506 
507 
508 void SAL_CALL
propertyChange(const PropertyChangeEvent & rEvt)509 	PropertyHelper_Spell::propertyChange( const PropertyChangeEvent& rEvt )
510 		throw(RuntimeException)
511 {
512 	MutexGuard	aGuard( GetLinguMutex() );
513 	propertyChange_Impl( rEvt );
514 }
515 
516 
SetTmpPropVals(const PropertyValues & rPropVals)517 void PropertyHelper_Spell::SetTmpPropVals( const PropertyValues &rPropVals )
518 {
519 	PropertyChgHelper::SetTmpPropVals( rPropVals );
520 
521 	// return value is default value unless there is an explicitly supplied
522 	// temporary value
523     nResMaxNumberOfSuggestions  = GetDefaultNumberOfSuggestions();
524 	bResIsSpellWithDigits		= bIsSpellWithDigits;
525 	bResIsSpellCapitalization	= bIsSpellCapitalization;
526 	//
527 	sal_Int32 nLen = rPropVals.getLength();
528 	if (nLen)
529 	{
530 		const PropertyValue *pVal = rPropVals.getConstArray();
531 		for (sal_Int32 i = 0;  i < nLen;  ++i)
532 		{
533             if (pVal[i].Name.equalsAscii( UPN_MAX_NUMBER_OF_SUGGESTIONS ))
534             {
535                 pVal[i].Value >>= nResMaxNumberOfSuggestions;
536             }
537             else
538             {
539                 sal_Bool *pbResVal = NULL;
540                 switch (pVal[i].Handle)
541                 {
542                     case UPH_IS_SPELL_UPPER_CASE     : pbResVal = &bResIsSpellUpperCase; break;
543                     case UPH_IS_SPELL_WITH_DIGITS    : pbResVal = &bResIsSpellWithDigits; break;
544                     case UPH_IS_SPELL_CAPITALIZATION : pbResVal = &bResIsSpellCapitalization; break;
545                     default:
546                         DBG_ASSERT( 0, "unknown property" );
547                 }
548                 if (pbResVal)
549                     pVal[i].Value >>= *pbResVal;
550             }
551 		}
552 	}
553 }
554 
GetDefaultNumberOfSuggestions() const555 sal_Int16 PropertyHelper_Spell::GetDefaultNumberOfSuggestions() const
556 {
557     return 16;
558 }
559 
560 ///////////////////////////////////////////////////////////////////////////
561 
562 static const char *aHP[] =
563 {
564 	UPN_HYPH_MIN_LEADING,
565 	UPN_HYPH_MIN_TRAILING,
566 	UPN_HYPH_MIN_WORD_LENGTH
567 };
568 
569 
PropertyHelper_Hyphen(const Reference<XInterface> & rxSource,Reference<XPropertySet> & rxPropSet)570 PropertyHelper_Hyphen::PropertyHelper_Hyphen(
571 		const Reference< XInterface > & rxSource,
572 		Reference< XPropertySet > &rxPropSet ) :
573 	PropertyChgHelper	( rxSource, rxPropSet, AE_HYPHENATOR )
574 {
575 	AddPropNames( aHP, sizeof(aHP) / sizeof(aHP[0]) );
576 	SetDefaultValues();
577 	GetCurrentValues();
578 }
579 
580 
~PropertyHelper_Hyphen()581 PropertyHelper_Hyphen::~PropertyHelper_Hyphen()
582 {
583 }
584 
585 
SetDefaultValues()586 void PropertyHelper_Hyphen::SetDefaultValues()
587 {
588 	PropertyChgHelper::SetDefaultValues();
589 
590 	nResHyphMinLeading	 	= nHyphMinLeading		= 2;
591 	nResHyphMinTrailing	 	= nHyphMinTrailing		= 2;
592 	nResHyphMinWordLength	= nHyphMinWordLength	= 0;
593 }
594 
595 
GetCurrentValues()596 void PropertyHelper_Hyphen::GetCurrentValues()
597 {
598 	PropertyChgHelper::GetCurrentValues();
599 
600 	sal_Int32 nLen = GetPropNames().getLength();
601 	if (GetPropSet().is() && nLen)
602 	{
603 		const OUString *pPropName = GetPropNames().getConstArray();
604 		for (sal_Int32 i = 0;  i < nLen;  ++i)
605 		{
606 			sal_Int16  *pnVal	 = NULL,
607 				   *pnResVal = NULL;
608 
609             if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_HYPH_MIN_LEADING ) ))
610 			{
611 				pnVal	 = &nHyphMinLeading;
612 				pnResVal = &nResHyphMinLeading;
613 			}
614             else if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_HYPH_MIN_TRAILING ) ))
615 			{
616 				pnVal	 = &nHyphMinTrailing;
617 				pnResVal = &nResHyphMinTrailing;
618 			}
619             else if (pPropName[i].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( UPN_HYPH_MIN_WORD_LENGTH ) ))
620 			{
621 				pnVal	 = &nHyphMinWordLength;
622 				pnResVal = &nResHyphMinWordLength;
623 			}
624 
625 			if (pnVal && pnResVal)
626 			{
627 				GetPropSet()->getPropertyValue( pPropName[i] ) >>= *pnVal;
628 				*pnResVal = *pnVal;
629 			}
630 		}
631 	}
632 }
633 
634 
propertyChange_Impl(const PropertyChangeEvent & rEvt)635 sal_Bool PropertyHelper_Hyphen::propertyChange_Impl( const PropertyChangeEvent& rEvt )
636 {
637 	sal_Bool bRes = PropertyChgHelper::propertyChange_Impl( rEvt );
638 
639 	if (!bRes  &&  GetPropSet().is()  &&  rEvt.Source == GetPropSet())
640 	{
641 		sal_Int16 nLngSvcFlags = LinguServiceEventFlags::HYPHENATE_AGAIN;
642 
643 		sal_Int16	*pnVal = NULL;
644 		switch (rEvt.PropertyHandle)
645 		{
646 			case UPH_HYPH_MIN_LEADING	  : pnVal = &nHyphMinLeading; break;
647 			case UPH_HYPH_MIN_TRAILING	  : pnVal = &nHyphMinTrailing; break;
648 			case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &nHyphMinWordLength; break;
649 			default:
650                 DBG_ASSERT( 0, "unknown property" );
651 		}
652 		if (pnVal)
653 			rEvt.NewValue >>= *pnVal;
654 
655 		bRes = (pnVal != 0);
656 		if (bRes)
657 		{
658 			if (nLngSvcFlags)
659 			{
660 				LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags );
661 				LaunchEvent( aEvt );
662 			}
663 		}
664 	}
665 
666 	return bRes;
667 }
668 
669 
670 void SAL_CALL
propertyChange(const PropertyChangeEvent & rEvt)671     PropertyHelper_Hyphen::propertyChange( const PropertyChangeEvent& rEvt )
672 		throw(RuntimeException)
673 {
674 	MutexGuard	aGuard( GetLinguMutex() );
675 	propertyChange_Impl( rEvt );
676 }
677 
678 
SetTmpPropVals(const PropertyValues & rPropVals)679 void PropertyHelper_Hyphen::SetTmpPropVals( const PropertyValues &rPropVals )
680 {
681 	PropertyChgHelper::SetTmpPropVals( rPropVals );
682 
683 	// return value is default value unless there is an explicitly supplied
684 	// temporary value
685 	nResHyphMinLeading	 	= nHyphMinLeading;
686 	nResHyphMinTrailing	 	= nHyphMinTrailing;
687 	nResHyphMinWordLength	= nHyphMinWordLength;
688 	//
689 	sal_Int32 nLen = rPropVals.getLength();
690 	if (nLen)
691 	{
692 		const PropertyValue *pVal = rPropVals.getConstArray();
693 		for (sal_Int32 i = 0;  i < nLen;  ++i)
694 		{
695 			sal_Int16	*pnResVal = NULL;
696 			switch (pVal[i].Handle)
697 			{
698 				case UPH_HYPH_MIN_LEADING	  : pnResVal = &nResHyphMinLeading; break;
699 				case UPH_HYPH_MIN_TRAILING	  : pnResVal = &nResHyphMinTrailing; break;
700 				case UPH_HYPH_MIN_WORD_LENGTH : pnResVal = &nResHyphMinWordLength; break;
701 				default:
702                     DBG_ASSERT( 0, "unknown property" );
703 			}
704 			if (pnResVal)
705 				pVal[i].Value >>= *pnResVal;
706 		}
707 	}
708 }
709 
PropertyHelper_Thesaurus(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rxSource,::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rxPropSet)710 PropertyHelper_Thesaurus::PropertyHelper_Thesaurus(
711 			const ::com::sun::star::uno::Reference<
712 				::com::sun::star::uno::XInterface > &rxSource,
713 			::com::sun::star::uno::Reference<
714 				::com::sun::star::beans::XPropertySet > &rxPropSet )
715 {
716 	pInst = new PropertyHelper_Thes( rxSource, rxPropSet );
717 	xPropHelper = pInst;
718 }
719 
~PropertyHelper_Thesaurus()720 PropertyHelper_Thesaurus::~PropertyHelper_Thesaurus()
721 {
722 }
723 
AddAsPropListener()724 void PropertyHelper_Thesaurus::AddAsPropListener()
725 {
726 	pInst->AddAsPropListener();
727 }
728 
RemoveAsPropListener()729 void PropertyHelper_Thesaurus::RemoveAsPropListener()
730 {
731 	pInst->RemoveAsPropListener();
732 }
733 
SetTmpPropVals(const com::sun::star::beans::PropertyValues & rPropVals)734 void PropertyHelper_Thesaurus::SetTmpPropVals( const com::sun::star::beans::PropertyValues &rPropVals )
735 {
736 	pInst->SetTmpPropVals( rPropVals );
737 }
738 
PropertyHelper_Hyphenation(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rxSource,::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rxPropSet)739 PropertyHelper_Hyphenation::PropertyHelper_Hyphenation(
740 			const ::com::sun::star::uno::Reference<
741 				::com::sun::star::uno::XInterface > &rxSource,
742 			::com::sun::star::uno::Reference<
743 				::com::sun::star::beans::XPropertySet > &rxPropSet)
744 {
745 	pInst = new PropertyHelper_Hyphen( rxSource, rxPropSet );
746 	xPropHelper = pInst;
747 }
748 
~PropertyHelper_Hyphenation()749 PropertyHelper_Hyphenation::~PropertyHelper_Hyphenation()
750 {
751 }
752 
AddAsPropListener()753 void PropertyHelper_Hyphenation::AddAsPropListener()
754 {
755 	pInst->AddAsPropListener();
756 }
757 
RemoveAsPropListener()758 void PropertyHelper_Hyphenation::RemoveAsPropListener()
759 {
760 	pInst->RemoveAsPropListener();
761 }
762 
SetTmpPropVals(const com::sun::star::beans::PropertyValues & rPropVals)763 void PropertyHelper_Hyphenation::SetTmpPropVals( const com::sun::star::beans::PropertyValues &rPropVals )
764 {
765 	pInst->SetTmpPropVals( rPropVals );
766 }
767 
GetMinLeading() const768 sal_Int16 PropertyHelper_Hyphenation::GetMinLeading() const
769 {
770 	return pInst->GetMinLeading();
771 }
772 
GetMinTrailing() const773 sal_Int16 PropertyHelper_Hyphenation::GetMinTrailing() const
774 {
775 	return pInst->GetMinTrailing();
776 }
777 
GetMinWordLength() const778 sal_Int16 PropertyHelper_Hyphenation::GetMinWordLength() const
779 {
780 	return pInst->GetMinWordLength();
781 }
782 
addLinguServiceEventListener(const::com::sun::star::uno::Reference<::com::sun::star::linguistic2::XLinguServiceEventListener> & rxListener)783 sal_Bool PropertyHelper_Hyphenation::addLinguServiceEventListener(
784 				const ::com::sun::star::uno::Reference<
785 					::com::sun::star::linguistic2::XLinguServiceEventListener >& rxListener )
786 			throw(::com::sun::star::uno::RuntimeException)
787 {
788 	return pInst->addLinguServiceEventListener( rxListener );
789 }
790 
removeLinguServiceEventListener(const::com::sun::star::uno::Reference<::com::sun::star::linguistic2::XLinguServiceEventListener> & rxListener)791 sal_Bool PropertyHelper_Hyphenation::removeLinguServiceEventListener(
792 				const ::com::sun::star::uno::Reference<
793 					::com::sun::star::linguistic2::XLinguServiceEventListener >& rxListener )
794 			throw(::com::sun::star::uno::RuntimeException)
795 {
796 	return pInst->removeLinguServiceEventListener( rxListener );
797 }
798 
PropertyHelper_Spelling(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rxSource,::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rxPropSet)799 PropertyHelper_Spelling::PropertyHelper_Spelling(
800 			const ::com::sun::star::uno::Reference<
801 				::com::sun::star::uno::XInterface > &rxSource,
802 			::com::sun::star::uno::Reference<
803 				::com::sun::star::beans::XPropertySet > &rxPropSet )
804 {
805 	pInst = new PropertyHelper_Spell( rxSource, rxPropSet );
806 	xPropHelper = pInst;
807 }
808 
~PropertyHelper_Spelling()809 PropertyHelper_Spelling::~PropertyHelper_Spelling()
810 {
811 }
812 
AddAsPropListener()813 void PropertyHelper_Spelling::AddAsPropListener()
814 {
815 	pInst->AddAsPropListener();
816 }
817 
RemoveAsPropListener()818 void PropertyHelper_Spelling::RemoveAsPropListener()
819 {
820 	pInst->RemoveAsPropListener();
821 }
822 
SetTmpPropVals(const com::sun::star::beans::PropertyValues & rPropVals)823 void PropertyHelper_Spelling::SetTmpPropVals( const com::sun::star::beans::PropertyValues &rPropVals )
824 {
825 	pInst->SetTmpPropVals( rPropVals );
826 }
827 
GetMaxNumberOfSuggestions() const828 sal_Int16 PropertyHelper_Spelling::GetMaxNumberOfSuggestions() const
829 {
830 	return pInst->GetMaxNumberOfSuggestions();
831 }
832 
IsSpellUpperCase() const833 sal_Bool PropertyHelper_Spelling::IsSpellUpperCase() const
834 {
835 	return pInst->IsSpellUpperCase();
836 }
837 
IsSpellWithDigits() const838 sal_Bool PropertyHelper_Spelling::IsSpellWithDigits() const
839 {
840 	return pInst->IsSpellWithDigits();
841 }
842 
IsSpellCapitalization() const843 sal_Bool PropertyHelper_Spelling::IsSpellCapitalization() const
844 {
845 	return pInst->IsSpellCapitalization();
846 }
847 
addLinguServiceEventListener(const::com::sun::star::uno::Reference<::com::sun::star::linguistic2::XLinguServiceEventListener> & rxListener)848 sal_Bool PropertyHelper_Spelling::addLinguServiceEventListener(
849 				const ::com::sun::star::uno::Reference<
850 					::com::sun::star::linguistic2::XLinguServiceEventListener >& rxListener )
851 			throw(::com::sun::star::uno::RuntimeException)
852 {
853 	return pInst->addLinguServiceEventListener( rxListener );
854 }
855 
removeLinguServiceEventListener(const::com::sun::star::uno::Reference<::com::sun::star::linguistic2::XLinguServiceEventListener> & rxListener)856 sal_Bool PropertyHelper_Spelling::removeLinguServiceEventListener(
857 				const ::com::sun::star::uno::Reference<
858 					::com::sun::star::linguistic2::XLinguServiceEventListener >& rxListener )
859 			throw(::com::sun::star::uno::RuntimeException)
860 {
861 	return pInst->removeLinguServiceEventListener( rxListener );
862 }
863 
864 
865 ///////////////////////////////////////////////////////////////////////////
866 
867 }   // namespace linguistic
868 
869