Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / toolkit / source / controls / formattedcontrol.cxx
blob1770cab7bd7304d84f62a9920b79a888a07e15a4
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 <controls/formattedcontrol.hxx>
21 #include <helper/property.hxx>
23 #include <com/sun/star/awt/XVclWindowPeer.hpp>
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <com/sun/star/util/NumberFormatter.hpp>
26 #include <com/sun/star/util/NumberFormatsSupplier.hpp>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <osl/diagnose.h>
32 #include <helper/unopropertyarrayhelper.hxx>
33 #include <mutex>
35 namespace toolkit
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::awt;
41 using namespace ::com::sun::star::lang;
42 using namespace ::com::sun::star::beans;
43 using namespace ::com::sun::star::util;
46 namespace
49 std::mutex& getDefaultFormatsMutex()
51 static std::mutex s_aDefaultFormatsMutex;
52 return s_aDefaultFormatsMutex;
55 Reference< XNumberFormatsSupplier > s_xDefaultFormats;
56 bool s_bTriedCreation = false;
57 oslInterlockedCount s_refCount(0);
59 const Reference< XNumberFormatsSupplier >& lcl_getDefaultFormats_throw()
61 std::scoped_lock aGuard( getDefaultFormatsMutex() );
63 if ( !s_xDefaultFormats.is() && !s_bTriedCreation )
65 s_bTriedCreation = true;
66 s_xDefaultFormats = NumberFormatsSupplier::createWithDefaultLocale( ::comphelper::getProcessComponentContext() );
68 if ( !s_xDefaultFormats.is() )
69 throw RuntimeException();
71 return s_xDefaultFormats;
74 void lcl_registerDefaultFormatsClient()
76 osl_atomic_increment( &s_refCount );
79 void lcl_revokeDefaultFormatsClient()
81 Reference< XNumberFormatsSupplier > xReleasePotentialLastReference;
83 std::scoped_lock aGuard( getDefaultFormatsMutex() );
84 if ( 0 != osl_atomic_decrement( &s_refCount ) )
85 return;
87 xReleasePotentialLastReference = std::move(s_xDefaultFormats);
88 s_bTriedCreation = false;
90 xReleasePotentialLastReference.clear();
95 // = UnoControlFormattedFieldModel
98 UnoControlFormattedFieldModel::UnoControlFormattedFieldModel( const Reference< XComponentContext >& rxContext )
99 :UnoControlModel( rxContext )
100 ,m_bRevokedAsClient( false )
101 ,m_bSettingValueAndText( false )
103 ImplRegisterProperty( BASEPROPERTY_ALIGN );
104 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
105 ImplRegisterProperty( BASEPROPERTY_BORDER );
106 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
107 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
108 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT );
109 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE );
110 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX );
111 ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN );
112 ImplRegisterProperty( BASEPROPERTY_ENABLED );
113 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE );
114 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
115 ImplRegisterProperty( BASEPROPERTY_FORMATKEY );
116 ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER );
117 ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
118 ImplRegisterProperty( BASEPROPERTY_HELPURL );
119 ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN );
120 ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
121 ImplRegisterProperty( BASEPROPERTY_REPEAT );
122 ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY );
123 ImplRegisterProperty( BASEPROPERTY_READONLY );
124 ImplRegisterProperty( BASEPROPERTY_SPIN );
125 ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT );
126 ImplRegisterProperty( BASEPROPERTY_TABSTOP );
127 ImplRegisterProperty( BASEPROPERTY_TEXT );
128 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
129 ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION );
130 ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT );
131 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
132 ImplRegisterProperty( BASEPROPERTY_WRITING_MODE );
133 ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE );
134 ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR );
135 ImplRegisterProperty( BASEPROPERTY_HIGHLIGHT_COLOR );
136 ImplRegisterProperty( BASEPROPERTY_HIGHLIGHT_TEXT_COLOR );
138 Any aTreatAsNumber;
139 aTreatAsNumber <<= true;
140 ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER, aTreatAsNumber );
142 lcl_registerDefaultFormatsClient();
146 UnoControlFormattedFieldModel::~UnoControlFormattedFieldModel()
151 OUString UnoControlFormattedFieldModel::getServiceName()
153 return u"stardiv.vcl.controlmodel.FormattedField"_ustr;
157 void UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const Any& rValue )
159 UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue );
161 switch ( nHandle )
163 case BASEPROPERTY_EFFECTIVE_VALUE:
164 if ( !m_bSettingValueAndText )
165 impl_updateTextFromValue_nothrow(rGuard);
166 break;
167 case BASEPROPERTY_FORMATSSUPPLIER:
168 impl_updateCachedFormatter_nothrow(rGuard);
169 impl_updateTextFromValue_nothrow(rGuard);
170 break;
171 case BASEPROPERTY_FORMATKEY:
172 impl_updateCachedFormatKey_nothrow(rGuard);
173 impl_updateTextFromValue_nothrow(rGuard);
174 break;
179 void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow( std::unique_lock<std::mutex>& rGuard)
181 if ( !m_xCachedFormatter.is() )
182 impl_updateCachedFormatter_nothrow(rGuard);
183 if ( !m_xCachedFormatter.is() )
184 return;
188 Any aEffectiveValue;
189 getFastPropertyValue( rGuard, aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE );
191 OUString sStringValue;
192 if ( !( aEffectiveValue >>= sStringValue ) )
194 double nDoubleValue(0);
195 if ( aEffectiveValue >>= nDoubleValue )
197 sal_Int32 nFormatKey( 0 );
198 if ( m_aCachedFormat.hasValue() )
199 m_aCachedFormat >>= nFormatKey;
200 sStringValue = m_xCachedFormatter->convertNumberToString( nFormatKey, nDoubleValue );
204 setFastPropertyValueImpl( rGuard, BASEPROPERTY_TEXT, Any( sStringValue ) );
206 catch( const Exception& )
208 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
213 void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow(std::unique_lock<std::mutex>& rGuard)
215 Any aFormatsSupplier;
216 getFastPropertyValue( rGuard, aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER );
219 Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, UNO_QUERY );
220 if ( !xSupplier.is() )
221 xSupplier = lcl_getDefaultFormats_throw();
223 if ( !m_xCachedFormatter.is() )
225 m_xCachedFormatter.set(
226 NumberFormatter::create(::comphelper::getProcessComponentContext()),
227 UNO_QUERY_THROW
230 m_xCachedFormatter->attachNumberFormatsSupplier( xSupplier );
232 catch( const Exception& )
234 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
238 void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow(std::unique_lock<std::mutex>& rGuard)
240 Any aFormatKey;
241 getFastPropertyValue( rGuard, aFormatKey, BASEPROPERTY_FORMATKEY );
242 m_aCachedFormat = std::move(aFormatKey);
245 void UnoControlFormattedFieldModel::dispose( )
247 UnoControlModel::dispose();
249 std::unique_lock aGuard( m_aMutex );
250 if ( !m_bRevokedAsClient )
252 lcl_revokeDefaultFormatsClient();
253 m_bRevokedAsClient = true;
258 void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount, sal_Int32* _pHandles,
259 Any* _pValues, sal_Int32* _pValidHandles ) const
261 ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_EFFECTIVE_VALUE, BASEPROPERTY_TEXT );
263 UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles );
267 namespace
269 class ResetFlagOnExit
271 private:
272 bool& m_rFlag;
274 public:
275 explicit ResetFlagOnExit( bool& _rFlag )
276 :m_rFlag( _rFlag )
279 ~ResetFlagOnExit()
281 m_rFlag = false;
287 void SAL_CALL UnoControlFormattedFieldModel::setPropertyValues( const Sequence< OUString >& _rPropertyNames, const Sequence< Any >& _rValues )
289 bool bSettingValue = false;
290 bool bSettingText = false;
291 for ( auto const & propertyName : _rPropertyNames )
293 if ( BASEPROPERTY_EFFECTIVE_VALUE == GetPropertyId( propertyName ) )
294 bSettingValue = true;
296 if ( BASEPROPERTY_TEXT == GetPropertyId( propertyName ) )
297 bSettingText = true;
300 m_bSettingValueAndText = ( bSettingValue && bSettingText );
301 ResetFlagOnExit aResetFlag( m_bSettingValueAndText );
302 UnoControlModel::setPropertyValues( _rPropertyNames, _rValues );
306 bool UnoControlFormattedFieldModel::convertFastPropertyValue(
307 std::unique_lock<std::mutex>& rGuard,
308 Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId,
309 const Any& rValue )
311 if ( BASEPROPERTY_EFFECTIVE_DEFAULT == nPropId && rValue.hasValue() )
313 double dVal = 0;
314 bool bStreamed = (rValue >>= dVal);
315 if ( bStreamed )
317 rConvertedValue <<= dVal;
319 else
321 sal_Int32 nVal = 0;
322 bStreamed = (rValue >>= nVal);
323 if ( bStreamed )
325 rConvertedValue <<= static_cast<double>(nVal);
327 else
329 OUString sVal;
330 bStreamed = (rValue >>= sVal);
331 if ( bStreamed )
333 rConvertedValue <<= sVal;
338 if ( bStreamed )
340 getFastPropertyValue( rGuard, rOldValue, nPropId );
341 return !CompareProperties( rConvertedValue, rOldValue );
344 throw IllegalArgumentException(
345 ("Unable to convert the given value for the property "
346 + GetPropertyName(static_cast<sal_uInt16>(nPropId))
347 + " (double, integer, or string expected)."),
348 static_cast< XPropertySet* >(this),
352 return UnoControlModel::convertFastPropertyValue( rGuard, rConvertedValue, rOldValue, nPropId, rValue );
356 Any UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
358 Any aReturn;
359 switch (nPropId)
361 case BASEPROPERTY_DEFAULTCONTROL: aReturn <<= u"stardiv.vcl.control.FormattedField"_ustr; break;
363 case BASEPROPERTY_TREATASNUMBER: aReturn <<= true; break;
365 case BASEPROPERTY_EFFECTIVE_DEFAULT:
366 case BASEPROPERTY_EFFECTIVE_VALUE:
367 case BASEPROPERTY_EFFECTIVE_MAX:
368 case BASEPROPERTY_EFFECTIVE_MIN:
369 case BASEPROPERTY_FORMATKEY:
370 case BASEPROPERTY_FORMATSSUPPLIER:
371 // (void)
372 break;
374 default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break;
377 return aReturn;
381 ::cppu::IPropertyArrayHelper& UnoControlFormattedFieldModel::getInfoHelper()
383 static UnoPropertyArrayHelper aHelper( ImplGetPropertyIds() );
384 return aHelper;
387 // beans::XMultiPropertySet
389 Reference< XPropertySetInfo > UnoControlFormattedFieldModel::getPropertySetInfo( )
391 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
392 return xInfo;
395 OUString UnoControlFormattedFieldModel::getImplementationName()
397 return u"stardiv.Toolkit.UnoControlFormattedFieldModel"_ustr;
400 css::uno::Sequence<OUString>
401 UnoControlFormattedFieldModel::getSupportedServiceNames()
403 auto s(UnoControlModel::getSupportedServiceNames());
404 s.realloc(s.getLength() + 2);
405 auto ps = s.getArray();
406 ps[s.getLength() - 2] = "com.sun.star.awt.UnoControlFormattedFieldModel";
407 ps[s.getLength() - 1] = "stardiv.vcl.controlmodel.FormattedField";
408 return s;
411 // = UnoFormattedFieldControl
414 UnoFormattedFieldControl::UnoFormattedFieldControl()
419 OUString UnoFormattedFieldControl::GetComponentServiceName() const
421 return u"FormattedField"_ustr;
425 void UnoFormattedFieldControl::textChanged(const TextEvent& e)
427 Reference< XVclWindowPeer > xPeer(getPeer(), UNO_QUERY);
428 OSL_ENSURE(xPeer.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?");
430 Sequence< OUString > aNames{ GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE ),
431 GetPropertyName( BASEPROPERTY_TEXT ) };
433 Sequence< Any > aValues{ xPeer->getProperty( aNames[0] ),
434 xPeer->getProperty( aNames[1] ) };
436 ImplSetPropertyValues( aNames, aValues, false );
438 if ( GetTextListeners().getLength() )
439 GetTextListeners().textChanged( e );
442 OUString UnoFormattedFieldControl::getImplementationName()
444 return u"stardiv.Toolkit.UnoFormattedFieldControl"_ustr;
447 css::uno::Sequence<OUString>
448 UnoFormattedFieldControl::getSupportedServiceNames()
450 auto s(UnoEditControl::getSupportedServiceNames());
451 s.realloc(s.getLength() + 2);
452 auto ps = s.getArray();
453 ps[s.getLength() - 2] = "com.sun.star.awt.UnoControlFormattedField";
454 ps[s.getLength() - 1] = "stardiv.vcl.control.FormattedField";
455 return s;
457 } // namespace toolkit
460 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
461 stardiv_Toolkit_UnoControlFormattedFieldModel_get_implementation(
462 css::uno::XComponentContext *context,
463 css::uno::Sequence<css::uno::Any> const &)
465 return cppu::acquire(new toolkit::UnoControlFormattedFieldModel(context));
468 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
469 stardiv_Toolkit_UnoFormattedFieldControl_get_implementation(
470 css::uno::XComponentContext *,
471 css::uno::Sequence<css::uno::Any> const &)
473 return cppu::acquire(new toolkit::UnoFormattedFieldControl());
476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */