bump product version to 4.1.6.2
[LibreOffice.git] / toolkit / source / controls / formattedcontrol.cxx
blob9aa143b54560b80b147c3a8498ba4198a725d66b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <toolkit/controls/formattedcontrol.hxx>
21 #include <toolkit/helper/unopropertyarrayhelper.hxx>
22 #include <toolkit/helper/property.hxx>
24 #include <com/sun/star/awt/XVclWindowPeer.hpp>
25 #include <com/sun/star/util/NumberFormatter.hpp>
26 #include <com/sun/star/util/NumberFormatsSupplier.hpp>
28 #include <tools/diagnose_ex.h>
29 #include <comphelper/processfactory.hxx>
30 #include <osl/diagnose.h>
32 //........................................................................
33 namespace toolkit
35 //........................................................................
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::awt;
39 using namespace ::com::sun::star::lang;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::util;
43 // -------------------------------------------------------------------
44 namespace
46 // ...............................................................
47 ::osl::Mutex& getDefaultFormatsMutex()
49 static ::osl::Mutex s_aDefaultFormatsMutex;
50 return s_aDefaultFormatsMutex;
53 // ...............................................................
54 Reference< XNumberFormatsSupplier >& lcl_getDefaultFormatsAccess_nothrow()
56 static Reference< XNumberFormatsSupplier > s_xDefaultFormats;
57 return s_xDefaultFormats;
60 // ...............................................................
61 bool& lcl_getTriedCreation()
63 static bool s_bTriedCreation = false;
64 return s_bTriedCreation;
67 // ...............................................................
68 const Reference< XNumberFormatsSupplier >& lcl_getDefaultFormats_throw()
70 ::osl::MutexGuard aGuard( getDefaultFormatsMutex() );
72 bool& rbTriedCreation = lcl_getTriedCreation();
73 Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
74 if ( !rDefaultFormats.is() && !rbTriedCreation )
76 rbTriedCreation = true;
77 rDefaultFormats = NumberFormatsSupplier::createWithDefaultLocale( ::comphelper::getProcessComponentContext() );
79 if ( !rDefaultFormats.is() )
80 throw RuntimeException();
82 return rDefaultFormats;
85 // ...............................................................
86 static oslInterlockedCount s_refCount(0);
88 // ...............................................................
89 void lcl_registerDefaultFormatsClient()
91 osl_atomic_increment( &s_refCount );
94 // ...............................................................
95 void lcl_revokeDefaultFormatsClient()
97 ::osl::ClearableMutexGuard aGuard( getDefaultFormatsMutex() );
98 if ( 0 == osl_atomic_decrement( &s_refCount ) )
100 Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
101 Reference< XNumberFormatsSupplier > xReleasePotentialLastReference( rDefaultFormats );
102 rDefaultFormats.clear();
103 lcl_getTriedCreation() = false;
105 aGuard.clear();
106 xReleasePotentialLastReference.clear();
111 // ===================================================================
112 // = UnoControlFormattedFieldModel
113 // ===================================================================
114 // -------------------------------------------------------------------
115 UnoControlFormattedFieldModel::UnoControlFormattedFieldModel( const Reference< XComponentContext >& rxContext )
116 :UnoControlModel( rxContext )
117 ,m_bRevokedAsClient( false )
118 ,m_bSettingValueAndText( false )
120 ImplRegisterProperty( BASEPROPERTY_ALIGN );
121 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
122 ImplRegisterProperty( BASEPROPERTY_BORDER );
123 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
124 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
125 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT );
126 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE );
127 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX );
128 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN );
129 ImplRegisterProperty( BASEPROPERTY_ENABLED );
130 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE );
131 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
132 ImplRegisterProperty( BASEPROPERTY_FORMATKEY );
133 ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER );
134 ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
135 ImplRegisterProperty( BASEPROPERTY_HELPURL );
136 ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN );
137 ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
138 ImplRegisterProperty( BASEPROPERTY_REPEAT );
139 ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY );
140 ImplRegisterProperty( BASEPROPERTY_READONLY );
141 ImplRegisterProperty( BASEPROPERTY_SPIN );
142 ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT );
143 ImplRegisterProperty( BASEPROPERTY_TABSTOP );
144 ImplRegisterProperty( BASEPROPERTY_TEXT );
145 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
146 ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION );
147 ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT );
148 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
149 ImplRegisterProperty( BASEPROPERTY_WRITING_MODE );
150 ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE );
151 ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR );
153 Any aTreatAsNumber;
154 aTreatAsNumber <<= (sal_Bool) sal_True;
155 ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER, aTreatAsNumber );
157 lcl_registerDefaultFormatsClient();
160 // -------------------------------------------------------------------
161 UnoControlFormattedFieldModel::~UnoControlFormattedFieldModel()
165 // -------------------------------------------------------------------
166 OUString UnoControlFormattedFieldModel::getServiceName() throw(RuntimeException)
168 return OUString::createFromAscii( szServiceName_UnoControlFormattedFieldModel );
171 // -------------------------------------------------------------------
172 void SAL_CALL UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
174 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
176 switch ( nHandle )
178 case BASEPROPERTY_EFFECTIVE_VALUE:
179 if ( !m_bSettingValueAndText )
180 impl_updateTextFromValue_nothrow();
181 break;
182 case BASEPROPERTY_FORMATSSUPPLIER:
183 impl_updateCachedFormatter_nothrow();
184 impl_updateTextFromValue_nothrow();
185 break;
186 case BASEPROPERTY_FORMATKEY:
187 impl_updateCachedFormatKey_nothrow();
188 impl_updateTextFromValue_nothrow();
189 break;
193 // -------------------------------------------------------------------
194 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
196 if ( !m_xCachedFormatter.is() )
197 impl_updateCachedFormatter_nothrow();
198 if ( !m_xCachedFormatter.is() )
199 return;
203 Any aEffectiveValue;
204 getFastPropertyValue( aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE );
206 OUString sStringValue;
207 if ( !( aEffectiveValue >>= sStringValue ) )
209 double nDoubleValue(0);
210 if ( aEffectiveValue >>= nDoubleValue )
212 sal_Int32 nFormatKey( 0 );
213 if ( m_aCachedFormat.hasValue() )
214 m_aCachedFormat >>= nFormatKey;
215 sStringValue = m_xCachedFormatter->convertNumberToString( nFormatKey, nDoubleValue );
219 Reference< XPropertySet > xThis( *this, UNO_QUERY );
220 xThis->setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), makeAny( sStringValue ) );
222 catch( const Exception& )
224 DBG_UNHANDLED_EXCEPTION();
228 // -------------------------------------------------------------------
229 void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow()
231 Any aFormatsSupplier;
232 getFastPropertyValue( aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER );
235 Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, UNO_QUERY );
236 if ( !xSupplier.is() )
237 xSupplier = lcl_getDefaultFormats_throw();
239 if ( !m_xCachedFormatter.is() )
241 m_xCachedFormatter = Reference< XNumberFormatter >(
242 NumberFormatter::create(::comphelper::getProcessComponentContext()),
243 UNO_QUERY_THROW
246 m_xCachedFormatter->attachNumberFormatsSupplier( xSupplier );
248 catch( const Exception& )
250 DBG_UNHANDLED_EXCEPTION();
254 // -------------------------------------------------------------------
255 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
257 Any aFormatKey;
258 getFastPropertyValue( aFormatKey, BASEPROPERTY_FORMATKEY );
259 m_aCachedFormat = aFormatKey;
262 // -------------------------------------------------------------------
263 void UnoControlFormattedFieldModel::dispose( ) throw(RuntimeException)
265 UnoControlModel::dispose();
267 ::osl::MutexGuard aGuard( GetMutex() );
268 if ( !m_bRevokedAsClient )
270 lcl_revokeDefaultFormatsClient();
271 m_bRevokedAsClient = true;
275 // -------------------------------------------------------------------
276 void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount, sal_Int32* _pHandles,
277 Any* _pValues, sal_Int32* _pValidHandles ) const SAL_THROW(())
279 ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_EFFECTIVE_VALUE, BASEPROPERTY_TEXT );
281 UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles );
284 // -------------------------------------------------------------------
285 namespace
287 class ResetFlagOnExit
289 private:
290 bool& m_rFlag;
292 public:
293 ResetFlagOnExit( bool& _rFlag )
294 :m_rFlag( _rFlag )
297 ~ResetFlagOnExit()
299 m_rFlag = false;
304 // -------------------------------------------------------------------
305 void SAL_CALL UnoControlFormattedFieldModel::setPropertyValues( const Sequence< OUString >& _rPropertyNames, const Sequence< Any >& _rValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
307 bool bSettingValue = false;
308 bool bSettingText = false;
309 for ( const OUString* pPropertyNames = _rPropertyNames.getConstArray();
310 pPropertyNames != _rPropertyNames.getConstArray() + _rPropertyNames.getLength();
311 ++pPropertyNames
314 if ( BASEPROPERTY_EFFECTIVE_VALUE == GetPropertyId( *pPropertyNames ) )
315 bSettingValue = true;
317 if ( BASEPROPERTY_TEXT == GetPropertyId( *pPropertyNames ) )
318 bSettingText = true;
321 m_bSettingValueAndText = ( bSettingValue && bSettingText );
322 ResetFlagOnExit aResetFlag( m_bSettingValueAndText );
323 UnoControlModel::setPropertyValues( _rPropertyNames, _rValues );
326 // -------------------------------------------------------------------
327 sal_Bool UnoControlFormattedFieldModel::convertFastPropertyValue(
328 Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId,
329 const Any& rValue ) throw (IllegalArgumentException)
331 if ( BASEPROPERTY_EFFECTIVE_DEFAULT == nPropId && rValue.hasValue() )
333 double dVal = 0;
334 OUString sVal;
335 sal_Bool bStreamed = (rValue >>= dVal);
336 if ( bStreamed )
338 rConvertedValue <<= dVal;
340 else
342 sal_Int32 nVal = 0;
343 bStreamed = (rValue >>= nVal);
344 if ( bStreamed )
346 rConvertedValue <<= static_cast<double>(nVal);
348 else
350 bStreamed = (rValue >>= sVal);
351 if ( bStreamed )
353 rConvertedValue <<= sVal;
358 if ( bStreamed )
360 getFastPropertyValue( rOldValue, nPropId );
361 return !CompareProperties( rConvertedValue, rOldValue );
364 throw IllegalArgumentException(
365 ( OUString("Unable to convert the given value for the property ")
366 += GetPropertyName((sal_uInt16)nPropId) )
367 += " (double, integer, or string expected).",
368 static_cast< XPropertySet* >(this),
372 return UnoControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nPropId, rValue );
375 // -------------------------------------------------------------------
376 Any UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
378 Any aReturn;
379 switch (nPropId)
381 case BASEPROPERTY_DEFAULTCONTROL: aReturn <<= OUString( OUString::createFromAscii( szServiceName_UnoControlFormattedField ) ); break;
383 case BASEPROPERTY_TREATASNUMBER: aReturn <<= (sal_Bool)sal_True; break;
385 case BASEPROPERTY_EFFECTIVE_DEFAULT:
386 case BASEPROPERTY_EFFECTIVE_VALUE:
387 case BASEPROPERTY_EFFECTIVE_MAX:
388 case BASEPROPERTY_EFFECTIVE_MIN:
389 case BASEPROPERTY_FORMATKEY:
390 case BASEPROPERTY_FORMATSSUPPLIER:
391 // (void)
392 break;
394 default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break;
397 return aReturn;
400 // -------------------------------------------------------------------
401 ::cppu::IPropertyArrayHelper& UnoControlFormattedFieldModel::getInfoHelper()
403 static UnoPropertyArrayHelper* pHelper = NULL;
404 if ( !pHelper )
406 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
407 pHelper = new UnoPropertyArrayHelper( aIDs );
409 return *pHelper;
412 // beans::XMultiPropertySet
413 // -------------------------------------------------------------------
414 Reference< XPropertySetInfo > UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException)
416 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
417 return xInfo;
420 // ===================================================================
421 // = UnoFormattedFieldControl
422 // ===================================================================
423 // -------------------------------------------------------------------
424 UnoFormattedFieldControl::UnoFormattedFieldControl()
425 :UnoSpinFieldControl()
429 // -------------------------------------------------------------------
430 OUString UnoFormattedFieldControl::GetComponentServiceName()
432 return OUString("FormattedField");
435 // -------------------------------------------------------------------
436 void UnoFormattedFieldControl::textChanged(const TextEvent& e) throw(RuntimeException)
438 Reference< XVclWindowPeer > xPeer(getPeer(), UNO_QUERY);
439 OSL_ENSURE(xPeer.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?");
441 Sequence< OUString > aNames( 2 );
442 aNames[0] = GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE );
443 aNames[1] = GetPropertyName( BASEPROPERTY_TEXT );
445 Sequence< Any > aValues( 2 );
446 aValues[0] = xPeer->getProperty( aNames[0] );
447 aValues[1] = xPeer->getProperty( aNames[1] );
449 ImplSetPropertyValues( aNames, aValues, sal_False );
451 if ( GetTextListeners().getLength() )
452 GetTextListeners().textChanged( e );
455 //........................................................................
456 } // namespace toolkit
457 //........................................................................
459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */