Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / toolkit / source / controls / formattedcontrol.cxx
blobe08957dc924d3ef335cf6dfe3efe69cc384119fb
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/XNumberFormatsSupplier.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 = Reference< XNumberFormatsSupplier >(
78 ::comphelper::getProcessServiceFactory()->createInstance(
79 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatsSupplier" ) ) ),
80 UNO_QUERY_THROW
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;
109 aGuard.clear();
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 );
157 Any aTreatAsNumber;
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 );
180 switch ( nHandle )
182 case BASEPROPERTY_EFFECTIVE_VALUE:
183 if ( !m_bSettingValueAndText )
184 impl_updateTextFromValue_nothrow();
185 break;
186 case BASEPROPERTY_FORMATSSUPPLIER:
187 impl_updateCachedFormatter_nothrow();
188 impl_updateTextFromValue_nothrow();
189 break;
190 case BASEPROPERTY_FORMATKEY:
191 impl_updateCachedFormatKey_nothrow();
192 impl_updateTextFromValue_nothrow();
193 break;
197 // -------------------------------------------------------------------
198 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
200 if ( !m_xCachedFormatter.is() )
201 impl_updateCachedFormatter_nothrow();
202 if ( !m_xCachedFormatter.is() )
203 return;
207 Any aEffectiveValue;
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()),
247 UNO_QUERY_THROW
250 m_xCachedFormatter->attachNumberFormatsSupplier( xSupplier );
252 catch( const Exception& )
254 DBG_UNHANDLED_EXCEPTION();
258 // -------------------------------------------------------------------
259 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
261 Any aFormatKey;
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 // -------------------------------------------------------------------
289 namespace
291 class ResetFlagOnExit
293 private:
294 bool& m_rFlag;
296 public:
297 ResetFlagOnExit( bool& _rFlag )
298 :m_rFlag( _rFlag )
301 ~ResetFlagOnExit()
303 m_rFlag = false;
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();
315 ++pPropertyNames
318 if ( BASEPROPERTY_EFFECTIVE_VALUE == GetPropertyId( *pPropertyNames ) )
319 bSettingValue = true;
321 if ( BASEPROPERTY_TEXT == GetPropertyId( *pPropertyNames ) )
322 bSettingText = true;
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() )
337 double dVal = 0;
338 ::rtl::OUString sVal;
339 sal_Bool bStreamed = (rValue >>= dVal);
340 if ( bStreamed )
342 rConvertedValue <<= dVal;
344 else
346 sal_Int32 nVal = 0;
347 bStreamed = (rValue >>= nVal);
348 if ( bStreamed )
350 rConvertedValue <<= static_cast<double>(nVal);
352 else
354 bStreamed = (rValue >>= sVal);
355 if ( bStreamed )
357 rConvertedValue <<= sVal;
362 if ( bStreamed )
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
382 Any aReturn;
383 switch (nPropId)
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:
395 // (void)
396 break;
398 default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break;
401 return aReturn;
404 // -------------------------------------------------------------------
405 ::cppu::IPropertyArrayHelper& UnoControlFormattedFieldModel::getInfoHelper()
407 static UnoPropertyArrayHelper* pHelper = NULL;
408 if ( !pHelper )
410 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
411 pHelper = new UnoPropertyArrayHelper( aIDs );
413 return *pHelper;
416 // beans::XMultiPropertySet
417 // -------------------------------------------------------------------
418 Reference< XPropertySetInfo > UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException)
420 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
421 return xInfo;
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: */