1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formattedcontrol.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_toolkit.hxx"
33 #include <toolkit/controls/formattedcontrol.hxx>
34 #include <toolkit/helper/unopropertyarrayhelper.hxx>
35 #include <toolkit/helper/property.hxx>
37 #include <com/sun/star/awt/XVclWindowPeer.hpp>
38 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
40 #include <tools/diagnose_ex.h>
41 #include <comphelper/processfactory.hxx>
42 #include <osl/diagnose.h>
44 //........................................................................
47 //........................................................................
49 using namespace ::com::sun::star::uno
;
50 using namespace ::com::sun::star::awt
;
51 using namespace ::com::sun::star::lang
;
52 using namespace ::com::sun::star::beans
;
53 using namespace ::com::sun::star::util
;
55 // -------------------------------------------------------------------
58 // ...............................................................
59 ::osl::Mutex
& getDefaultFormatsMutex()
61 static ::osl::Mutex s_aDefaultFormatsMutex
;
62 return s_aDefaultFormatsMutex
;
65 // ...............................................................
66 Reference
< XNumberFormatsSupplier
>& lcl_getDefaultFormatsAccess_nothrow()
68 static Reference
< XNumberFormatsSupplier
> s_xDefaultFormats
;
69 return s_xDefaultFormats
;
72 // ...............................................................
73 bool& lcl_getTriedCreation()
75 static bool s_bTriedCreation
= false;
76 return s_bTriedCreation
;
79 // ...............................................................
80 const Reference
< XNumberFormatsSupplier
>& lcl_getDefaultFormats_throw()
82 ::osl::MutexGuard
aGuard( getDefaultFormatsMutex() );
84 bool& rbTriedCreation
= lcl_getTriedCreation();
85 Reference
< XNumberFormatsSupplier
>& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
86 if ( !rDefaultFormats
.is() && !rbTriedCreation
)
88 rbTriedCreation
= true;
89 rDefaultFormats
= Reference
< XNumberFormatsSupplier
>(
90 ::comphelper::createProcessComponent(
91 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatsSupplier" ) ) ),
95 if ( !rDefaultFormats
.is() )
96 throw RuntimeException();
98 return rDefaultFormats
;
101 // ...............................................................
102 static oslInterlockedCount
s_refCount(0);
104 // ...............................................................
105 void lcl_registerDefaultFormatsClient()
107 osl_incrementInterlockedCount( &s_refCount
);
110 // ...............................................................
111 void lcl_revokeDefaultFormatsClient()
113 ::osl::ClearableMutexGuard
aGuard( getDefaultFormatsMutex() );
114 if ( 0 == osl_decrementInterlockedCount( &s_refCount
) )
116 Reference
< XNumberFormatsSupplier
>& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
117 Reference
< XNumberFormatsSupplier
> xReleasePotentialLastReference( rDefaultFormats
);
118 rDefaultFormats
.clear();
119 lcl_getTriedCreation() = false;
122 xReleasePotentialLastReference
.clear();
127 // ===================================================================
128 // = UnoControlFormattedFieldModel
129 // ===================================================================
130 // -------------------------------------------------------------------
131 UnoControlFormattedFieldModel::UnoControlFormattedFieldModel()
132 :m_bRevokedAsClient( false )
133 ,m_bSettingValueAndText( false )
135 ImplRegisterProperty( BASEPROPERTY_ALIGN
);
136 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR
);
137 ImplRegisterProperty( BASEPROPERTY_BORDER
);
138 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR
);
139 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL
);
140 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT
);
141 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE
);
142 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX
);
143 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN
);
144 ImplRegisterProperty( BASEPROPERTY_ENABLED
);
145 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE
);
146 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR
);
147 ImplRegisterProperty( BASEPROPERTY_FORMATKEY
);
148 ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER
);
149 ImplRegisterProperty( BASEPROPERTY_HELPTEXT
);
150 ImplRegisterProperty( BASEPROPERTY_HELPURL
);
151 ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN
);
152 ImplRegisterProperty( BASEPROPERTY_PRINTABLE
);
153 ImplRegisterProperty( BASEPROPERTY_REPEAT
);
154 ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY
);
155 ImplRegisterProperty( BASEPROPERTY_READONLY
);
156 ImplRegisterProperty( BASEPROPERTY_SPIN
);
157 ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT
);
158 ImplRegisterProperty( BASEPROPERTY_TABSTOP
);
159 ImplRegisterProperty( BASEPROPERTY_TEXT
);
160 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR
);
161 ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION
);
162 ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT
);
163 ImplRegisterProperty( BASEPROPERTY_WRITING_MODE
);
164 ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE
);
165 ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR
);
168 aTreatAsNumber
<<= (sal_Bool
) sal_True
;
169 ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER
, aTreatAsNumber
);
171 lcl_registerDefaultFormatsClient();
174 // -------------------------------------------------------------------
175 UnoControlFormattedFieldModel::~UnoControlFormattedFieldModel()
179 // -------------------------------------------------------------------
180 ::rtl::OUString
UnoControlFormattedFieldModel::getServiceName() throw(RuntimeException
)
182 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedFieldModel
);
185 // -------------------------------------------------------------------
186 void SAL_CALL
UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw (Exception
)
188 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle
, rValue
);
192 case BASEPROPERTY_EFFECTIVE_VALUE
:
193 if ( !m_bSettingValueAndText
)
194 impl_updateTextFromValue_nothrow();
196 case BASEPROPERTY_FORMATSSUPPLIER
:
197 impl_updateCachedFormatter_nothrow();
198 impl_updateTextFromValue_nothrow();
200 case BASEPROPERTY_FORMATKEY
:
201 impl_updateCachedFormatKey_nothrow();
202 impl_updateTextFromValue_nothrow();
207 // -------------------------------------------------------------------
208 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
210 if ( !m_xCachedFormatter
.is() )
211 impl_updateCachedFormatter_nothrow();
212 if ( !m_xCachedFormatter
.is() )
218 getFastPropertyValue( aEffectiveValue
, BASEPROPERTY_EFFECTIVE_VALUE
);
220 ::rtl::OUString sStringValue
;
221 if ( !( aEffectiveValue
>>= sStringValue
) )
223 double nDoubleValue(0);
224 if ( aEffectiveValue
>>= nDoubleValue
)
226 sal_Int32
nFormatKey( 0 );
227 if ( m_aCachedFormat
.hasValue() )
228 m_aCachedFormat
>>= nFormatKey
;
229 sStringValue
= m_xCachedFormatter
->convertNumberToString( nFormatKey
, nDoubleValue
);
233 Reference
< XPropertySet
> xThis( *this, UNO_QUERY
);
234 xThis
->setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT
), makeAny( sStringValue
) );
236 catch( const Exception
& )
238 DBG_UNHANDLED_EXCEPTION();
242 // -------------------------------------------------------------------
243 void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow()
245 Any aFormatsSupplier
;
246 getFastPropertyValue( aFormatsSupplier
, BASEPROPERTY_FORMATSSUPPLIER
);
249 Reference
< XNumberFormatsSupplier
> xSupplier( aFormatsSupplier
, UNO_QUERY
);
250 if ( !xSupplier
.is() )
251 xSupplier
= lcl_getDefaultFormats_throw();
253 if ( !m_xCachedFormatter
.is() )
255 m_xCachedFormatter
= Reference
< XNumberFormatter
>(
256 ::comphelper::createProcessComponent( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" ) ) ),
260 m_xCachedFormatter
->attachNumberFormatsSupplier( xSupplier
);
262 catch( const Exception
& )
264 DBG_UNHANDLED_EXCEPTION();
268 // -------------------------------------------------------------------
269 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
272 getFastPropertyValue( aFormatKey
, BASEPROPERTY_FORMATKEY
);
273 m_aCachedFormat
= aFormatKey
;
276 // -------------------------------------------------------------------
277 void UnoControlFormattedFieldModel::dispose( ) throw(RuntimeException
)
279 UnoControlModel::dispose();
281 ::osl::MutexGuard
aGuard( GetMutex() );
282 if ( !m_bRevokedAsClient
)
284 lcl_revokeDefaultFormatsClient();
285 m_bRevokedAsClient
= true;
289 // -------------------------------------------------------------------
290 void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount
, sal_Int32
* _pHandles
,
291 Any
* _pValues
, sal_Int32
* _pValidHandles
) const SAL_THROW(())
293 ImplEnsureHandleOrder( _nCount
, _pHandles
, _pValues
, BASEPROPERTY_EFFECTIVE_VALUE
, BASEPROPERTY_TEXT
);
295 UnoControlModel::ImplNormalizePropertySequence( _nCount
, _pHandles
, _pValues
, _pValidHandles
);
298 // -------------------------------------------------------------------
301 class ResetFlagOnExit
307 ResetFlagOnExit( bool& _rFlag
)
318 // -------------------------------------------------------------------
319 void SAL_CALL
UnoControlFormattedFieldModel::setPropertyValues( const Sequence
< ::rtl::OUString
>& _rPropertyNames
, const Sequence
< Any
>& _rValues
) throw(PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
321 bool bSettingValue
= false;
322 bool bSettingText
= false;
323 for ( const ::rtl::OUString
* pPropertyNames
= _rPropertyNames
.getConstArray();
324 pPropertyNames
!= _rPropertyNames
.getConstArray() + _rPropertyNames
.getLength();
328 if ( BASEPROPERTY_EFFECTIVE_VALUE
== GetPropertyId( *pPropertyNames
) )
329 bSettingValue
= true;
331 if ( BASEPROPERTY_TEXT
== GetPropertyId( *pPropertyNames
) )
335 m_bSettingValueAndText
= ( bSettingValue
&& bSettingText
);
336 ResetFlagOnExit
aResetFlag( m_bSettingValueAndText
);
337 UnoControlModel::setPropertyValues( _rPropertyNames
, _rValues
);
340 // -------------------------------------------------------------------
341 sal_Bool
UnoControlFormattedFieldModel::convertFastPropertyValue(
342 Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nPropId
,
343 const Any
& rValue
) throw (IllegalArgumentException
)
345 if ( BASEPROPERTY_EFFECTIVE_DEFAULT
== nPropId
&& rValue
.hasValue() )
349 ::rtl::OUString sVal
;
350 sal_Bool bStreamed
= (rValue
>>= dVal
);
353 rConvertedValue
<<= dVal
;
357 bStreamed
= (rValue
>>= nVal
);
360 rConvertedValue
<<= static_cast<double>(nVal
);
364 bStreamed
= (rValue
>>= sVal
);
367 rConvertedValue
<<= sVal
;
374 getFastPropertyValue( rOldValue
, nPropId
);
375 return !CompareProperties( rConvertedValue
, rOldValue
);
378 throw IllegalArgumentException(
379 ( ::rtl::OUString::createFromAscii("Unable to convert the given value for the property ")
380 += GetPropertyName((sal_uInt16
)nPropId
) )
381 += ::rtl::OUString::createFromAscii(" (double, integer, or string expected)."),
382 static_cast< XPropertySet
* >(this),
386 return UnoControlModel::convertFastPropertyValue( rConvertedValue
, rOldValue
, nPropId
, rValue
);
389 // -------------------------------------------------------------------
390 Any
UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId
) const
395 case BASEPROPERTY_DEFAULTCONTROL
: aReturn
<<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedField
) ); break;
397 case BASEPROPERTY_TREATASNUMBER
: aReturn
<<= (sal_Bool
)sal_True
; break;
399 case BASEPROPERTY_EFFECTIVE_DEFAULT
:
400 case BASEPROPERTY_EFFECTIVE_VALUE
:
401 case BASEPROPERTY_EFFECTIVE_MAX
:
402 case BASEPROPERTY_EFFECTIVE_MIN
:
403 case BASEPROPERTY_FORMATKEY
:
404 case BASEPROPERTY_FORMATSSUPPLIER
:
408 default : aReturn
= UnoControlModel::ImplGetDefaultValue( nPropId
); break;
414 // -------------------------------------------------------------------
415 ::cppu::IPropertyArrayHelper
& UnoControlFormattedFieldModel::getInfoHelper()
417 static UnoPropertyArrayHelper
* pHelper
= NULL
;
420 Sequence
<sal_Int32
> aIDs
= ImplGetPropertyIds();
421 pHelper
= new UnoPropertyArrayHelper( aIDs
);
426 // beans::XMultiPropertySet
427 // -------------------------------------------------------------------
428 Reference
< XPropertySetInfo
> UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException
)
430 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
434 // ===================================================================
435 // = UnoFormattedFieldControl
436 // ===================================================================
437 // -------------------------------------------------------------------
438 UnoFormattedFieldControl::UnoFormattedFieldControl()
442 // -------------------------------------------------------------------
443 ::rtl::OUString
UnoFormattedFieldControl::GetComponentServiceName()
445 return ::rtl::OUString::createFromAscii( "FormattedField" );
448 // -------------------------------------------------------------------
449 void UnoFormattedFieldControl::textChanged(const TextEvent
& e
) throw(RuntimeException
)
451 Reference
< XVclWindowPeer
> xPeer(getPeer(), UNO_QUERY
);
452 OSL_ENSURE(xPeer
.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?");
454 Sequence
< ::rtl::OUString
> aNames( 2 );
455 aNames
[0] = GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE
);
456 aNames
[1] = GetPropertyName( BASEPROPERTY_TEXT
);
458 Sequence
< Any
> aValues( 2 );
459 aValues
[0] = xPeer
->getProperty( aNames
[0] );
460 aValues
[1] = xPeer
->getProperty( aNames
[1] );
462 ImplSetPropertyValues( aNames
, aValues
, FALSE
);
464 if ( GetTextListeners().getLength() )
465 GetTextListeners().textChanged( e
);
468 //........................................................................
469 } // namespace toolkit
470 //........................................................................