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