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_toolkit.hxx" 30 #include <toolkit/controls/formattedcontrol.hxx> 31 #include <toolkit/helper/unopropertyarrayhelper.hxx> 32 #include <toolkit/helper/property.hxx> 33 34 #include <com/sun/star/awt/XVclWindowPeer.hpp> 35 #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 36 37 #include <tools/diagnose_ex.h> 38 #include <comphelper/processfactory.hxx> 39 #include <osl/diagnose.h> 40 41 //........................................................................ 42 namespace toolkit 43 { 44 //........................................................................ 45 46 using namespace ::com::sun::star::uno; 47 using namespace ::com::sun::star::awt; 48 using namespace ::com::sun::star::lang; 49 using namespace ::com::sun::star::beans; 50 using namespace ::com::sun::star::util; 51 52 // ------------------------------------------------------------------- 53 namespace 54 { 55 // ............................................................... 56 ::osl::Mutex& getDefaultFormatsMutex() 57 { 58 static ::osl::Mutex s_aDefaultFormatsMutex; 59 return s_aDefaultFormatsMutex; 60 } 61 62 // ............................................................... 63 Reference< XNumberFormatsSupplier >& lcl_getDefaultFormatsAccess_nothrow() 64 { 65 static Reference< XNumberFormatsSupplier > s_xDefaultFormats; 66 return s_xDefaultFormats; 67 } 68 69 // ............................................................... 70 bool& lcl_getTriedCreation() 71 { 72 static bool s_bTriedCreation = false; 73 return s_bTriedCreation; 74 } 75 76 // ............................................................... 77 const Reference< XNumberFormatsSupplier >& lcl_getDefaultFormats_throw() 78 { 79 ::osl::MutexGuard aGuard( getDefaultFormatsMutex() ); 80 81 bool& rbTriedCreation = lcl_getTriedCreation(); 82 Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() ); 83 if ( !rDefaultFormats.is() && !rbTriedCreation ) 84 { 85 rbTriedCreation = true; 86 rDefaultFormats = Reference< XNumberFormatsSupplier >( 87 ::comphelper::createProcessComponent( 88 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatsSupplier" ) ) ), 89 UNO_QUERY_THROW 90 ); 91 } 92 if ( !rDefaultFormats.is() ) 93 throw RuntimeException(); 94 95 return rDefaultFormats; 96 } 97 98 // ............................................................... 99 static oslInterlockedCount s_refCount(0); 100 101 // ............................................................... 102 void lcl_registerDefaultFormatsClient() 103 { 104 osl_incrementInterlockedCount( &s_refCount ); 105 } 106 107 // ............................................................... 108 void lcl_revokeDefaultFormatsClient() 109 { 110 ::osl::ClearableMutexGuard aGuard( getDefaultFormatsMutex() ); 111 if ( 0 == osl_decrementInterlockedCount( &s_refCount ) ) 112 { 113 Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() ); 114 Reference< XNumberFormatsSupplier > xReleasePotentialLastReference( rDefaultFormats ); 115 rDefaultFormats.clear(); 116 lcl_getTriedCreation() = false; 117 118 aGuard.clear(); 119 xReleasePotentialLastReference.clear(); 120 } 121 } 122 } 123 124 // =================================================================== 125 // = UnoControlFormattedFieldModel 126 // =================================================================== 127 // ------------------------------------------------------------------- 128 UnoControlFormattedFieldModel::UnoControlFormattedFieldModel( const Reference< XMultiServiceFactory >& i_factory ) 129 :UnoControlModel( i_factory ) 130 ,m_bRevokedAsClient( false ) 131 ,m_bSettingValueAndText( false ) 132 { 133 ImplRegisterProperty( BASEPROPERTY_ALIGN ); 134 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); 135 ImplRegisterProperty( BASEPROPERTY_BORDER ); 136 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); 137 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); 138 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT ); 139 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE ); 140 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX ); 141 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN ); 142 ImplRegisterProperty( BASEPROPERTY_ENABLED ); 143 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); 144 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); 145 ImplRegisterProperty( BASEPROPERTY_FORMATKEY ); 146 ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER ); 147 ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); 148 ImplRegisterProperty( BASEPROPERTY_HELPURL ); 149 ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN ); 150 ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); 151 ImplRegisterProperty( BASEPROPERTY_REPEAT ); 152 ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY ); 153 ImplRegisterProperty( BASEPROPERTY_READONLY ); 154 ImplRegisterProperty( BASEPROPERTY_SPIN ); 155 ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT ); 156 ImplRegisterProperty( BASEPROPERTY_TABSTOP ); 157 ImplRegisterProperty( BASEPROPERTY_TEXT ); 158 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR ); 159 ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION ); 160 ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT ); 161 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN ); 162 ImplRegisterProperty( BASEPROPERTY_WRITING_MODE ); 163 ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE ); 164 ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR ); 165 166 Any aTreatAsNumber; 167 aTreatAsNumber <<= (sal_Bool) sal_True; 168 ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER, aTreatAsNumber ); 169 170 lcl_registerDefaultFormatsClient(); 171 } 172 173 // ------------------------------------------------------------------- 174 UnoControlFormattedFieldModel::~UnoControlFormattedFieldModel() 175 { 176 } 177 178 // ------------------------------------------------------------------- 179 ::rtl::OUString UnoControlFormattedFieldModel::getServiceName() throw(RuntimeException) 180 { 181 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedFieldModel ); 182 } 183 184 // ------------------------------------------------------------------- 185 void SAL_CALL UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) 186 { 187 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); 188 189 switch ( nHandle ) 190 { 191 case BASEPROPERTY_EFFECTIVE_VALUE: 192 if ( !m_bSettingValueAndText ) 193 impl_updateTextFromValue_nothrow(); 194 break; 195 case BASEPROPERTY_FORMATSSUPPLIER: 196 impl_updateCachedFormatter_nothrow(); 197 impl_updateTextFromValue_nothrow(); 198 break; 199 case BASEPROPERTY_FORMATKEY: 200 impl_updateCachedFormatKey_nothrow(); 201 impl_updateTextFromValue_nothrow(); 202 break; 203 } 204 } 205 206 // ------------------------------------------------------------------- 207 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow() 208 { 209 if ( !m_xCachedFormatter.is() ) 210 impl_updateCachedFormatter_nothrow(); 211 if ( !m_xCachedFormatter.is() ) 212 return; 213 214 try 215 { 216 Any aEffectiveValue; 217 getFastPropertyValue( aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE ); 218 219 ::rtl::OUString sStringValue; 220 if ( !( aEffectiveValue >>= sStringValue ) ) 221 { 222 double nDoubleValue(0); 223 if ( aEffectiveValue >>= nDoubleValue ) 224 { 225 sal_Int32 nFormatKey( 0 ); 226 if ( m_aCachedFormat.hasValue() ) 227 m_aCachedFormat >>= nFormatKey; 228 sStringValue = m_xCachedFormatter->convertNumberToString( nFormatKey, nDoubleValue ); 229 } 230 } 231 232 Reference< XPropertySet > xThis( *this, UNO_QUERY ); 233 xThis->setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), makeAny( sStringValue ) ); 234 } 235 catch( const Exception& ) 236 { 237 DBG_UNHANDLED_EXCEPTION(); 238 } 239 } 240 241 // ------------------------------------------------------------------- 242 void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow() 243 { 244 Any aFormatsSupplier; 245 getFastPropertyValue( aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER ); 246 try 247 { 248 Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, UNO_QUERY ); 249 if ( !xSupplier.is() ) 250 xSupplier = lcl_getDefaultFormats_throw(); 251 252 if ( !m_xCachedFormatter.is() ) 253 { 254 m_xCachedFormatter = Reference< XNumberFormatter >( 255 ::comphelper::createProcessComponent( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" ) ) ), 256 UNO_QUERY_THROW 257 ); 258 } 259 m_xCachedFormatter->attachNumberFormatsSupplier( xSupplier ); 260 } 261 catch( const Exception& ) 262 { 263 DBG_UNHANDLED_EXCEPTION(); 264 } 265 } 266 267 // ------------------------------------------------------------------- 268 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow() 269 { 270 Any aFormatKey; 271 getFastPropertyValue( aFormatKey, BASEPROPERTY_FORMATKEY ); 272 m_aCachedFormat = aFormatKey; 273 } 274 275 // ------------------------------------------------------------------- 276 void UnoControlFormattedFieldModel::dispose( ) throw(RuntimeException) 277 { 278 UnoControlModel::dispose(); 279 280 ::osl::MutexGuard aGuard( GetMutex() ); 281 if ( !m_bRevokedAsClient ) 282 { 283 lcl_revokeDefaultFormatsClient(); 284 m_bRevokedAsClient = true; 285 } 286 } 287 288 // ------------------------------------------------------------------- 289 void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount, sal_Int32* _pHandles, 290 Any* _pValues, sal_Int32* _pValidHandles ) const SAL_THROW(()) 291 { 292 ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_EFFECTIVE_VALUE, BASEPROPERTY_TEXT ); 293 294 UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles ); 295 } 296 297 // ------------------------------------------------------------------- 298 namespace 299 { 300 class ResetFlagOnExit 301 { 302 private: 303 bool& m_rFlag; 304 305 public: 306 ResetFlagOnExit( bool& _rFlag ) 307 :m_rFlag( _rFlag ) 308 { 309 } 310 ~ResetFlagOnExit() 311 { 312 m_rFlag = false; 313 } 314 }; 315 } 316 317 // ------------------------------------------------------------------- 318 void SAL_CALL UnoControlFormattedFieldModel::setPropertyValues( const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) 319 { 320 bool bSettingValue = false; 321 bool bSettingText = false; 322 for ( const ::rtl::OUString* pPropertyNames = _rPropertyNames.getConstArray(); 323 pPropertyNames != _rPropertyNames.getConstArray() + _rPropertyNames.getLength(); 324 ++pPropertyNames 325 ) 326 { 327 if ( BASEPROPERTY_EFFECTIVE_VALUE == GetPropertyId( *pPropertyNames ) ) 328 bSettingValue = true; 329 330 if ( BASEPROPERTY_TEXT == GetPropertyId( *pPropertyNames ) ) 331 bSettingText = true; 332 } 333 334 m_bSettingValueAndText = ( bSettingValue && bSettingText ); 335 ResetFlagOnExit aResetFlag( m_bSettingValueAndText ); 336 UnoControlModel::setPropertyValues( _rPropertyNames, _rValues ); 337 } 338 339 // ------------------------------------------------------------------- 340 sal_Bool UnoControlFormattedFieldModel::convertFastPropertyValue( 341 Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId, 342 const Any& rValue ) throw (IllegalArgumentException) 343 { 344 if ( BASEPROPERTY_EFFECTIVE_DEFAULT == nPropId && rValue.hasValue() ) 345 { 346 double dVal = 0; 347 sal_Int32 nVal = 0; 348 ::rtl::OUString sVal; 349 sal_Bool bStreamed = (rValue >>= dVal); 350 if ( bStreamed ) 351 { 352 rConvertedValue <<= dVal; 353 } 354 else 355 { 356 bStreamed = (rValue >>= nVal); 357 if ( bStreamed ) 358 { 359 rConvertedValue <<= static_cast<double>(nVal); 360 } 361 else 362 { 363 bStreamed = (rValue >>= sVal); 364 if ( bStreamed ) 365 { 366 rConvertedValue <<= sVal; 367 } 368 } 369 } 370 371 if ( bStreamed ) 372 { 373 getFastPropertyValue( rOldValue, nPropId ); 374 return !CompareProperties( rConvertedValue, rOldValue ); 375 } 376 377 throw IllegalArgumentException( 378 ( ::rtl::OUString::createFromAscii("Unable to convert the given value for the property ") 379 += GetPropertyName((sal_uInt16)nPropId) ) 380 += ::rtl::OUString::createFromAscii(" (double, integer, or string expected)."), 381 static_cast< XPropertySet* >(this), 382 1); 383 } 384 385 return UnoControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nPropId, rValue ); 386 } 387 388 // ------------------------------------------------------------------- 389 Any UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const 390 { 391 Any aReturn; 392 switch (nPropId) 393 { 394 case BASEPROPERTY_DEFAULTCONTROL: aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedField ) ); break; 395 396 case BASEPROPERTY_TREATASNUMBER: aReturn <<= (sal_Bool)sal_True; break; 397 398 case BASEPROPERTY_EFFECTIVE_DEFAULT: 399 case BASEPROPERTY_EFFECTIVE_VALUE: 400 case BASEPROPERTY_EFFECTIVE_MAX: 401 case BASEPROPERTY_EFFECTIVE_MIN: 402 case BASEPROPERTY_FORMATKEY: 403 case BASEPROPERTY_FORMATSSUPPLIER: 404 // (void) 405 break; 406 407 default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break; 408 } 409 410 return aReturn; 411 } 412 413 // ------------------------------------------------------------------- 414 ::cppu::IPropertyArrayHelper& UnoControlFormattedFieldModel::getInfoHelper() 415 { 416 static UnoPropertyArrayHelper* pHelper = NULL; 417 if ( !pHelper ) 418 { 419 Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); 420 pHelper = new UnoPropertyArrayHelper( aIDs ); 421 } 422 return *pHelper; 423 } 424 425 // beans::XMultiPropertySet 426 // ------------------------------------------------------------------- 427 Reference< XPropertySetInfo > UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException) 428 { 429 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 430 return xInfo; 431 } 432 433 // =================================================================== 434 // = UnoFormattedFieldControl 435 // =================================================================== 436 // ------------------------------------------------------------------- 437 UnoFormattedFieldControl::UnoFormattedFieldControl( const Reference< XMultiServiceFactory >& i_factory ) 438 :UnoSpinFieldControl( i_factory ) 439 { 440 } 441 442 // ------------------------------------------------------------------- 443 ::rtl::OUString UnoFormattedFieldControl::GetComponentServiceName() 444 { 445 return ::rtl::OUString::createFromAscii( "FormattedField" ); 446 } 447 448 // ------------------------------------------------------------------- 449 void UnoFormattedFieldControl::textChanged(const TextEvent& e) throw(RuntimeException) 450 { 451 Reference< XVclWindowPeer > xPeer(getPeer(), UNO_QUERY); 452 OSL_ENSURE(xPeer.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?"); 453 454 Sequence< ::rtl::OUString > aNames( 2 ); 455 aNames[0] = GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE ); 456 aNames[1] = GetPropertyName( BASEPROPERTY_TEXT ); 457 458 Sequence< Any > aValues( 2 ); 459 aValues[0] = xPeer->getProperty( aNames[0] ); 460 aValues[1] = xPeer->getProperty( aNames[1] ); 461 462 ImplSetPropertyValues( aNames, aValues, sal_False ); 463 464 if ( GetTextListeners().getLength() ) 465 GetTextListeners().textChanged( e ); 466 } 467 468 //........................................................................ 469 } // namespace toolkit 470 //........................................................................ 471