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/NumberFormatsSupplier.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
= 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;
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
);
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
);
178 case BASEPROPERTY_EFFECTIVE_VALUE
:
179 if ( !m_bSettingValueAndText
)
180 impl_updateTextFromValue_nothrow();
182 case BASEPROPERTY_FORMATSSUPPLIER
:
183 impl_updateCachedFormatter_nothrow();
184 impl_updateTextFromValue_nothrow();
186 case BASEPROPERTY_FORMATKEY
:
187 impl_updateCachedFormatKey_nothrow();
188 impl_updateTextFromValue_nothrow();
193 // -------------------------------------------------------------------
194 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
196 if ( !m_xCachedFormatter
.is() )
197 impl_updateCachedFormatter_nothrow();
198 if ( !m_xCachedFormatter
.is() )
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()),
246 m_xCachedFormatter
->attachNumberFormatsSupplier( xSupplier
);
248 catch( const Exception
& )
250 DBG_UNHANDLED_EXCEPTION();
254 // -------------------------------------------------------------------
255 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
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 // -------------------------------------------------------------------
287 class ResetFlagOnExit
293 ResetFlagOnExit( bool& _rFlag
)
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();
314 if ( BASEPROPERTY_EFFECTIVE_VALUE
== GetPropertyId( *pPropertyNames
) )
315 bSettingValue
= true;
317 if ( BASEPROPERTY_TEXT
== GetPropertyId( *pPropertyNames
) )
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() )
335 sal_Bool bStreamed
= (rValue
>>= dVal
);
338 rConvertedValue
<<= dVal
;
343 bStreamed
= (rValue
>>= nVal
);
346 rConvertedValue
<<= static_cast<double>(nVal
);
350 bStreamed
= (rValue
>>= sVal
);
353 rConvertedValue
<<= sVal
;
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
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
:
394 default : aReturn
= UnoControlModel::ImplGetDefaultValue( nPropId
); break;
400 // -------------------------------------------------------------------
401 ::cppu::IPropertyArrayHelper
& UnoControlFormattedFieldModel::getInfoHelper()
403 static UnoPropertyArrayHelper
* pHelper
= NULL
;
406 Sequence
<sal_Int32
> aIDs
= ImplGetPropertyIds();
407 pHelper
= new UnoPropertyArrayHelper( aIDs
);
412 // beans::XMultiPropertySet
413 // -------------------------------------------------------------------
414 Reference
< XPropertySetInfo
> UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException
)
416 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
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: */