LCOV - code coverage report
Current view: top level - forms/source/component - FormattedField.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 187 521 35.9 %
Date: 2015-06-13 12:38:46 Functions: 34 60 56.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : #include "FormattedField.hxx"
      20             : #include "services.hxx"
      21             : #include "property.hrc"
      22             : #include "property.hxx"
      23             : #include "frm_resource.hxx"
      24             : #include "frm_resource.hrc"
      25             : #include "propertybaghelper.hxx"
      26             : #include <comphelper/sequence.hxx>
      27             : #include <comphelper/numbers.hxx>
      28             : #include <connectivity/dbtools.hxx>
      29             : #include <connectivity/dbconversion.hxx>
      30             : #include <svl/zforlist.hxx>
      31             : #include <svl/numuno.hxx>
      32             : #include <vcl/svapp.hxx>
      33             : #include <vcl/settings.hxx>
      34             : #include <tools/debug.hxx>
      35             : #include <tools/wintypes.hxx>
      36             : #include <i18nlangtag/languagetag.hxx>
      37             : #include <rtl/textenc.h>
      38             : #include <com/sun/star/sdbc/DataType.hpp>
      39             : #include <com/sun/star/util/NumberFormat.hpp>
      40             : #include <com/sun/star/util/Date.hpp>
      41             : #include <com/sun/star/util/Time.hpp>
      42             : #include <com/sun/star/awt/MouseEvent.hpp>
      43             : #include <com/sun/star/form/XSubmit.hpp>
      44             : #include <com/sun/star/awt/XWindow.hpp>
      45             : #include <com/sun/star/awt/XKeyListener.hpp>
      46             : #include <com/sun/star/form/FormComponentType.hpp>
      47             : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
      48             : #include <com/sun/star/util/XNumberFormatTypes.hpp>
      49             : #include <com/sun/star/form/XForm.hpp>
      50             : #include <com/sun/star/container/XIndexAccess.hpp>
      51             : #include <osl/mutex.hxx>
      52             : // needed as long as we use the SolarMutex
      53             : #include <comphelper/streamsection.hxx>
      54             : #include <cppuhelper/weakref.hxx>
      55             : #include <unotools/desktopterminationobserver.hxx>
      56             : #include <list>
      57             : #include <algorithm>
      58             : 
      59             : 
      60             : using namespace dbtools;
      61             : using namespace ::com::sun::star::uno;
      62             : using namespace ::com::sun::star::sdb;
      63             : using namespace ::com::sun::star::sdbc;
      64             : using namespace ::com::sun::star::sdbcx;
      65             : using namespace ::com::sun::star::beans;
      66             : using namespace ::com::sun::star::container;
      67             : using namespace ::com::sun::star::form;
      68             : using namespace ::com::sun::star::awt;
      69             : using namespace ::com::sun::star::io;
      70             : using namespace ::com::sun::star::lang;
      71             : using namespace ::com::sun::star::util;
      72             : using namespace ::com::sun::star::form::binding;
      73             : 
      74             : namespace
      75             : {
      76             :     typedef com::sun::star::util::Date UNODate;
      77             :     typedef com::sun::star::util::Time UNOTime;
      78             :     typedef com::sun::star::util::DateTime UNODateTime;
      79             : }
      80             : 
      81             : namespace frm
      82             : {
      83             : class StandardFormatsSupplier : protected SvNumberFormatsSupplierObj, public ::utl::ITerminationListener
      84             : {
      85             : protected:
      86             :             SvNumberFormatter*                       m_pMyPrivateFormatter;
      87             :     static  WeakReference< XNumberFormatsSupplier >  s_xDefaultFormatsSupplier;
      88             : public:
      89             :     static Reference< XNumberFormatsSupplier > get( const Reference< XComponentContext >& _rxORB );
      90             :     using SvNumberFormatsSupplierObj::operator new;
      91             :     using SvNumberFormatsSupplierObj::operator delete;
      92             : protected:
      93             :     StandardFormatsSupplier(const Reference< XComponentContext >& _rxFactory,LanguageType _eSysLanguage);
      94             :     virtual ~StandardFormatsSupplier();
      95             : protected:
      96             :     virtual bool    queryTermination() const SAL_OVERRIDE;
      97             :     virtual void    notifyTermination() SAL_OVERRIDE;
      98             : };
      99          46 : WeakReference< XNumberFormatsSupplier > StandardFormatsSupplier::s_xDefaultFormatsSupplier;
     100          16 : StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XComponentContext > & _rxContext,LanguageType _eSysLanguage)
     101             :     :SvNumberFormatsSupplierObj()
     102          16 :     ,m_pMyPrivateFormatter(new SvNumberFormatter(_rxContext, _eSysLanguage))
     103             : {
     104          16 :     SetNumberFormatter(m_pMyPrivateFormatter);
     105             :     // #i29147#
     106          16 :     ::utl::DesktopTerminationObserver::registerTerminationListener( this );
     107          16 : }
     108          48 : StandardFormatsSupplier::~StandardFormatsSupplier()
     109             : {
     110          16 :     ::utl::DesktopTerminationObserver::revokeTerminationListener( this );
     111          16 :     DELETEZ( m_pMyPrivateFormatter );
     112          32 : }
     113          16 : Reference< XNumberFormatsSupplier > StandardFormatsSupplier::get( const Reference< XComponentContext >& _rxORB )
     114             : {
     115          16 :     LanguageType eSysLanguage = LANGUAGE_SYSTEM;
     116             :     {
     117          16 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     118          32 :         Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
     119          16 :         if ( xSupplier.is() )
     120           0 :             return xSupplier;
     121             :         // get the Office's locale
     122          32 :         eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
     123             :     }
     124          16 :     StandardFormatsSupplier* pSupplier = new StandardFormatsSupplier( _rxORB, eSysLanguage );
     125          16 :     Reference< XNumberFormatsSupplier > xNewlyCreatedSupplier( pSupplier );
     126             :     {
     127          16 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     128          32 :         Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
     129          16 :         if ( xSupplier.is() )
     130             :             // somebody used the small time frame where the mutex was not locked to create and set
     131             :             // the supplier
     132           0 :             return xSupplier;
     133          32 :         s_xDefaultFormatsSupplier = xNewlyCreatedSupplier;
     134             :     }
     135          16 :     return xNewlyCreatedSupplier;
     136             : }
     137           0 : bool StandardFormatsSupplier::queryTermination() const
     138             : {
     139           0 :     return true;
     140             : }
     141           0 : void StandardFormatsSupplier::notifyTermination()
     142             : {
     143           0 :     Reference< XNumberFormatsSupplier > xKeepAlive = this;
     144             :     // when the application is terminating, release our static reference so that we are cleared/destructed
     145             :     // earlier than upon unloading the library
     146             :     // #i29147#
     147           0 :     s_xDefaultFormatsSupplier = WeakReference< XNumberFormatsSupplier >( );
     148           0 :     SetNumberFormatter( NULL );
     149           0 :     DELETEZ( m_pMyPrivateFormatter );
     150           0 : }
     151           0 : Sequence<Type> OFormattedControl::_getTypes()
     152             : {
     153             :     return ::comphelper::concatSequences(
     154             :         OFormattedControl_BASE::getTypes(),
     155             :         OBoundControl::_getTypes()
     156           0 :     );
     157             : }
     158         110 : Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException, std::exception)
     159             : {
     160         110 :     Any aReturn = OBoundControl::queryAggregation(_rType);
     161         110 :     if (!aReturn.hasValue())
     162           2 :         aReturn = OFormattedControl_BASE::queryInterface(_rType);
     163         110 :     return aReturn;
     164             : }
     165           2 : OFormattedControl::OFormattedControl(const Reference<XComponentContext>& _rxFactory)
     166             :                :OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD)
     167           2 :                ,m_nKeyEvent(0)
     168             : {
     169           2 :     osl_atomic_increment(&m_refCount);
     170             :     {
     171           2 :         Reference<XWindow>  xComp;
     172           2 :         if (query_aggregation(m_xAggregate, xComp))
     173             :         {
     174           2 :             xComp->addKeyListener(this);
     175           2 :         }
     176             :     }
     177           2 :     osl_atomic_decrement(&m_refCount);
     178           2 : }
     179           6 : OFormattedControl::~OFormattedControl()
     180             : {
     181           2 :     if( m_nKeyEvent )
     182           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     183           2 :     if (!OComponentHelper::rBHelper.bDisposed)
     184             :     {
     185           0 :         acquire();
     186           0 :         dispose();
     187             :     }
     188           4 : }
     189             : 
     190             : // XKeyListener
     191           4 : void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException, std::exception)
     192             : {
     193           4 :     OBoundControl::disposing(_rSource);
     194           4 : }
     195           0 : void OFormattedControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     196             : {
     197           0 :     if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
     198           0 :         return;
     199             :     // Is the control located in a form with a Submit URL?
     200           0 :     Reference<com::sun::star::beans::XPropertySet>  xSet(getModel(), UNO_QUERY);
     201           0 :     if( !xSet.is() )
     202           0 :         return;
     203           0 :     Reference<XFormComponent>  xFComp(xSet, UNO_QUERY);
     204           0 :     InterfaceRef  xParent = xFComp->getParent();
     205           0 :     if( !xParent.is() )
     206           0 :         return;
     207           0 :     Reference<com::sun::star::beans::XPropertySet>  xFormSet(xParent, UNO_QUERY);
     208           0 :     if( !xFormSet.is() )
     209           0 :         return;
     210           0 :     Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL ));
     211           0 :     if (!isA(aTmp, static_cast< OUString* >(NULL)) ||
     212           0 :         getString(aTmp).isEmpty() )
     213           0 :         return;
     214           0 :     Reference<XIndexAccess>  xElements(xParent, UNO_QUERY);
     215           0 :     sal_Int32 nCount = xElements->getCount();
     216           0 :     if( nCount > 1 )
     217             :     {
     218           0 :         Reference<com::sun::star::beans::XPropertySet>  xFCSet;
     219           0 :         for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
     220             :         {
     221             :             //  Any aElement(xElements->getByIndex(nIndex));
     222           0 :             xElements->getByIndex(nIndex) >>= xFCSet;
     223           0 :             if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
     224           0 :                 getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
     225             :             {
     226             :                 // Found another Edit -> Do not submit then
     227           0 :                 if (xFCSet != xSet)
     228           0 :                     return;
     229             :             }
     230           0 :         }
     231             :     }
     232             :     // Because we're still in the Handler, execute submit asynchronously
     233           0 :     if( m_nKeyEvent )
     234           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     235             :     m_nKeyEvent = Application::PostUserEvent( LINK(this, OFormattedControl,
     236           0 :                                             OnKeyPressed) );
     237             : }
     238             : 
     239           0 : void OFormattedControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     240             : {
     241           0 : }
     242             : 
     243           0 : IMPL_LINK_NOARG(OFormattedControl, OnKeyPressed)
     244             : {
     245           0 :     m_nKeyEvent = 0;
     246           0 :     Reference<XFormComponent>  xFComp(getModel(), UNO_QUERY);
     247           0 :     InterfaceRef  xParent = xFComp->getParent();
     248           0 :     Reference<XSubmit>  xSubmit(xParent, UNO_QUERY);
     249           0 :     if (xSubmit.is())
     250           0 :         xSubmit->submit( Reference<XControl> (), ::com::sun::star::awt::MouseEvent() );
     251           0 :     return 0L;
     252             : }
     253             : 
     254           1 : StringSequence  OFormattedControl::getSupportedServiceNames() throw(std::exception)
     255             : {
     256           1 :     StringSequence aSupported = OBoundControl::getSupportedServiceNames();
     257           1 :     aSupported.realloc(aSupported.getLength() + 2);
     258           1 :     OUString*pArray = aSupported.getArray();
     259           1 :     pArray[aSupported.getLength()-2] = FRM_SUN_CONTROL_FORMATTEDFIELD;
     260           1 :     pArray[aSupported.getLength()-1] = STARDIV_ONE_FORM_CONTROL_FORMATTEDFIELD;
     261           1 :     return aSupported;
     262             : }
     263             : 
     264           3 : void OFormattedControl::setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     265             : {
     266           3 :     OBoundControl::setDesignMode(bOn);
     267           3 : }
     268             : 
     269          16 : void OFormattedModel::implConstruct()
     270             : {
     271             :     // members
     272          16 :     m_bOriginalNumeric = false;
     273          16 :     m_bNumeric = false;
     274          16 :     m_xOriginalFormatter = NULL;
     275          16 :     m_nKeyType = NumberFormat::UNDEFINED;
     276          16 :     m_aNullDate = DBTypeConversion::getStandardDate();
     277          16 :     m_nFieldType =  DataType::OTHER;
     278             :     // default our formats supplier
     279          16 :     osl_atomic_increment(&m_refCount);
     280          16 :     setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     281          16 :     osl_atomic_decrement(&m_refCount);
     282          16 :     startAggregatePropertyListening( PROPERTY_FORMATKEY );
     283          16 :     startAggregatePropertyListening( PROPERTY_FORMATSSUPPLIER );
     284          16 : }
     285          16 : OFormattedModel::OFormattedModel(const Reference<XComponentContext>& _rxFactory)
     286             :     :OEditBaseModel(_rxFactory, VCL_CONTROLMODEL_FORMATTEDFIELD, FRM_SUN_CONTROL_FORMATTEDFIELD, true, true )
     287             :     // use the old control name for compytibility reasons
     288          16 :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     289             : {
     290          16 :     implConstruct();
     291          16 :     m_nClassId = FormComponentType::TEXTFIELD;
     292          16 :     initValueProperty( PROPERTY_EFFECTIVE_VALUE, PROPERTY_ID_EFFECTIVE_VALUE );
     293          16 : }
     294           0 : OFormattedModel::OFormattedModel( const OFormattedModel* _pOriginal, const Reference< XComponentContext >& _rxFactory )
     295             :     :OEditBaseModel( _pOriginal, _rxFactory )
     296           0 :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     297             : {
     298           0 :     implConstruct();
     299           0 : }
     300             : 
     301          32 : OFormattedModel::~OFormattedModel()
     302             : {
     303          32 : }
     304             : 
     305             : // XCloneable
     306           0 : IMPLEMENT_DEFAULT_CLONING( OFormattedModel )
     307             : 
     308          16 : void SAL_CALL OFormattedModel::disposing()
     309             : {
     310          16 :     OErrorBroadcaster::disposing();
     311          16 :     OEditBaseModel::disposing();
     312          16 : }
     313             : 
     314             : // XServiceInfo
     315           2 : StringSequence OFormattedModel::getSupportedServiceNames() throw(std::exception)
     316             : {
     317           2 :     StringSequence aSupported = OEditBaseModel::getSupportedServiceNames();
     318           2 :     sal_Int32 nOldLen = aSupported.getLength();
     319           2 :     aSupported.realloc( nOldLen + 9 );
     320           2 :     OUString* pStoreTo = aSupported.getArray() + nOldLen;
     321           2 :     *pStoreTo++ = BINDABLE_CONTROL_MODEL;
     322           2 :     *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
     323           2 :     *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
     324           2 :     *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
     325           2 :     *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
     326           2 :     *pStoreTo++ = FRM_SUN_COMPONENT_FORMATTEDFIELD;
     327           2 :     *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD;
     328           2 :     *pStoreTo++ = BINDABLE_DATABASE_FORMATTED_FIELD;
     329           2 :     *pStoreTo++ = FRM_COMPONENT_FORMATTEDFIELD;
     330           2 :     return aSupported;
     331             : }
     332             : 
     333             : // XAggregation
     334         571 : Any SAL_CALL OFormattedModel::queryAggregation(const Type& _rType) throw(RuntimeException, std::exception)
     335             : {
     336         571 :     Any aReturn = OEditBaseModel::queryAggregation( _rType );
     337         571 :     return aReturn.hasValue() ? aReturn : OErrorBroadcaster::queryInterface( _rType );
     338             : }
     339             : 
     340             : // XTypeProvider
     341           0 : Sequence< Type > OFormattedModel::_getTypes()
     342             : {
     343             :     return ::comphelper::concatSequences(
     344             :         OEditBaseModel::_getTypes(),
     345             :         OErrorBroadcaster::getTypes()
     346           0 :     );
     347             : }
     348             : 
     349             : // XPersistObject
     350           0 : OUString SAL_CALL OFormattedModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     351             : {
     352           0 :     return OUString(FRM_COMPONENT_EDIT);
     353             : }
     354             : 
     355             : // XPropertySet
     356          16 : void OFormattedModel::describeFixedProperties( Sequence< Property >& _rProps ) const
     357             : {
     358          16 :     BEGIN_DESCRIBE_PROPERTIES( 3, OEditBaseModel )
     359          16 :         DECL_BOOL_PROP1(EMPTY_IS_NULL,                          BOUND);
     360          16 :         DECL_PROP1(TABINDEX,            sal_Int16,              BOUND);
     361          16 :         DECL_BOOL_PROP2(FILTERPROPOSAL,                         BOUND, MAYBEDEFAULT);
     362             :     END_DESCRIBE_PROPERTIES();
     363          16 : }
     364             : 
     365          16 : void OFormattedModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
     366             : {
     367          16 :     OEditBaseModel::describeAggregateProperties( _rAggregateProps );
     368             :     // TreatAsNumeric is not transient: we want to attach it to the UI
     369             :     // This is necessary to make EffectiveDefault (which may be text or a number) meaningful
     370          16 :     ModifyPropertyAttributes(_rAggregateProps, PROPERTY_TREATASNUMERIC, 0, PropertyAttribute::TRANSIENT);
     371             :     // Same for FormatKey
     372             :     // (though the paragraph above for the TreatAsNumeric does not hold anymore - we do not have an UI for this.
     373             :     // But we have for the format key ...)
     374          16 :     ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, PropertyAttribute::TRANSIENT);
     375          16 :     RemoveProperty(_rAggregateProps, PROPERTY_STRICTFORMAT);
     376             :     // no strict format property for formatted fields: it does not make sense, 'cause
     377             :     // there is no general way to decide which characters/sub strings are allowed during the input of an
     378             :     // arbitraryly formatted control
     379          16 : }
     380             : 
     381         169 : void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
     382             : {
     383         169 :     OEditBaseModel::getFastPropertyValue(rValue, nHandle);
     384         169 : }
     385             : 
     386          29 : void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception, std::exception)
     387             : {
     388          29 :     OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
     389          29 : }
     390             : 
     391          29 : sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
     392             :                                                         throw( IllegalArgumentException )
     393             : {
     394          29 :     return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
     395             : }
     396             : 
     397          16 : void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle)
     398             : {
     399          16 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     400             :     {
     401          16 :         Reference<XNumberFormatsSupplier>  xSupplier = calcDefaultFormatsSupplier();
     402             :         DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !");
     403          16 :         if (m_xAggregateSet.is())
     404          16 :             m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     405             :     }
     406             :     else
     407           0 :         OEditBaseModel::setPropertyToDefaultByHandle(nHandle);
     408          16 : }
     409             : 
     410           0 : void OFormattedModel::setPropertyToDefault(const OUString& aPropertyName) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException, std::exception )
     411             : {
     412           0 :     OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper();
     413           0 :     sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
     414           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     415           0 :         setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     416             :     else
     417           0 :         OEditBaseModel::setPropertyToDefault(aPropertyName);
     418           0 : }
     419             : 
     420           0 : Any OFormattedModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
     421             : {
     422           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     423             :     {
     424           0 :         Reference<XNumberFormatsSupplier>  xSupplier = calcDefaultFormatsSupplier();
     425           0 :         return makeAny(xSupplier);
     426             :     }
     427             :     else
     428           0 :         return OEditBaseModel::getPropertyDefaultByHandle(nHandle);
     429             : }
     430             : 
     431           0 : Any SAL_CALL OFormattedModel::getPropertyDefault( const OUString& aPropertyName ) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException, std::exception )
     432             : {
     433           0 :     OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper();
     434           0 :     sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
     435           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     436           0 :         return getPropertyDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     437             :     else
     438           0 :         return OEditBaseModel::getPropertyDefault(aPropertyName);
     439             : }
     440             : 
     441          36 : void OFormattedModel::_propertyChanged( const com::sun::star::beans::PropertyChangeEvent& evt ) throw(RuntimeException)
     442             : {
     443             :     // TODO: check how this works with external bindings
     444             :     OSL_ENSURE( evt.Source == m_xAggregateSet, "OFormattedModel::_propertyChanged: where did this come from?" );
     445          36 :     if ( evt.Source == m_xAggregateSet )
     446             :     {
     447          36 :         Reference< XPropertySet > xSourceSet( evt.Source, UNO_QUERY );
     448          36 :         if ( evt.PropertyName == PROPERTY_FORMATKEY )
     449             :         {
     450          14 :             if ( evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG )
     451             :             {
     452             :                 try
     453             :                 {
     454          14 :                     ::osl::MutexGuard aGuard( m_aMutex );
     455          28 :                     Reference<XNumberFormatsSupplier> xSupplier( calcFormatsSupplier() );
     456          14 :                     m_nKeyType  = getNumberFormatType(xSupplier->getNumberFormats(), getINT32( evt.NewValue ) );
     457             :                     // as m_aSaveValue (which is used by commitControlValueToDbColumn) is format dependent we have
     458             :                     // to recalc it, which is done by translateDbColumnToControlValue
     459          14 :                     if ( m_xColumn.is() && m_xAggregateFastSet.is()  && !m_xCursor->isBeforeFirst() && !m_xCursor->isAfterLast())
     460             :                     {
     461           0 :                         setControlValue( translateDbColumnToControlValue(), eOther );
     462             :                     }
     463             :                     // if we're connected to an external value binding, then re-calculate the type
     464             :                     // used to exchange the value - it depends on the format, too
     465          14 :                     if ( hasExternalValueBinding() )
     466             :                     {
     467           0 :                         calculateExternalValueType();
     468          14 :                     }
     469             :                 }
     470           0 :                 catch(const Exception&)
     471             :                 {
     472             :                 }
     473             :             }
     474          14 :             return;
     475             :         }
     476          22 :         if ( evt.PropertyName == PROPERTY_FORMATSSUPPLIER )
     477             :         {
     478          14 :             updateFormatterNullDate();
     479          14 :             return;
     480             :         }
     481           8 :         OBoundControlModel::_propertyChanged( evt );
     482             :     }
     483             : }
     484             : 
     485          14 : void OFormattedModel::updateFormatterNullDate()
     486             : {
     487             :     // calc the current NULL date
     488          14 :     Reference< XNumberFormatsSupplier > xSupplier( calcFormatsSupplier() );
     489          14 :     if ( xSupplier.is() )
     490          14 :         xSupplier->getNumberFormatSettings()->getPropertyValue("NullDate") >>= m_aNullDate;
     491          14 : }
     492             : 
     493          42 : Reference< XNumberFormatsSupplier > OFormattedModel::calcFormatsSupplier() const
     494             : {
     495          42 :     Reference<XNumberFormatsSupplier>  xSupplier;
     496             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !");
     497             :     // Does my aggregate model have a FormatSupplier?
     498          42 :     if( m_xAggregateSet.is() )
     499          42 :         m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier;
     500          42 :     if (!xSupplier.is())
     501             :         // check if my parent form has a supplier
     502           0 :         xSupplier = calcFormFormatsSupplier();
     503          42 :     if (!xSupplier.is())
     504           0 :         xSupplier = calcDefaultFormatsSupplier();
     505             :     DBG_ASSERT(xSupplier.is(), "OFormattedModel::calcFormatsSupplier : no supplier !");
     506             :     // We should have one by now
     507          42 :     return xSupplier;
     508             : }
     509             : 
     510           0 : Reference<XNumberFormatsSupplier>  OFormattedModel::calcFormFormatsSupplier() const
     511             : {
     512             :     Reference<XChild> xMe(
     513             :         static_cast<XWeak*>(const_cast<OFormattedModel*>(this)),
     514           0 :         css::uno::UNO_QUERY);
     515             :     // By this we make sure that we get the right object even when aggregating
     516             :     DBG_ASSERT(xMe.is(), "OFormattedModel::calcFormFormatsSupplier : I should have a content interface !");
     517             :     // Iterate through until we reach a StartForm (starting with an own Parent)
     518           0 :     Reference<XChild>  xParent(xMe->getParent(), UNO_QUERY);
     519           0 :     Reference<XForm>  xNextParentForm(xParent, UNO_QUERY);
     520           0 :     while (!xNextParentForm.is() && xParent.is())
     521             :     {
     522           0 :         xParent.set(xParent->getParent(), css::uno::UNO_QUERY);
     523           0 :         xNextParentForm.set(xParent, css::uno::UNO_QUERY);
     524             :     }
     525           0 :     if (!xNextParentForm.is())
     526             :     {
     527             :         OSL_FAIL("OFormattedModel::calcFormFormatsSupplier : have no ancestor which is a form !");
     528           0 :         return NULL;
     529             :     }
     530             :     // The FormatSupplier of my ancestor (if it has one)
     531           0 :     Reference< XRowSet > xRowSet( xNextParentForm, UNO_QUERY );
     532           0 :     Reference< XNumberFormatsSupplier > xSupplier;
     533           0 :     if (xRowSet.is())
     534           0 :         xSupplier = getNumberFormats( getConnection(xRowSet), true, getContext() );
     535           0 :     return xSupplier;
     536             : }
     537             : 
     538          16 : Reference< XNumberFormatsSupplier > OFormattedModel::calcDefaultFormatsSupplier() const
     539             : {
     540          16 :     return StandardFormatsSupplier::get( getContext() );
     541             : }
     542             : 
     543             : // XBoundComponent
     544           0 : void OFormattedModel::loaded(const EventObject& rEvent) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     545             : {
     546             :     // HACK: our onConnectedDbColumn accesses our NumberFormatter which locks the solar mutex (as it doesn't have
     547             :     // an own one). To prevent deadlocks with other threads which may request a property from us in an
     548             :     // UI-triggered action (e.g. an tooltip) we lock the solar mutex _here_ before our base class locks
     549             :     // it's own muext (which is used for property requests)
     550             :     // alternative a): we use two mutexes, one which is passed to the OPropertysetHelper and used for
     551             :     // property requests and one for our own code. This would need a lot of code rewriting
     552             :     // alternative b): The NumberFormatter has to be really threadsafe (with an own mutex), which is
     553             :     // the only "clean" solution for me.
     554           0 :     SolarMutexGuard aGuard;
     555           0 :     OEditBaseModel::loaded(rEvent);
     556           0 : }
     557             : 
     558          14 : void OFormattedModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
     559             : {
     560          14 :     m_xOriginalFormatter = NULL;
     561             :     // get some properties of the field
     562          14 :     m_nFieldType = DataType::OTHER;
     563          14 :     Reference<XPropertySet> xField = getField();
     564          14 :     if ( xField.is() )
     565          14 :         xField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= m_nFieldType;
     566          14 :     sal_Int32 nFormatKey = 0;
     567             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::onConnectedDbColumn : have no aggregate !");
     568          14 :     if (m_xAggregateSet.is())
     569             :     {   // all the following doesn't make any sense if we have no aggregate ...
     570          14 :         Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
     571             :         DBG_ASSERT( aSupplier.hasValue(), "OFormattedModel::onConnectedDbColumn : invalid property value !" );
     572             :         // This should've been set to the correct value in the ctor or in the read
     573          28 :         Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     574          14 :         if ( !(aFmtKey >>= nFormatKey ) )
     575             :         {   // nobody gave us a format to use. So we examine the field we're bound to for a
     576             :             // format key, and use it ourself, too
     577           0 :             sal_Int32 nType = DataType::VARCHAR;
     578           0 :             if (xField.is())
     579             :             {
     580           0 :                 aFmtKey = xField->getPropertyValue(PROPERTY_FORMATKEY);
     581           0 :                 xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType ;
     582             :             }
     583           0 :             Reference<XNumberFormatsSupplier>  xSupplier = calcFormFormatsSupplier();
     584             :             DBG_ASSERT(xSupplier.is(), "OFormattedModel::onConnectedDbColumn : bound to a field but no parent with a formatter ? how this ?");
     585           0 :             if (xSupplier.is())
     586             :             {
     587           0 :                 m_bOriginalNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC));
     588           0 :                 if (!aFmtKey.hasValue())
     589             :                 {   // we aren't bound to a field (or this field's format is invalid)
     590             :                     // -> determine the standard text (or numeric) format of the supplier
     591           0 :                     Reference<XNumberFormatTypes>  xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
     592           0 :                     if (xTypes.is())
     593             :                     {
     594           0 :                         Locale aApplicationLocale = Application::GetSettings().GetUILanguageTag().getLocale();
     595           0 :                         if (m_bOriginalNumeric)
     596           0 :                             aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::NUMBER, aApplicationLocale);
     597             :                         else
     598           0 :                             aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::TEXT, aApplicationLocale);
     599           0 :                     }
     600             :                 }
     601           0 :                 aSupplier >>= m_xOriginalFormatter;
     602           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     603           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, aFmtKey);
     604             :                 // Adapt the NumericFalg to my bound field
     605           0 :                 if (xField.is())
     606             :                 {
     607           0 :                     m_bNumeric = false;
     608           0 :                     switch (nType)
     609             :                     {
     610             :                         case DataType::BIT:
     611             :                         case DataType::BOOLEAN:
     612             :                         case DataType::TINYINT:
     613             :                         case DataType::SMALLINT:
     614             :                         case DataType::INTEGER:
     615             :                         case DataType::BIGINT:
     616             :                         case DataType::FLOAT:
     617             :                         case DataType::REAL:
     618             :                         case DataType::DOUBLE:
     619             :                         case DataType::NUMERIC:
     620             :                         case DataType::DECIMAL:
     621             :                         case DataType::DATE:
     622             :                         case DataType::TIME:
     623             :                         case DataType::TIMESTAMP:
     624           0 :                             m_bNumeric = true;
     625           0 :                             break;
     626             :                     }
     627             :                 }
     628             :                 else
     629           0 :                     m_bNumeric = m_bOriginalNumeric;
     630           0 :                 setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny(m_bNumeric));
     631           0 :                 OSL_VERIFY( aFmtKey >>= nFormatKey );
     632           0 :             }
     633          14 :         }
     634             :     }
     635          14 :     Reference<XNumberFormatsSupplier>  xSupplier = calcFormatsSupplier();
     636          14 :     m_bNumeric = getBOOL( getPropertyValue( PROPERTY_TREATASNUMERIC ) );
     637          14 :     m_nKeyType  = getNumberFormatType( xSupplier->getNumberFormats(), nFormatKey );
     638          14 :     xSupplier->getNumberFormatSettings()->getPropertyValue("NullDate") >>= m_aNullDate;
     639          14 :     OEditBaseModel::onConnectedDbColumn( _rxForm );
     640          14 : }
     641             : 
     642          14 : void OFormattedModel::onDisconnectedDbColumn()
     643             : {
     644          14 :     OEditBaseModel::onDisconnectedDbColumn();
     645          14 :     if (m_xOriginalFormatter.is())
     646             :     {   // Our aggregated model does not hold any Format information
     647           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(m_xOriginalFormatter));
     648           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, Any());
     649           0 :         setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny(m_bOriginalNumeric));
     650           0 :         m_xOriginalFormatter = NULL;
     651             :     }
     652          14 :     m_nFieldType = DataType::OTHER;
     653          14 :     m_nKeyType   = NumberFormat::UNDEFINED;
     654          14 :     m_aNullDate  = DBTypeConversion::getStandardDate();
     655          14 : }
     656             : 
     657           0 : void OFormattedModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
     658             : {
     659           0 :     OEditBaseModel::write(_rxOutStream);
     660           0 :     _rxOutStream->writeShort(0x0003);
     661             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::write : have no aggregate !");
     662             :     // Bring my Format (may be void) to a persistent Format.
     663             :     // The Supplier together with the Key is already persistent, but that doesn't mean
     664             :     // we have to save the Supplier (which would be quite some overhead)
     665           0 :         Reference<XNumberFormatsSupplier>  xSupplier;
     666           0 :         Any aFmtKey;
     667           0 :     bool bVoidKey = true;
     668           0 :     if (m_xAggregateSet.is())
     669             :     {
     670           0 :         Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
     671           0 :         if (aSupplier.getValueType().getTypeClass() != TypeClass_VOID)
     672             :         {
     673           0 :             OSL_VERIFY( aSupplier >>= xSupplier );
     674             :         }
     675           0 :         aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     676           0 :         bVoidKey = (!xSupplier.is() || !aFmtKey.hasValue()) || (isLoaded() && m_xOriginalFormatter.is());
     677             :         // (no Format and/or Key) OR (loaded and faked Formatter)
     678             :     }
     679           0 :     _rxOutStream->writeBoolean(!bVoidKey);
     680           0 :     if (!bVoidKey)
     681             :     {
     682             :         // Create persistent values from the FormatKey and the Formatter
     683           0 :         Any aKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     684           0 :         sal_Int32 nKey = aKey.hasValue() ? getINT32(aKey) : 0;
     685           0 :         Reference<XNumberFormats>  xFormats = xSupplier->getNumberFormats();
     686           0 :         OUString         sFormatDescription;
     687           0 :         LanguageType    eFormatLanguage = LANGUAGE_DONTKNOW;
     688             :         static const char s_aLocaleProp[] = "Locale";
     689           0 :         Reference<com::sun::star::beans::XPropertySet>  xFormat = xFormats->getByKey(nKey);
     690           0 :         if (hasProperty(s_aLocaleProp, xFormat))
     691             :         {
     692           0 :             Any aLocale = xFormat->getPropertyValue(s_aLocaleProp);
     693             :             DBG_ASSERT(isA(aLocale, static_cast<Locale*>(NULL)), "OFormattedModel::write : invalid language property !");
     694           0 :             if (isA(aLocale, static_cast<Locale*>(NULL)))
     695             :             {
     696           0 :                 Locale const * pLocale = static_cast<Locale const *>(aLocale.getValue());
     697           0 :                 eFormatLanguage = LanguageTag::convertToLanguageType( *pLocale, false);
     698           0 :             }
     699             :         }
     700             :         static const char s_aFormatStringProp[] = "FormatString";
     701           0 :         if (hasProperty(s_aFormatStringProp, xFormat))
     702           0 :             xFormat->getPropertyValue(s_aFormatStringProp) >>= sFormatDescription;
     703           0 :         _rxOutStream->writeUTF(sFormatDescription);
     704           0 :         _rxOutStream->writeLong((sal_Int32)eFormatLanguage);
     705             :     }
     706             :     // version 2 : write the properties common to all OEditBaseModels
     707           0 :     writeCommonEditProperties(_rxOutStream);
     708             :     // version 3 : write the effective value property of the aggregate
     709             :     // Due to a bug within the UnoControlFormattedFieldModel implementation (our default aggregate)
     710             :     // this props value isn't correctly read and this can't be corrected without being incompatible.
     711             :     // so we have our own handling.
     712             :     // and to be a little bit more compatible we make the following section skippable
     713             :     {
     714           0 :         OStreamSection aDownCompat(_rxOutStream);
     715             :         // a sub version within the skippable block
     716           0 :         _rxOutStream->writeShort(0x0000);
     717             :         // version 0: the effective value of the aggregate
     718           0 :         Any aEffectiveValue;
     719           0 :         if (m_xAggregateSet.is())
     720             :         {
     721           0 :             try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(const Exception&) { }
     722             :         }
     723             :         {
     724           0 :             OStreamSection aDownCompat2(_rxOutStream);
     725           0 :             switch (aEffectiveValue.getValueType().getTypeClass())
     726             :             {
     727             :                 case TypeClass_STRING:
     728           0 :                     _rxOutStream->writeShort(0x0000);
     729           0 :                     _rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue));
     730           0 :                     break;
     731             :                 case TypeClass_DOUBLE:
     732           0 :                     _rxOutStream->writeShort(0x0001);
     733           0 :                     _rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue));
     734           0 :                     break;
     735             :                 default:    // void and all unknown states
     736             :                     DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !");
     737           0 :                     _rxOutStream->writeShort(0x0002);
     738           0 :                     break;
     739           0 :             }
     740           0 :         }
     741           0 :     }
     742           0 : }
     743             : 
     744           0 : void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
     745             : {
     746           0 :     OEditBaseModel::read(_rxInStream);
     747           0 :     sal_uInt16 nVersion = _rxInStream->readShort();
     748           0 :     Reference<XNumberFormatsSupplier>  xSupplier;
     749           0 :     sal_Int32 nKey = -1;
     750           0 :     switch (nVersion)
     751             :     {
     752             :         case 0x0001 :
     753             :         case 0x0002 :
     754             :         case 0x0003 :
     755             :         {
     756           0 :             bool bNonVoidKey = _rxInStream->readBoolean();
     757           0 :             if (bNonVoidKey)
     758             :             {
     759             :                 // read string and language...
     760           0 :                 OUString sFormatDescription = _rxInStream->readUTF();
     761           0 :                 LanguageType eDescriptionLanguage = (LanguageType)_rxInStream->readLong();
     762             :                 // and let a formatter roll dice based on that to create a key...
     763           0 :                 xSupplier = calcFormatsSupplier();
     764             :                 // calcFormatsSupplier first takes the one from the model, then one from the starform, then a new one...
     765           0 :                 Reference<XNumberFormats>  xFormats = xSupplier->getNumberFormats();
     766           0 :                 if (xFormats.is())
     767             :                 {
     768           0 :                     Locale aDescriptionLanguage( LanguageTag::convertToLocale(eDescriptionLanguage));
     769           0 :                     nKey = xFormats->queryKey(sFormatDescription, aDescriptionLanguage, sal_False);
     770           0 :                     if (nKey == (sal_Int32)-1)
     771             :                     {   // does not yet exist in my formatter...
     772           0 :                         nKey = xFormats->addNew(sFormatDescription, aDescriptionLanguage);
     773           0 :                     }
     774           0 :                 }
     775             :             }
     776           0 :             if ((nVersion == 0x0002) || (nVersion == 0x0003))
     777           0 :                 readCommonEditProperties(_rxInStream);
     778           0 :             if (nVersion == 0x0003)
     779             :             {   // since version 3 there is a "skippable" block at this position
     780           0 :                 OStreamSection aDownCompat(_rxInStream);
     781           0 :                 sal_Int16 nSubVersion = _rxInStream->readShort();
     782             :                 (void)nSubVersion;
     783             :                 // version 0 and higher : the "effective value" property
     784           0 :                 Any aEffectiveValue;
     785             :                 {
     786           0 :                     OStreamSection aDownCompat2(_rxInStream);
     787           0 :                     switch (_rxInStream->readShort())
     788             :                     {
     789             :                         case 0: // String
     790           0 :                             aEffectiveValue <<= _rxInStream->readUTF();
     791           0 :                             break;
     792             :                         case 1: // double
     793           0 :                             aEffectiveValue <<= (double)_rxInStream->readDouble();
     794           0 :                             break;
     795             :                         case 2:
     796           0 :                             break;
     797             :                         case 3:
     798             :                             OSL_FAIL("FmXFormattedModel::read : unknown effective value type !");
     799           0 :                     }
     800             :                 }
     801             :                 // this property is only to be set if we have no control source : in all other cases the base class did a
     802             :                 // reset after it's read and this set the effective value to a default value
     803           0 :                 if ( m_xAggregateSet.is() && getControlSource().isEmpty() )
     804             :                 {
     805             :                     try
     806             :                     {
     807           0 :                         m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue);
     808             :                     }
     809           0 :                     catch(const Exception&)
     810             :                     {
     811             :                     }
     812           0 :                 }
     813             :             }
     814             :         }
     815           0 :         break;
     816             :         default :
     817             :             OSL_FAIL("OFormattedModel::read : unknown version !");
     818             :             // then the format of the aggregated set stay like it was during creation: void
     819           0 :             defaultCommonEditProperties();
     820           0 :             break;
     821             :     }
     822           0 :     if ((nKey != -1) && m_xAggregateSet.is())
     823             :     {
     824           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     825           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey));
     826             :     }
     827             :     else
     828             :     {
     829           0 :         setPropertyToDefault(PROPERTY_FORMATSSUPPLIER);
     830           0 :         setPropertyToDefault(PROPERTY_FORMATKEY);
     831           0 :     }
     832           0 : }
     833             : 
     834           0 : sal_uInt16 OFormattedModel::getPersistenceFlags() const
     835             : {
     836           0 :     return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS);
     837             :     // a) we do our own call to writeCommonEditProperties
     838             : }
     839             : 
     840           0 : bool OFormattedModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
     841             : {
     842           0 :     Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
     843           0 :     if ( aControlValue != m_aSaveValue )
     844             :     {
     845             :         // empty string + EmptyIsNull = void
     846           0 :         if  (   !aControlValue.hasValue()
     847           0 :             ||  (   ( aControlValue.getValueType().getTypeClass() == TypeClass_STRING )
     848           0 :                 &&  getString( aControlValue ).isEmpty()
     849           0 :                 &&  m_bEmptyIsNull
     850             :                 )
     851             :             )
     852           0 :             m_xColumnUpdate->updateNull();
     853             :         else
     854             :         {
     855             :             try
     856             :             {
     857           0 :                 double f = 0.0;
     858           0 :                 if ( aControlValue.getValueType().getTypeClass() == TypeClass_DOUBLE || (aControlValue >>= f)) // #i110323
     859             :                 {
     860           0 :                     DBTypeConversion::setValue( m_xColumnUpdate, m_aNullDate, getDouble( aControlValue ), m_nKeyType );
     861             :                 }
     862             :                 else
     863             :                 {
     864             :                     DBG_ASSERT( aControlValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::commitControlValueToDbColumn: invalud value type !" );
     865           0 :                     m_xColumnUpdate->updateString( getString( aControlValue ) );
     866             :                 }
     867             :             }
     868           0 :             catch(const Exception&)
     869             :             {
     870           0 :                 return false;
     871             :             }
     872             :         }
     873           0 :         m_aSaveValue = aControlValue;
     874             :     }
     875           0 :     return true;
     876             : }
     877             : 
     878           0 : void OFormattedModel::onConnectedExternalValue( )
     879             : {
     880           0 :     OEditBaseModel::onConnectedExternalValue();
     881           0 :     updateFormatterNullDate();
     882           0 : }
     883             : 
     884           0 : Any OFormattedModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
     885             : {
     886           0 :     Any aControlValue;
     887           0 :     switch( _rExternalValue.getValueTypeClass() )
     888             :     {
     889             :     case TypeClass_VOID:
     890           0 :         break;
     891             :     case TypeClass_STRING:
     892           0 :         aControlValue = _rExternalValue;
     893           0 :         break;
     894             :     case TypeClass_BOOLEAN:
     895             :     {
     896           0 :         bool bExternalValue = false;
     897           0 :         _rExternalValue >>= bExternalValue;
     898           0 :         aControlValue <<= (double)( bExternalValue ? 1 : 0 );
     899             :     }
     900           0 :     break;
     901             :     default:
     902             :     {
     903           0 :         if ( _rExternalValue.getValueType().equals( cppu::UnoType< UNODate >::get() ) )
     904             :         {
     905           0 :             UNODate aDate;
     906           0 :             _rExternalValue >>= aDate;
     907           0 :             aControlValue <<= DBTypeConversion::toDouble( aDate, m_aNullDate );
     908             :         }
     909           0 :         else if ( _rExternalValue.getValueType().equals( cppu::UnoType< UNOTime >::get() ) )
     910             :         {
     911           0 :             UNOTime aTime;
     912           0 :             _rExternalValue >>= aTime;
     913           0 :             aControlValue <<= DBTypeConversion::toDouble( aTime );
     914             :         }
     915           0 :         else if ( _rExternalValue.getValueType().equals( cppu::UnoType< UNODateTime >::get() ) )
     916             :         {
     917           0 :             UNODateTime aDateTime;
     918           0 :             _rExternalValue >>= aDateTime;
     919           0 :             aControlValue <<= DBTypeConversion::toDouble( aDateTime, m_aNullDate );
     920             :         }
     921             :         else
     922             :         {
     923             :             OSL_ENSURE( _rExternalValue.getValueTypeClass() == TypeClass_DOUBLE,
     924             :                 "OFormattedModel::translateExternalValueToControlValue: don't know how to translate this type!" );
     925           0 :             double fValue = 0;
     926           0 :             OSL_VERIFY( _rExternalValue >>= fValue );
     927           0 :             aControlValue <<= fValue;
     928             :         }
     929             :     }
     930             :     }
     931           0 :     return aControlValue;
     932             : }
     933             : 
     934           0 : Any OFormattedModel::translateControlValueToExternalValue( ) const
     935             : {
     936             :     OSL_PRECOND( hasExternalValueBinding(),
     937             :         "OFormattedModel::translateControlValueToExternalValue: precondition not met!" );
     938           0 :     Any aControlValue( getControlValue() );
     939           0 :     if ( !aControlValue.hasValue() )
     940           0 :         return aControlValue;
     941           0 :     Any aExternalValue;
     942             :     // translate into the external value type
     943           0 :     Type aExternalValueType( getExternalValueType() );
     944           0 :     switch ( aExternalValueType.getTypeClass() )
     945             :     {
     946             :     case TypeClass_STRING:
     947             :     {
     948           0 :         OUString sString;
     949           0 :         if ( aControlValue >>= sString )
     950             :         {
     951           0 :             aExternalValue <<= sString;
     952           0 :             break;
     953           0 :         }
     954             :     }
     955             :     // NO break here!
     956             :     case TypeClass_BOOLEAN:
     957             :     {
     958           0 :         double fValue = 0;
     959           0 :         OSL_VERIFY( aControlValue >>= fValue );
     960             :         // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
     961             :         // and the control value is a string. This implies some weird misconfiguration
     962             :         // of the FormattedModel, so we won't care for it for the moment.
     963           0 :         aExternalValue <<= fValue != 0.0;
     964             :     }
     965           0 :     break;
     966             :     default:
     967             :     {
     968           0 :         double fValue = 0;
     969           0 :         OSL_VERIFY( aControlValue >>= fValue );
     970             :         // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
     971             :         // and the control value is a string. This implies some weird misconfiguration
     972             :         // of the FormattedModel, so we won't care for it for the moment.
     973           0 :         if ( aExternalValueType.equals( cppu::UnoType< UNODate >::get() ) )
     974             :         {
     975           0 :             aExternalValue <<= DBTypeConversion::toDate( fValue, m_aNullDate );
     976             :         }
     977           0 :         else if ( aExternalValueType.equals( cppu::UnoType< UNOTime >::get() ) )
     978             :         {
     979           0 :             aExternalValue <<= DBTypeConversion::toTime( fValue );
     980             :         }
     981           0 :         else if ( aExternalValueType.equals( cppu::UnoType< UNODateTime >::get() ) )
     982             :         {
     983           0 :             aExternalValue <<= DBTypeConversion::toDateTime( fValue, m_aNullDate );
     984             :         }
     985             :         else
     986             :         {
     987             :             OSL_ENSURE( aExternalValueType.equals( cppu::UnoType< double >::get() ),
     988             :                 "OFormattedModel::translateControlValueToExternalValue: don't know how to translate this type!" );
     989           0 :             aExternalValue <<= fValue;
     990             :         }
     991             :     }
     992           0 :     break;
     993             :     }
     994           0 :     return aExternalValue;
     995             : }
     996             : 
     997          14 : Any OFormattedModel::translateDbColumnToControlValue()
     998             : {
     999          14 :     if ( m_bNumeric )
    1000           0 :         m_aSaveValue <<= DBTypeConversion::getValue( m_xColumn, m_aNullDate ); // #100056# OJ
    1001             :     else
    1002          14 :         m_aSaveValue <<= m_xColumn->getString();
    1003          14 :     if ( m_xColumn->wasNull() )
    1004           9 :         m_aSaveValue.clear();
    1005          14 :     return m_aSaveValue;
    1006             : }
    1007             : 
    1008           0 : Sequence< Type > OFormattedModel::getSupportedBindingTypes()
    1009             : {
    1010           0 :     ::std::list< Type > aTypes;
    1011           0 :     aTypes.push_back( cppu::UnoType< double >::get() );
    1012           0 :     switch ( m_nKeyType & ~NumberFormat::DEFINED )
    1013             :     {
    1014             :     case NumberFormat::DATE:
    1015           0 :         aTypes.push_front(cppu::UnoType< UNODate >::get() );
    1016           0 :         break;
    1017             :     case NumberFormat::TIME:
    1018           0 :         aTypes.push_front(cppu::UnoType< UNOTime >::get() );
    1019           0 :         break;
    1020             :     case NumberFormat::DATETIME:
    1021           0 :         aTypes.push_front(cppu::UnoType< UNODateTime >::get() );
    1022           0 :         break;
    1023             :     case NumberFormat::TEXT:
    1024           0 :         aTypes.push_front(cppu::UnoType< OUString >::get() );
    1025           0 :         break;
    1026             :     case NumberFormat::LOGICAL:
    1027           0 :         aTypes.push_front(cppu::UnoType< sal_Bool >::get() );
    1028           0 :         break;
    1029             :     }
    1030           0 :     Sequence< Type > aTypesRet( aTypes.size() );
    1031           0 :     ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() );
    1032           0 :     return aTypesRet;
    1033             : }
    1034             : 
    1035           0 : Any OFormattedModel::getDefaultForReset() const
    1036             : {
    1037           0 :     return m_xAggregateSet->getPropertyValue( PROPERTY_EFFECTIVE_DEFAULT );
    1038             : }
    1039             : 
    1040           0 : void OFormattedModel::resetNoBroadcast()
    1041             : {
    1042           0 :     OEditBaseModel::resetNoBroadcast();
    1043           0 :     m_aSaveValue.clear();
    1044           0 : }
    1045             : 
    1046             : }
    1047             : 
    1048             : extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL
    1049           2 : com_sun_star_form_OFormattedControl_get_implementation(::com::sun::star::uno::XComponentContext* component,
    1050             :         ::com::sun::star::uno::Sequence<css::uno::Any> const &)
    1051             : {
    1052           2 :     return cppu::acquire(new frm::OFormattedControl(component));
    1053         138 : }
    1054             : 
    1055             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11