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 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 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 83 PropertyChgHelper::~PropertyChgHelper() 84 { 85 } 86 87 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 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 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 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 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 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 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 244 PropertyHelper_Spell::~PropertyHelper_Spell() 245 { 246 } 247 248 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 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 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