1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/XNumberFormatsSupplier.hpp>
28 #include <tools/diagnose_ex.h>
29 #include <comphelper/processfactory.hxx>
30 #include <osl/diagnose.h>
32 //........................................................................
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 // -------------------------------------------------------------------
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
= Reference
< XNumberFormatsSupplier
>(
78 ::comphelper::getProcessServiceFactory()->createInstance(
79 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatsSupplier" ) ) ),
83 if ( !rDefaultFormats
.is() )
84 throw RuntimeException();
86 return rDefaultFormats
;
89 // ...............................................................
90 static oslInterlockedCount
s_refCount(0);
92 // ...............................................................
93 void lcl_registerDefaultFormatsClient()
95 osl_atomic_increment( &s_refCount
);
98 // ...............................................................
99 void lcl_revokeDefaultFormatsClient()
101 ::osl::ClearableMutexGuard
aGuard( getDefaultFormatsMutex() );
102 if ( 0 == osl_atomic_decrement( &s_refCount
) )
104 Reference
< XNumberFormatsSupplier
>& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
105 Reference
< XNumberFormatsSupplier
> xReleasePotentialLastReference( rDefaultFormats
);
106 rDefaultFormats
.clear();
107 lcl_getTriedCreation() = false;
110 xReleasePotentialLastReference
.clear();
115 // ===================================================================
116 // = UnoControlFormattedFieldModel
117 // ===================================================================
118 // -------------------------------------------------------------------
119 UnoControlFormattedFieldModel::UnoControlFormattedFieldModel( const Reference
< XMultiServiceFactory
>& i_factory
)
120 :UnoControlModel( i_factory
)
121 ,m_bRevokedAsClient( false )
122 ,m_bSettingValueAndText( false )
124 ImplRegisterProperty( BASEPROPERTY_ALIGN
);
125 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR
);
126 ImplRegisterProperty( BASEPROPERTY_BORDER
);
127 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR
);
128 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL
);
129 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT
);
130 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE
);
131 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX
);
132 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN
);
133 ImplRegisterProperty( BASEPROPERTY_ENABLED
);
134 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE
);
135 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR
);
136 ImplRegisterProperty( BASEPROPERTY_FORMATKEY
);
137 ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER
);
138 ImplRegisterProperty( BASEPROPERTY_HELPTEXT
);
139 ImplRegisterProperty( BASEPROPERTY_HELPURL
);
140 ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN
);
141 ImplRegisterProperty( BASEPROPERTY_PRINTABLE
);
142 ImplRegisterProperty( BASEPROPERTY_REPEAT
);
143 ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY
);
144 ImplRegisterProperty( BASEPROPERTY_READONLY
);
145 ImplRegisterProperty( BASEPROPERTY_SPIN
);
146 ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT
);
147 ImplRegisterProperty( BASEPROPERTY_TABSTOP
);
148 ImplRegisterProperty( BASEPROPERTY_TEXT
);
149 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR
);
150 ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION
);
151 ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT
);
152 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN
);
153 ImplRegisterProperty( BASEPROPERTY_WRITING_MODE
);
154 ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE
);
155 ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR
);
158 aTreatAsNumber
<<= (sal_Bool
) sal_True
;
159 ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER
, aTreatAsNumber
);
161 lcl_registerDefaultFormatsClient();
164 // -------------------------------------------------------------------
165 UnoControlFormattedFieldModel::~UnoControlFormattedFieldModel()
169 // -------------------------------------------------------------------
170 ::rtl::OUString
UnoControlFormattedFieldModel::getServiceName() throw(RuntimeException
)
172 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedFieldModel
);
175 // -------------------------------------------------------------------
176 void SAL_CALL
UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw (Exception
)
178 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle
, rValue
);
182 case BASEPROPERTY_EFFECTIVE_VALUE
:
183 if ( !m_bSettingValueAndText
)
184 impl_updateTextFromValue_nothrow();
186 case BASEPROPERTY_FORMATSSUPPLIER
:
187 impl_updateCachedFormatter_nothrow();
188 impl_updateTextFromValue_nothrow();
190 case BASEPROPERTY_FORMATKEY
:
191 impl_updateCachedFormatKey_nothrow();
192 impl_updateTextFromValue_nothrow();
197 // -------------------------------------------------------------------
198 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
200 if ( !m_xCachedFormatter
.is() )
201 impl_updateCachedFormatter_nothrow();
202 if ( !m_xCachedFormatter
.is() )
208 getFastPropertyValue( aEffectiveValue
, BASEPROPERTY_EFFECTIVE_VALUE
);
210 ::rtl::OUString sStringValue
;
211 if ( !( aEffectiveValue
>>= sStringValue
) )
213 double nDoubleValue(0);
214 if ( aEffectiveValue
>>= nDoubleValue
)
216 sal_Int32
nFormatKey( 0 );
217 if ( m_aCachedFormat
.hasValue() )
218 m_aCachedFormat
>>= nFormatKey
;
219 sStringValue
= m_xCachedFormatter
->convertNumberToString( nFormatKey
, nDoubleValue
);
223 Reference
< XPropertySet
> xThis( *this, UNO_QUERY
);
224 xThis
->setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT
), makeAny( sStringValue
) );
226 catch( const Exception
& )
228 DBG_UNHANDLED_EXCEPTION();
232 // -------------------------------------------------------------------
233 void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow()
235 Any aFormatsSupplier
;
236 getFastPropertyValue( aFormatsSupplier
, BASEPROPERTY_FORMATSSUPPLIER
);
239 Reference
< XNumberFormatsSupplier
> xSupplier( aFormatsSupplier
, UNO_QUERY
);
240 if ( !xSupplier
.is() )
241 xSupplier
= lcl_getDefaultFormats_throw();
243 if ( !m_xCachedFormatter
.is() )
245 m_xCachedFormatter
= Reference
< XNumberFormatter
>(
246 NumberFormatter::create(::comphelper::getProcessComponentContext()),
250 m_xCachedFormatter
->attachNumberFormatsSupplier( xSupplier
);
252 catch( const Exception
& )
254 DBG_UNHANDLED_EXCEPTION();
258 // -------------------------------------------------------------------
259 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
262 getFastPropertyValue( aFormatKey
, BASEPROPERTY_FORMATKEY
);
263 m_aCachedFormat
= aFormatKey
;
266 // -------------------------------------------------------------------
267 void UnoControlFormattedFieldModel::dispose( ) throw(RuntimeException
)
269 UnoControlModel::dispose();
271 ::osl::MutexGuard
aGuard( GetMutex() );
272 if ( !m_bRevokedAsClient
)
274 lcl_revokeDefaultFormatsClient();
275 m_bRevokedAsClient
= true;
279 // -------------------------------------------------------------------
280 void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount
, sal_Int32
* _pHandles
,
281 Any
* _pValues
, sal_Int32
* _pValidHandles
) const SAL_THROW(())
283 ImplEnsureHandleOrder( _nCount
, _pHandles
, _pValues
, BASEPROPERTY_EFFECTIVE_VALUE
, BASEPROPERTY_TEXT
);
285 UnoControlModel::ImplNormalizePropertySequence( _nCount
, _pHandles
, _pValues
, _pValidHandles
);
288 // -------------------------------------------------------------------
291 class ResetFlagOnExit
297 ResetFlagOnExit( bool& _rFlag
)
308 // -------------------------------------------------------------------
309 void SAL_CALL
UnoControlFormattedFieldModel::setPropertyValues( const Sequence
< ::rtl::OUString
>& _rPropertyNames
, const Sequence
< Any
>& _rValues
) throw(PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
311 bool bSettingValue
= false;
312 bool bSettingText
= false;
313 for ( const ::rtl::OUString
* pPropertyNames
= _rPropertyNames
.getConstArray();
314 pPropertyNames
!= _rPropertyNames
.getConstArray() + _rPropertyNames
.getLength();
318 if ( BASEPROPERTY_EFFECTIVE_VALUE
== GetPropertyId( *pPropertyNames
) )
319 bSettingValue
= true;
321 if ( BASEPROPERTY_TEXT
== GetPropertyId( *pPropertyNames
) )
325 m_bSettingValueAndText
= ( bSettingValue
&& bSettingText
);
326 ResetFlagOnExit
aResetFlag( m_bSettingValueAndText
);
327 UnoControlModel::setPropertyValues( _rPropertyNames
, _rValues
);
330 // -------------------------------------------------------------------
331 sal_Bool
UnoControlFormattedFieldModel::convertFastPropertyValue(
332 Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nPropId
,
333 const Any
& rValue
) throw (IllegalArgumentException
)
335 if ( BASEPROPERTY_EFFECTIVE_DEFAULT
== nPropId
&& rValue
.hasValue() )
338 ::rtl::OUString sVal
;
339 sal_Bool bStreamed
= (rValue
>>= dVal
);
342 rConvertedValue
<<= dVal
;
347 bStreamed
= (rValue
>>= nVal
);
350 rConvertedValue
<<= static_cast<double>(nVal
);
354 bStreamed
= (rValue
>>= sVal
);
357 rConvertedValue
<<= sVal
;
364 getFastPropertyValue( rOldValue
, nPropId
);
365 return !CompareProperties( rConvertedValue
, rOldValue
);
368 throw IllegalArgumentException(
369 ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to convert the given value for the property "))
370 += GetPropertyName((sal_uInt16
)nPropId
) )
371 += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (double, integer, or string expected).")),
372 static_cast< XPropertySet
* >(this),
376 return UnoControlModel::convertFastPropertyValue( rConvertedValue
, rOldValue
, nPropId
, rValue
);
379 // -------------------------------------------------------------------
380 Any
UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId
) const
385 case BASEPROPERTY_DEFAULTCONTROL
: aReturn
<<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedField
) ); break;
387 case BASEPROPERTY_TREATASNUMBER
: aReturn
<<= (sal_Bool
)sal_True
; break;
389 case BASEPROPERTY_EFFECTIVE_DEFAULT
:
390 case BASEPROPERTY_EFFECTIVE_VALUE
:
391 case BASEPROPERTY_EFFECTIVE_MAX
:
392 case BASEPROPERTY_EFFECTIVE_MIN
:
393 case BASEPROPERTY_FORMATKEY
:
394 case BASEPROPERTY_FORMATSSUPPLIER
:
398 default : aReturn
= UnoControlModel::ImplGetDefaultValue( nPropId
); break;
404 // -------------------------------------------------------------------
405 ::cppu::IPropertyArrayHelper
& UnoControlFormattedFieldModel::getInfoHelper()
407 static UnoPropertyArrayHelper
* pHelper
= NULL
;
410 Sequence
<sal_Int32
> aIDs
= ImplGetPropertyIds();
411 pHelper
= new UnoPropertyArrayHelper( aIDs
);
416 // beans::XMultiPropertySet
417 // -------------------------------------------------------------------
418 Reference
< XPropertySetInfo
> UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException
)
420 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
424 // ===================================================================
425 // = UnoFormattedFieldControl
426 // ===================================================================
427 // -------------------------------------------------------------------
428 UnoFormattedFieldControl::UnoFormattedFieldControl( const Reference
< XMultiServiceFactory
>& i_factory
)
429 :UnoSpinFieldControl( i_factory
)
433 // -------------------------------------------------------------------
434 ::rtl::OUString
UnoFormattedFieldControl::GetComponentServiceName()
436 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FormattedField"));
439 // -------------------------------------------------------------------
440 void UnoFormattedFieldControl::textChanged(const TextEvent
& e
) throw(RuntimeException
)
442 Reference
< XVclWindowPeer
> xPeer(getPeer(), UNO_QUERY
);
443 OSL_ENSURE(xPeer
.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?");
445 Sequence
< ::rtl::OUString
> aNames( 2 );
446 aNames
[0] = GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE
);
447 aNames
[1] = GetPropertyName( BASEPROPERTY_TEXT
);
449 Sequence
< Any
> aValues( 2 );
450 aValues
[0] = xPeer
->getProperty( aNames
[0] );
451 aValues
[1] = xPeer
->getProperty( aNames
[1] );
453 ImplSetPropertyValues( aNames
, aValues
, sal_False
);
455 if ( GetTextListeners().getLength() )
456 GetTextListeners().textChanged( e
);
459 //........................................................................
460 } // namespace toolkit
461 //........................................................................
463 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */