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

Generated by: LCOV version 1.10