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