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