LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/forms/source/component - FormattedField.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 187 522 35.8 %
Date: 2013-07-09 Functions: 35 60 58.3 %
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             : 
      20             : 
      21             : #include "FormattedField.hxx"
      22             : #include "services.hxx"
      23             : #include "property.hrc"
      24             : #include "property.hxx"
      25             : #include "frm_resource.hxx"
      26             : #include "frm_resource.hrc"
      27             : #include "propertybaghelper.hxx"
      28             : #include <comphelper/sequence.hxx>
      29             : #include <comphelper/numbers.hxx>
      30             : #include <connectivity/dbtools.hxx>
      31             : #include <connectivity/dbconversion.hxx>
      32             : #include <svl/zforlist.hxx>
      33             : #include <svl/numuno.hxx>
      34             : #include <vcl/svapp.hxx>
      35             : #include <tools/debug.hxx>
      36             : #include <tools/wintypes.hxx>
      37             : #include <i18nlangtag/languagetag.hxx>
      38             : #include <rtl/textenc.h>
      39             : #include <com/sun/star/sdbc/DataType.hpp>
      40             : #include <com/sun/star/util/NumberFormat.hpp>
      41             : #include <com/sun/star/util/Date.hpp>
      42             : #include <com/sun/star/util/Time.hpp>
      43             : #include <com/sun/star/awt/MouseEvent.hpp>
      44             : #include <com/sun/star/form/XSubmit.hpp>
      45             : #include <com/sun/star/awt/XWindow.hpp>
      46             : #include <com/sun/star/awt/XKeyListener.hpp>
      47             : #include <com/sun/star/form/FormComponentType.hpp>
      48             : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
      49             : #include <com/sun/star/util/XNumberFormatTypes.hpp>
      50             : #include <com/sun/star/form/XForm.hpp>
      51             : #include <com/sun/star/container/XIndexAccess.hpp>
      52             : #include <osl/mutex.hxx>
      53             :     // needed as long as we use the SolarMutex
      54             : #include <comphelper/streamsection.hxx>
      55             : #include <cppuhelper/weakref.hxx>
      56             : #include <unotools/desktopterminationobserver.hxx>
      57             : 
      58             : #include <list>
      59             : #include <algorithm>
      60             : 
      61             : using namespace dbtools;
      62             : using namespace ::com::sun::star::uno;
      63             : using namespace ::com::sun::star::sdb;
      64             : using namespace ::com::sun::star::sdbc;
      65             : using namespace ::com::sun::star::sdbcx;
      66             : using namespace ::com::sun::star::beans;
      67             : using namespace ::com::sun::star::container;
      68             : using namespace ::com::sun::star::form;
      69             : using namespace ::com::sun::star::awt;
      70             : using namespace ::com::sun::star::io;
      71             : using namespace ::com::sun::star::lang;
      72             : using namespace ::com::sun::star::util;
      73             : using namespace ::com::sun::star::form::binding;
      74             : 
      75             : namespace
      76             : {
      77             :     typedef com::sun::star::util::Date UNODate;
      78             :     typedef com::sun::star::util::Time UNOTime;
      79             :     typedef com::sun::star::util::DateTime UNODateTime;
      80             : }
      81             : 
      82             : //.........................................................................
      83             : namespace frm
      84             : {
      85             : 
      86             : /*************************************************************************/
      87             : 
      88             : class StandardFormatsSupplier : protected SvNumberFormatsSupplierObj, public ::utl::ITerminationListener
      89             : {
      90             : protected:
      91             :             SvNumberFormatter*                       m_pMyPrivateFormatter;
      92             :     static  WeakReference< XNumberFormatsSupplier >  s_xDefaultFormatsSupplier;
      93             : 
      94             : public:
      95             :     static Reference< XNumberFormatsSupplier > get( const Reference< XComponentContext >& _rxORB );
      96             : 
      97             :     using SvNumberFormatsSupplierObj::operator new;
      98             :     using SvNumberFormatsSupplierObj::operator delete;
      99             : 
     100             : protected:
     101             :     StandardFormatsSupplier(const Reference< XComponentContext >& _rxFactory,LanguageType _eSysLanguage);
     102             :     ~StandardFormatsSupplier();
     103             : 
     104             : protected:
     105             :     virtual bool    queryTermination() const;
     106             :     virtual void    notifyTermination();
     107             : };
     108             : 
     109             : //------------------------------------------------------------------
     110          24 : WeakReference< XNumberFormatsSupplier > StandardFormatsSupplier::s_xDefaultFormatsSupplier;
     111             : 
     112             : //------------------------------------------------------------------
     113          15 : StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XComponentContext > & _rxContext,LanguageType _eSysLanguage)
     114             :     :SvNumberFormatsSupplierObj()
     115          15 :     ,m_pMyPrivateFormatter(new SvNumberFormatter(_rxContext, _eSysLanguage))
     116             : {
     117          15 :     SetNumberFormatter(m_pMyPrivateFormatter);
     118             : 
     119             :     // #i29147#
     120          15 :     ::utl::DesktopTerminationObserver::registerTerminationListener( this );
     121          15 : }
     122             : 
     123             : //------------------------------------------------------------------
     124          45 : StandardFormatsSupplier::~StandardFormatsSupplier()
     125             : {
     126          15 :     ::utl::DesktopTerminationObserver::revokeTerminationListener( this );
     127             : 
     128          15 :     DELETEZ( m_pMyPrivateFormatter );
     129          30 : }
     130             : 
     131             : //------------------------------------------------------------------
     132          15 : Reference< XNumberFormatsSupplier > StandardFormatsSupplier::get( const Reference< XComponentContext >& _rxORB )
     133             : {
     134          15 :     LanguageType eSysLanguage = LANGUAGE_SYSTEM;
     135             :     {
     136          15 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     137          30 :         Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
     138          15 :         if ( xSupplier.is() )
     139           0 :             return xSupplier;
     140             : 
     141             :         // get the Office's locale
     142          30 :         eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
     143             :     }
     144             : 
     145          15 :     StandardFormatsSupplier* pSupplier = new StandardFormatsSupplier( _rxORB, eSysLanguage );
     146          15 :     Reference< XNumberFormatsSupplier > xNewlyCreatedSupplier( pSupplier );
     147             : 
     148             :     {
     149          15 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     150          30 :         Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
     151          15 :         if ( xSupplier.is() )
     152             :             // somebody used the small time frame where the mutex was not locked to create and set
     153             :             // the supplier
     154           0 :             return xSupplier;
     155             : 
     156          30 :         s_xDefaultFormatsSupplier = xNewlyCreatedSupplier;
     157             :     }
     158             : 
     159          15 :     return xNewlyCreatedSupplier;
     160             : }
     161             : 
     162             : //------------------------------------------------------------------
     163           1 : bool StandardFormatsSupplier::queryTermination() const
     164             : {
     165           1 :     return true;
     166             : }
     167             : 
     168             : //------------------------------------------------------------------
     169           1 : void StandardFormatsSupplier::notifyTermination()
     170             : {
     171           1 :     Reference< XNumberFormatsSupplier > xKeepAlive = this;
     172             :     // when the application is terminating, release our static reference so that we are cleared/destructed
     173             :     // earlier than upon unloading the library
     174             :     // #i29147#
     175           1 :     s_xDefaultFormatsSupplier = WeakReference< XNumberFormatsSupplier >( );
     176             : 
     177           1 :     SetNumberFormatter( NULL );
     178           1 :     DELETEZ( m_pMyPrivateFormatter );
     179           1 : }
     180             : 
     181             : /*************************************************************************/
     182             : //------------------------------------------------------------------
     183           1 : InterfaceRef SAL_CALL OFormattedControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
     184             : {
     185           1 :     return *(new OFormattedControl( comphelper::getComponentContext(_rxFactory) ));
     186             : }
     187             : 
     188             : //------------------------------------------------------------------
     189           0 : Sequence<Type> OFormattedControl::_getTypes()
     190             : {
     191             :     return ::comphelper::concatSequences(
     192             :         OFormattedControl_BASE::getTypes(),
     193             :         OBoundControl::_getTypes()
     194           0 :     );
     195             : }
     196             : 
     197             : //------------------------------------------------------------------
     198          94 : Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException)
     199             : {
     200          94 :     Any aReturn = OBoundControl::queryAggregation(_rType);
     201          94 :     if (!aReturn.hasValue())
     202           2 :         aReturn = OFormattedControl_BASE::queryInterface(_rType);
     203          94 :     return aReturn;
     204             : }
     205             : 
     206             : 
     207             : DBG_NAME(OFormattedControl);
     208             : //------------------------------------------------------------------------------
     209           1 : OFormattedControl::OFormattedControl(const Reference<XComponentContext>& _rxFactory)
     210             :                :OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD)
     211           1 :                ,m_nKeyEvent(0)
     212             : {
     213             :     DBG_CTOR(OFormattedControl,NULL);
     214             : 
     215           1 :     increment(m_refCount);
     216             :     {
     217           1 :         Reference<XWindow>  xComp;
     218           1 :         if (query_aggregation(m_xAggregate, xComp))
     219             :         {
     220           1 :             xComp->addKeyListener(this);
     221           1 :         }
     222             :     }
     223           1 :     decrement(m_refCount);
     224           1 : }
     225             : 
     226             : //------------------------------------------------------------------------------
     227           3 : OFormattedControl::~OFormattedControl()
     228             : {
     229           1 :     if( m_nKeyEvent )
     230           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     231             : 
     232           1 :     if (!OComponentHelper::rBHelper.bDisposed)
     233             :     {
     234           0 :         acquire();
     235           0 :         dispose();
     236             :     }
     237             : 
     238             :     DBG_DTOR(OFormattedControl,NULL);
     239           2 : }
     240             : 
     241             : // XKeyListener
     242             : //------------------------------------------------------------------------------
     243           3 : void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException)
     244             : {
     245           3 :     OBoundControl::disposing(_rSource);
     246           3 : }
     247             : 
     248             : //------------------------------------------------------------------------------
     249           0 : void OFormattedControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
     250             : {
     251           0 :     if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
     252           0 :         return;
     253             : 
     254             :     // Steht das Control in einem Formular mit einer Submit-URL?
     255           0 :     Reference<com::sun::star::beans::XPropertySet>  xSet(getModel(), UNO_QUERY);
     256           0 :     if( !xSet.is() )
     257           0 :         return;
     258             : 
     259           0 :     Reference<XFormComponent>  xFComp(xSet, UNO_QUERY);
     260           0 :     InterfaceRef  xParent = xFComp->getParent();
     261           0 :     if( !xParent.is() )
     262           0 :         return;
     263             : 
     264           0 :     Reference<com::sun::star::beans::XPropertySet>  xFormSet(xParent, UNO_QUERY);
     265           0 :     if( !xFormSet.is() )
     266           0 :         return;
     267             : 
     268           0 :     Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL ));
     269           0 :     if (!isA(aTmp, static_cast< OUString* >(NULL)) ||
     270           0 :         getString(aTmp).isEmpty() )
     271           0 :         return;
     272             : 
     273           0 :     Reference<XIndexAccess>  xElements(xParent, UNO_QUERY);
     274           0 :     sal_Int32 nCount = xElements->getCount();
     275           0 :     if( nCount > 1 )
     276             :     {
     277             : 
     278           0 :         Reference<com::sun::star::beans::XPropertySet>  xFCSet;
     279           0 :         for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
     280             :         {
     281             :             //  Any aElement(xElements->getByIndex(nIndex));
     282           0 :             xElements->getByIndex(nIndex) >>= xFCSet;
     283             : 
     284           0 :             if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
     285           0 :                 getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
     286             :             {
     287             :                 // Noch ein weiteres Edit gefunden ==> dann nicht submitten
     288           0 :                 if (xFCSet != xSet)
     289           0 :                     return;
     290             :             }
     291           0 :         }
     292             :     }
     293             : 
     294             :     // Da wir noch im Haender stehen, submit asynchron ausloesen
     295           0 :     if( m_nKeyEvent )
     296           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     297             :     m_nKeyEvent = Application::PostUserEvent( LINK(this, OFormattedControl,
     298           0 :                                             OnKeyPressed) );
     299             : }
     300             : 
     301             : //------------------------------------------------------------------------------
     302           0 : void OFormattedControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException)
     303             : {
     304           0 : }
     305             : 
     306             : //------------------------------------------------------------------------------
     307           0 : IMPL_LINK(OFormattedControl, OnKeyPressed, void*, /*EMPTYARG*/)
     308             : {
     309           0 :     m_nKeyEvent = 0;
     310             : 
     311           0 :     Reference<XFormComponent>  xFComp(getModel(), UNO_QUERY);
     312           0 :     InterfaceRef  xParent = xFComp->getParent();
     313           0 :     Reference<XSubmit>  xSubmit(xParent, UNO_QUERY);
     314           0 :     if (xSubmit.is())
     315           0 :         xSubmit->submit( Reference<XControl> (), ::com::sun::star::awt::MouseEvent() );
     316           0 :     return 0L;
     317             : }
     318             : 
     319             : //------------------------------------------------------------------------------
     320           0 : StringSequence  OFormattedControl::getSupportedServiceNames() throw()
     321             : {
     322           0 :     StringSequence aSupported = OBoundControl::getSupportedServiceNames();
     323           0 :     aSupported.realloc(aSupported.getLength() + 1);
     324             : 
     325           0 :     OUString*pArray = aSupported.getArray();
     326           0 :     pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_FORMATTEDFIELD;
     327           0 :     return aSupported;
     328             : }
     329             : 
     330             : //------------------------------------------------------------------------------
     331           3 : void OFormattedControl::setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException)
     332             : {
     333           3 :     OBoundControl::setDesignMode(bOn);
     334           3 : }
     335             : 
     336             : /*************************************************************************/
     337             : DBG_NAME(OFormattedModel)
     338             : //------------------------------------------------------------------
     339          15 : void OFormattedModel::implConstruct()
     340             : {
     341             :     // members
     342          15 :     m_bOriginalNumeric = sal_False;
     343          15 :     m_bNumeric = sal_False;
     344          15 :     m_xOriginalFormatter = NULL;
     345          15 :     m_nKeyType = NumberFormat::UNDEFINED;
     346          15 :     m_aNullDate = DBTypeConversion::getStandardDate();
     347          15 :     m_nFieldType =  DataType::OTHER;
     348             : 
     349             :     // default our formats supplier
     350          15 :     increment(m_refCount);
     351          15 :     setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     352          15 :     decrement(m_refCount);
     353             : 
     354          15 :     startAggregatePropertyListening( PROPERTY_FORMATKEY );
     355          15 :     startAggregatePropertyListening( PROPERTY_FORMATSSUPPLIER );
     356          15 : }
     357             : 
     358             : //------------------------------------------------------------------
     359          15 : OFormattedModel::OFormattedModel(const Reference<XComponentContext>& _rxFactory)
     360             :     :OEditBaseModel(_rxFactory, VCL_CONTROLMODEL_FORMATTEDFIELD, FRM_SUN_CONTROL_FORMATTEDFIELD, sal_True, sal_True )
     361             :                             // use the old control name for compytibility reasons
     362          15 :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     363             : {
     364             :     DBG_CTOR(OFormattedModel, NULL);
     365             : 
     366          15 :     implConstruct();
     367             : 
     368          15 :     m_nClassId = FormComponentType::TEXTFIELD;
     369          15 :     initValueProperty( PROPERTY_EFFECTIVE_VALUE, PROPERTY_ID_EFFECTIVE_VALUE );
     370          15 : }
     371             : 
     372             : //------------------------------------------------------------------
     373           0 : OFormattedModel::OFormattedModel( const OFormattedModel* _pOriginal, const Reference< XComponentContext >& _rxFactory )
     374             :     :OEditBaseModel( _pOriginal, _rxFactory )
     375           0 :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     376             : {
     377             :     DBG_CTOR(OFormattedModel, NULL);
     378             : 
     379           0 :     implConstruct();
     380           0 : }
     381             : 
     382             : //------------------------------------------------------------------------------
     383          30 : OFormattedModel::~OFormattedModel()
     384             : {
     385             :     DBG_DTOR(OFormattedModel, NULL);
     386          30 : }
     387             : 
     388             : // XCloneable
     389             : //------------------------------------------------------------------------------
     390           0 : IMPLEMENT_DEFAULT_CLONING( OFormattedModel )
     391             : 
     392             : //------------------------------------------------------------------------------
     393          15 : void SAL_CALL OFormattedModel::disposing()
     394             : {
     395          15 :     OErrorBroadcaster::disposing();
     396          15 :     OEditBaseModel::disposing();
     397          15 : }
     398             : 
     399             : // XServiceInfo
     400             : //------------------------------------------------------------------------------
     401           1 : StringSequence OFormattedModel::getSupportedServiceNames() throw()
     402             : {
     403           1 :     StringSequence aSupported = OEditBaseModel::getSupportedServiceNames();
     404             : 
     405           1 :     sal_Int32 nOldLen = aSupported.getLength();
     406           1 :     aSupported.realloc( nOldLen + 8 );
     407           1 :     OUString* pStoreTo = aSupported.getArray() + nOldLen;
     408             : 
     409           1 :     *pStoreTo++ = BINDABLE_CONTROL_MODEL;
     410           1 :     *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
     411           1 :     *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
     412             : 
     413           1 :     *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
     414           1 :     *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
     415             : 
     416           1 :     *pStoreTo++ = FRM_SUN_COMPONENT_FORMATTEDFIELD;
     417           1 :     *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD;
     418           1 :     *pStoreTo++ = BINDABLE_DATABASE_FORMATTED_FIELD;
     419             : 
     420           1 :     return aSupported;
     421             : }
     422             : 
     423             : // XAggregation
     424             : //------------------------------------------------------------------------------
     425         561 : Any SAL_CALL OFormattedModel::queryAggregation(const Type& _rType) throw(RuntimeException)
     426             : {
     427         561 :     Any aReturn = OEditBaseModel::queryAggregation( _rType );
     428         561 :     return aReturn.hasValue() ? aReturn : OErrorBroadcaster::queryInterface( _rType );
     429             : }
     430             : 
     431             : // XTypeProvider
     432             : //------------------------------------------------------------------------------
     433           0 : Sequence< Type > OFormattedModel::_getTypes()
     434             : {
     435             :     return ::comphelper::concatSequences(
     436             :         OEditBaseModel::_getTypes(),
     437             :         OErrorBroadcaster::getTypes()
     438           0 :     );
     439             : }
     440             : 
     441             : // XPersistObject
     442             : //------------------------------------------------------------------------------
     443           0 : OUString SAL_CALL OFormattedModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
     444             : {
     445           0 :     return OUString(FRM_COMPONENT_EDIT);
     446             : }
     447             : 
     448             : // XPropertySet
     449             : //------------------------------------------------------------------------------
     450          15 : void OFormattedModel::describeFixedProperties( Sequence< Property >& _rProps ) const
     451             : {
     452          15 :     BEGIN_DESCRIBE_PROPERTIES( 3, OEditBaseModel )
     453          15 :         DECL_BOOL_PROP1(EMPTY_IS_NULL,                          BOUND);
     454          15 :         DECL_PROP1(TABINDEX,            sal_Int16,              BOUND);
     455          15 :         DECL_BOOL_PROP2(FILTERPROPOSAL,                         BOUND, MAYBEDEFAULT);
     456             :     END_DESCRIBE_PROPERTIES();
     457          15 : }
     458             : 
     459             : //------------------------------------------------------------------------------
     460          15 : void OFormattedModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
     461             : {
     462          15 :     OEditBaseModel::describeAggregateProperties( _rAggregateProps );
     463             : 
     464             :     // TreatAsNumeric nicht transient : wir wollen es an der UI anbinden (ist noetig, um dem EffectiveDefault
     465             :     // - der kann Text oder Zahl sein - einen Sinn zu geben)
     466          15 :     ModifyPropertyAttributes(_rAggregateProps, PROPERTY_TREATASNUMERIC, 0, PropertyAttribute::TRANSIENT);
     467             :     // same for FormatKey
     468             :     // (though the paragraph above for the TreatAsNumeric does not hold anymore - we do not have an UI for this.
     469             :     // But we have for the format key ...)
     470          15 :     ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, PropertyAttribute::TRANSIENT);
     471             : 
     472          15 :     RemoveProperty(_rAggregateProps, PROPERTY_STRICTFORMAT);
     473             :         // no strict format property for formatted fields: it does not make sense, 'cause
     474             :         // there is no general way to decide which characters/sub strings are allowed during the input of an
     475             :         // arbitraryly formatted control
     476          15 : }
     477             : 
     478             : //------------------------------------------------------------------------------
     479         166 : void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
     480             : {
     481         166 :     OEditBaseModel::getFastPropertyValue(rValue, nHandle);
     482         166 : }
     483             : 
     484             : //------------------------------------------------------------------------------
     485          29 : void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception)
     486             : {
     487          29 :     OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
     488          29 : }
     489             : 
     490             : //------------------------------------------------------------------------------
     491          29 : sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
     492             :                                                         throw( IllegalArgumentException )
     493             : {
     494          29 :     return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
     495             : }
     496             : 
     497             : //------------------------------------------------------------------------------
     498          15 : void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle)
     499             : {
     500          15 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     501             :     {
     502          15 :         Reference<XNumberFormatsSupplier>  xSupplier = calcDefaultFormatsSupplier();
     503             :         DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !");
     504          15 :         if (m_xAggregateSet.is())
     505          15 :             m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     506             :     }
     507             :     else
     508           0 :         OEditBaseModel::setPropertyToDefaultByHandle(nHandle);
     509          15 : }
     510             : 
     511             : //------------------------------------------------------------------------------
     512           0 : void OFormattedModel::setPropertyToDefault(const OUString& aPropertyName) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException )
     513             : {
     514           0 :     OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper();
     515           0 :     sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
     516             : 
     517           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     518           0 :         setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     519             :     else
     520           0 :         OEditBaseModel::setPropertyToDefault(aPropertyName);
     521           0 : }
     522             : 
     523             : //------------------------------------------------------------------------------
     524           0 : Any OFormattedModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
     525             : {
     526           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     527             :     {
     528           0 :         Reference<XNumberFormatsSupplier>  xSupplier = calcDefaultFormatsSupplier();
     529           0 :         return makeAny(xSupplier);
     530             :     }
     531             :     else
     532           0 :         return OEditBaseModel::getPropertyDefaultByHandle(nHandle);
     533             : }
     534             : 
     535             : //------------------------------------------------------------------------------
     536           0 : Any SAL_CALL OFormattedModel::getPropertyDefault( const OUString& aPropertyName ) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException )
     537             : {
     538           0 :     OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper();
     539           0 :     sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
     540             : 
     541           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     542           0 :         return getPropertyDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     543             :     else
     544           0 :         return OEditBaseModel::getPropertyDefault(aPropertyName);
     545             : }
     546             : 
     547             : //------------------------------------------------------------------------------
     548          36 : void OFormattedModel::_propertyChanged( const com::sun::star::beans::PropertyChangeEvent& evt ) throw(RuntimeException)
     549             : {
     550             :     // TODO: check how this works with external bindings
     551             : 
     552             :     OSL_ENSURE( evt.Source == m_xAggregateSet, "OFormattedModel::_propertyChanged: where did this come from?" );
     553          36 :     if ( evt.Source == m_xAggregateSet )
     554             :     {
     555          36 :         Reference< XPropertySet > xSourceSet( evt.Source, UNO_QUERY );
     556          36 :         if ( evt.PropertyName.equals( PROPERTY_FORMATKEY ) )
     557             :         {
     558          14 :             if ( evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG )
     559             :             {
     560             :                 try
     561             :                 {
     562          14 :                     ::osl::MutexGuard aGuard( m_aMutex );
     563             : 
     564          28 :                     Reference<XNumberFormatsSupplier> xSupplier( calcFormatsSupplier() );
     565          14 :                     m_nKeyType  = getNumberFormatType(xSupplier->getNumberFormats(), getINT32( evt.NewValue ) );
     566             : 
     567             :                     // as m_aSaveValue (which is used by commitControlValueToDbColumn) is format dependent we have
     568             :                     // to recalc it, which is done by translateDbColumnToControlValue
     569          14 :                     if ( m_xColumn.is() && m_xAggregateFastSet.is()  && !m_xCursor->isBeforeFirst() && !m_xCursor->isAfterLast())
     570             :                     {
     571           0 :                         setControlValue( translateDbColumnToControlValue(), eOther );
     572             :                     }
     573             : 
     574             :                     // if we're connected to an external value binding, then re-calculate the type
     575             :                     // used to exchange the value - it depends on the format, too
     576          14 :                     if ( hasExternalValueBinding() )
     577             :                     {
     578           0 :                         calculateExternalValueType();
     579          14 :                     }
     580             :                 }
     581           0 :                 catch(const Exception&)
     582             :                 {
     583             :                 }
     584             :             }
     585          14 :             return;
     586             :         }
     587             : 
     588          22 :         if ( evt.PropertyName.equals( PROPERTY_FORMATSSUPPLIER ) )
     589             :         {
     590          14 :             updateFormatterNullDate();
     591          14 :             return;
     592             :         }
     593             : 
     594           8 :         OBoundControlModel::_propertyChanged( evt );
     595             :     }
     596             : }
     597             : 
     598             : //------------------------------------------------------------------------------
     599          14 : void OFormattedModel::updateFormatterNullDate()
     600             : {
     601             :     // calc the current NULL date
     602          14 :     Reference< XNumberFormatsSupplier > xSupplier( calcFormatsSupplier() );
     603          14 :     if ( xSupplier.is() )
     604          14 :         xSupplier->getNumberFormatSettings()->getPropertyValue("NullDate") >>= m_aNullDate;
     605          14 : }
     606             : 
     607             : //------------------------------------------------------------------------------
     608          42 : Reference< XNumberFormatsSupplier > OFormattedModel::calcFormatsSupplier() const
     609             : {
     610          42 :     Reference<XNumberFormatsSupplier>  xSupplier;
     611             : 
     612             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !");
     613             :     // hat mein aggregiertes Model einen FormatSupplier ?
     614          42 :     if( m_xAggregateSet.is() )
     615          42 :         m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier;
     616             : 
     617          42 :     if (!xSupplier.is())
     618             :         // check if my parent form has a supplier
     619           0 :         xSupplier = calcFormFormatsSupplier();
     620             : 
     621          42 :     if (!xSupplier.is())
     622           0 :         xSupplier = calcDefaultFormatsSupplier();
     623             : 
     624             :     DBG_ASSERT(xSupplier.is(), "OFormattedModel::calcFormatsSupplier : no supplier !");
     625             :         // jetzt sollte aber einer da sein
     626          42 :     return xSupplier;
     627             : }
     628             : 
     629             : //------------------------------------------------------------------------------
     630           0 : Reference<XNumberFormatsSupplier>  OFormattedModel::calcFormFormatsSupplier() const
     631             : {
     632           0 :     Reference<XChild>  xMe;
     633           0 :     query_interface(static_cast<XWeak*>(const_cast<OFormattedModel*>(this)), xMe);
     634             :     // damit stellen wir sicher, dass wir auch fuer den Fall der Aggregation das richtige
     635             :     // Objekt bekommen
     636             :     DBG_ASSERT(xMe.is(), "OFormattedModel::calcFormFormatsSupplier : I should have a content interface !");
     637             : 
     638             :     // jetzt durchhangeln nach oben, bis wir auf eine starform treffen (angefangen mit meinem eigenen Parent)
     639           0 :     Reference<XChild>  xParent(xMe->getParent(), UNO_QUERY);
     640           0 :     Reference<XForm>  xNextParentForm(xParent, UNO_QUERY);
     641           0 :     while (!xNextParentForm.is() && xParent.is())
     642             :     {
     643           0 :         xParent         = xParent.query( xParent->getParent() );
     644           0 :         xNextParentForm = xNextParentForm.query( xParent );
     645             :     }
     646             : 
     647           0 :     if (!xNextParentForm.is())
     648             :     {
     649             :         OSL_FAIL("OFormattedModel::calcFormFormatsSupplier : have no ancestor which is a form !");
     650           0 :         return NULL;
     651             :     }
     652             : 
     653             :     // den FormatSupplier von meinem Vorfahren (falls der einen hat)
     654           0 :     Reference< XRowSet > xRowSet( xNextParentForm, UNO_QUERY );
     655           0 :     Reference< XNumberFormatsSupplier > xSupplier;
     656           0 :     if (xRowSet.is())
     657           0 :         xSupplier = getNumberFormats( getConnection(xRowSet), sal_True, getContext() );
     658           0 :     return xSupplier;
     659             : }
     660             : 
     661             : //------------------------------------------------------------------------------
     662          15 : Reference< XNumberFormatsSupplier > OFormattedModel::calcDefaultFormatsSupplier() const
     663             : {
     664          15 :     return StandardFormatsSupplier::get( getContext() );
     665             : }
     666             : 
     667             : // XBoundComponent
     668             : //------------------------------------------------------------------------------
     669           0 : void OFormattedModel::loaded(const EventObject& rEvent) throw ( ::com::sun::star::uno::RuntimeException)
     670             : {
     671             :     // HACK : our onConnectedDbColumn accesses our NumberFormatter which locks the solar mutex (as it doesn't have
     672             :     // an own one). To prevent deadlocks with other threads which may request a property from us in an
     673             :     // UI-triggered action (e.g. an tooltip) we lock the solar mutex _here_ before our base class locks
     674             :     // it's own muext (which is used for property requests)
     675             :     // alternative a): we use two mutexes, one which is passed to the OPropertysetHelper and used for
     676             :     // property requests and one for our own code. This would need a lot of code rewriting
     677             :     // alternative b): The NumberFormatter has to be really threadsafe (with an own mutex), which is
     678             :     // the only "clean" solution for me.
     679             : 
     680           0 :     SolarMutexGuard aGuard;
     681           0 :     OEditBaseModel::loaded(rEvent);
     682           0 : }
     683             : 
     684             : //------------------------------------------------------------------------------
     685          14 : void OFormattedModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
     686             : {
     687          14 :     m_xOriginalFormatter = NULL;
     688             : 
     689             :     // get some properties of the field
     690          14 :     m_nFieldType = DataType::OTHER;
     691          14 :     Reference<XPropertySet> xField = getField();
     692          14 :     if ( xField.is() )
     693          14 :         xField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= m_nFieldType;
     694             : 
     695          14 :     sal_Int32 nFormatKey = 0;
     696             : 
     697             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::onConnectedDbColumn : have no aggregate !");
     698          14 :     if (m_xAggregateSet.is())
     699             :     {   // all the following doesn't make any sense if we have no aggregate ...
     700          14 :         Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
     701             :         DBG_ASSERT( aSupplier.hasValue(), "OFormattedModel::onConnectedDbColumn : invalid property value !" );
     702             :         // das sollte im Constructor oder im read auf was richtiges gesetzt worden sein
     703             : 
     704          28 :         Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     705          14 :         if ( !(aFmtKey >>= nFormatKey ) )
     706             :         {   // nobody gave us a format to use. So we examine the field we're bound to for a
     707             :             // format key, and use it ourself, too
     708           0 :             sal_Int32 nType = DataType::VARCHAR;
     709           0 :             if (xField.is())
     710             :             {
     711           0 :                 aFmtKey = xField->getPropertyValue(PROPERTY_FORMATKEY);
     712           0 :                 xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType ;
     713             :             }
     714             : 
     715           0 :             Reference<XNumberFormatsSupplier>  xSupplier = calcFormFormatsSupplier();
     716             :             DBG_ASSERT(xSupplier.is(), "OFormattedModel::onConnectedDbColumn : bound to a field but no parent with a formatter ? how this ?");
     717           0 :             if (xSupplier.is())
     718             :             {
     719           0 :                 m_bOriginalNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC));
     720             : 
     721           0 :                 if (!aFmtKey.hasValue())
     722             :                 {   // we aren't bound to a field (or this field's format is invalid)
     723             :                     // -> determine the standard text (or numeric) format of the supplier
     724           0 :                     Reference<XNumberFormatTypes>  xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
     725           0 :                     if (xTypes.is())
     726             :                     {
     727           0 :                         Locale aApplicationLocale = Application::GetSettings().GetUILanguageTag().getLocale();
     728             : 
     729           0 :                         if (m_bOriginalNumeric)
     730           0 :                             aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::NUMBER, aApplicationLocale);
     731             :                         else
     732           0 :                             aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::TEXT, aApplicationLocale);
     733           0 :                     }
     734             :                 }
     735             : 
     736           0 :                 aSupplier >>= m_xOriginalFormatter;
     737           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     738           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, aFmtKey);
     739             : 
     740             :                 // das Numeric-Flag an mein gebundenes Feld anpassen
     741           0 :                 if (xField.is())
     742             :                 {
     743           0 :                     m_bNumeric = sal_False;
     744           0 :                     switch (nType)
     745             :                     {
     746             :                         case DataType::BIT:
     747             :                         case DataType::BOOLEAN:
     748             :                         case DataType::TINYINT:
     749             :                         case DataType::SMALLINT:
     750             :                         case DataType::INTEGER:
     751             :                         case DataType::BIGINT:
     752             :                         case DataType::FLOAT:
     753             :                         case DataType::REAL:
     754             :                         case DataType::DOUBLE:
     755             :                         case DataType::NUMERIC:
     756             :                         case DataType::DECIMAL:
     757             :                         case DataType::DATE:
     758             :                         case DataType::TIME:
     759             :                         case DataType::TIMESTAMP:
     760           0 :                             m_bNumeric = sal_True;
     761           0 :                             break;
     762             :                     }
     763             :                 }
     764             :                 else
     765           0 :                     m_bNumeric = m_bOriginalNumeric;
     766             : 
     767           0 :                 setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bNumeric));
     768             : 
     769           0 :                 OSL_VERIFY( aFmtKey >>= nFormatKey );
     770           0 :             }
     771          14 :         }
     772             :     }
     773             : 
     774          14 :     Reference<XNumberFormatsSupplier>  xSupplier = calcFormatsSupplier();
     775          14 :     m_bNumeric = getBOOL( getPropertyValue( PROPERTY_TREATASNUMERIC ) );
     776          14 :     m_nKeyType  = getNumberFormatType( xSupplier->getNumberFormats(), nFormatKey );
     777          14 :     xSupplier->getNumberFormatSettings()->getPropertyValue("NullDate") >>= m_aNullDate;
     778             : 
     779          14 :     OEditBaseModel::onConnectedDbColumn( _rxForm );
     780          14 : }
     781             : 
     782             : //------------------------------------------------------------------------------
     783          14 : void OFormattedModel::onDisconnectedDbColumn()
     784             : {
     785          14 :     OEditBaseModel::onDisconnectedDbColumn();
     786          14 :     if (m_xOriginalFormatter.is())
     787             :     {   // unser aggregiertes Model hatte keinerlei Format-Informationen
     788           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(m_xOriginalFormatter));
     789           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, Any());
     790           0 :         setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bOriginalNumeric));
     791           0 :         m_xOriginalFormatter = NULL;
     792             :     }
     793             : 
     794          14 :     m_nFieldType = DataType::OTHER;
     795          14 :     m_nKeyType   = NumberFormat::UNDEFINED;
     796          14 :     m_aNullDate  = DBTypeConversion::getStandardDate();
     797          14 : }
     798             : 
     799             : //------------------------------------------------------------------------------
     800           0 : void OFormattedModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
     801             : {
     802           0 :     OEditBaseModel::write(_rxOutStream);
     803           0 :     _rxOutStream->writeShort(0x0003);
     804             : 
     805             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::write : have no aggregate !");
     806             : 
     807             :     // mein Format (evtl. void) in ein persistentes Format bringen (der Supplier zusammen mit dem Key ist es zwar auch,
     808             :     // aber deswegen muessen wir ja nicht gleich den ganzen Supplier speichern, das waere ein klein wenig Overhead ;)
     809             : 
     810           0 :         Reference<XNumberFormatsSupplier>  xSupplier;
     811           0 :         Any aFmtKey;
     812           0 :     sal_Bool bVoidKey = sal_True;
     813           0 :     if (m_xAggregateSet.is())
     814             :     {
     815           0 :         Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
     816           0 :         if (aSupplier.getValueType().getTypeClass() != TypeClass_VOID)
     817             :         {
     818           0 :             OSL_VERIFY( aSupplier >>= xSupplier );
     819             :         }
     820             : 
     821           0 :         aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     822           0 :         bVoidKey = (!xSupplier.is() || !aFmtKey.hasValue()) || (isLoaded() && m_xOriginalFormatter.is());
     823             :             // (kein Fomatter und/oder Key) oder (loaded und faked Formatter)
     824             :     }
     825             : 
     826           0 :     _rxOutStream->writeBoolean(!bVoidKey);
     827           0 :     if (!bVoidKey)
     828             :     {
     829             :         // aus dem FormatKey und dem Formatter persistente Angaben basteln
     830             : 
     831           0 :         Any aKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     832           0 :         sal_Int32 nKey = aKey.hasValue() ? getINT32(aKey) : 0;
     833             : 
     834           0 :         Reference<XNumberFormats>  xFormats = xSupplier->getNumberFormats();
     835             : 
     836           0 :         OUString         sFormatDescription;
     837           0 :         LanguageType    eFormatLanguage = LANGUAGE_DONTKNOW;
     838             : 
     839           0 :         static const OUString s_aLocaleProp ("Locale");
     840           0 :         Reference<com::sun::star::beans::XPropertySet>  xFormat = xFormats->getByKey(nKey);
     841           0 :         if (hasProperty(s_aLocaleProp, xFormat))
     842             :         {
     843           0 :             Any aLocale = xFormat->getPropertyValue(s_aLocaleProp);
     844             :             DBG_ASSERT(isA(aLocale, static_cast<Locale*>(NULL)), "OFormattedModel::write : invalid language property !");
     845           0 :             if (isA(aLocale, static_cast<Locale*>(NULL)))
     846             :             {
     847           0 :                 Locale* pLocale = (Locale*)aLocale.getValue();
     848           0 :                 eFormatLanguage = LanguageTag( *pLocale ).getLanguageType( false);
     849           0 :             }
     850             :         }
     851             : 
     852           0 :         static const OUString s_aFormatStringProp ("FormatString");
     853           0 :         if (hasProperty(s_aFormatStringProp, xFormat))
     854           0 :             xFormat->getPropertyValue(s_aFormatStringProp) >>= sFormatDescription;
     855             : 
     856           0 :         _rxOutStream->writeUTF(sFormatDescription);
     857           0 :         _rxOutStream->writeLong((sal_Int32)eFormatLanguage);
     858             :     }
     859             : 
     860             :     // version 2 : write the properties common to all OEditBaseModels
     861           0 :     writeCommonEditProperties(_rxOutStream);
     862             : 
     863             :     // version 3 : write the effective value property of the aggregate
     864             :     // Due to a bug within the UnoControlFormattedFieldModel implementation (our default aggregate) this props value isn't correctly read
     865             :     // and this can't be corrected without being incompatible.
     866             :     // so we have our own handling.
     867             : 
     868             :     // and to be a little bit more compatible we make the following section skippable
     869             :     {
     870           0 :         OStreamSection aDownCompat(_rxOutStream);
     871             : 
     872             :         // a sub version within the skippable block
     873           0 :         _rxOutStream->writeShort(0x0000);
     874             : 
     875             :         // version 0: the effective value of the aggregate
     876           0 :                 Any aEffectiveValue;
     877           0 :         if (m_xAggregateSet.is())
     878             :         {
     879           0 :             try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(const Exception&) { }
     880             :         }
     881             : 
     882             :         {
     883           0 :             OStreamSection aDownCompat2(_rxOutStream);
     884           0 :             switch (aEffectiveValue.getValueType().getTypeClass())
     885             :             {
     886             :                 case TypeClass_STRING:
     887           0 :                     _rxOutStream->writeShort(0x0000);
     888           0 :                     _rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue));
     889           0 :                     break;
     890             :                 case TypeClass_DOUBLE:
     891           0 :                     _rxOutStream->writeShort(0x0001);
     892           0 :                     _rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue));
     893           0 :                     break;
     894             :                 default:    // void and all unknown states
     895             :                     DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !");
     896           0 :                     _rxOutStream->writeShort(0x0002);
     897           0 :                     break;
     898           0 :             }
     899           0 :         }
     900           0 :     }
     901           0 : }
     902             : 
     903             : //------------------------------------------------------------------------------
     904           0 : void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
     905             : {
     906           0 :     OEditBaseModel::read(_rxInStream);
     907           0 :     sal_uInt16 nVersion = _rxInStream->readShort();
     908             : 
     909           0 :     Reference<XNumberFormatsSupplier>  xSupplier;
     910           0 :     sal_Int32 nKey = -1;
     911           0 :     switch (nVersion)
     912             :     {
     913             :         case 0x0001 :
     914             :         case 0x0002 :
     915             :         case 0x0003 :
     916             :         {
     917           0 :             sal_Bool bNonVoidKey = _rxInStream->readBoolean();
     918           0 :             if (bNonVoidKey)
     919             :             {
     920             :                 // den String und die Language lesen ....
     921           0 :                 OUString sFormatDescription = _rxInStream->readUTF();
     922           0 :                 LanguageType eDescriptionLanguage = (LanguageType)_rxInStream->readLong();
     923             : 
     924             :                 // und daraus von einem Formatter zu einem Key zusammenwuerfeln lassen ...
     925           0 :                 xSupplier = calcFormatsSupplier();
     926             :                     // calcFormatsSupplier nimmt erst den vom Model, dann einen von der starform, dann einen ganz neuen ....
     927           0 :                 Reference<XNumberFormats>  xFormats = xSupplier->getNumberFormats();
     928             : 
     929           0 :                 if (xFormats.is())
     930             :                 {
     931           0 :                     Locale aDescriptionLanguage( LanguageTag(eDescriptionLanguage).getLocale());
     932             : 
     933           0 :                     nKey = xFormats->queryKey(sFormatDescription, aDescriptionLanguage, sal_False);
     934           0 :                     if (nKey == (sal_Int32)-1)
     935             :                     {   // noch nicht vorhanden in meinem Formatter ...
     936           0 :                         nKey = xFormats->addNew(sFormatDescription, aDescriptionLanguage);
     937           0 :                     }
     938           0 :                 }
     939             :             }
     940           0 :             if ((nVersion == 0x0002) || (nVersion == 0x0003))
     941           0 :                 readCommonEditProperties(_rxInStream);
     942             : 
     943           0 :             if (nVersion == 0x0003)
     944             :             {   // since version 3 there is a "skippable" block at this position
     945           0 :                 OStreamSection aDownCompat(_rxInStream);
     946             : 
     947           0 :                 sal_Int16 nSubVersion = _rxInStream->readShort();
     948             :                 (void)nSubVersion;
     949             : 
     950             :                 // version 0 and higher : the "effective value" property
     951           0 :                 Any aEffectiveValue;
     952             :                 {
     953           0 :                     OStreamSection aDownCompat2(_rxInStream);
     954           0 :                     switch (_rxInStream->readShort())
     955             :                     {
     956             :                         case 0: // String
     957           0 :                             aEffectiveValue <<= _rxInStream->readUTF();
     958           0 :                             break;
     959             :                         case 1: // double
     960           0 :                             aEffectiveValue <<= (double)_rxInStream->readDouble();
     961           0 :                             break;
     962             :                         case 2:
     963           0 :                             break;
     964             :                         case 3:
     965             :                             OSL_FAIL("FmXFormattedModel::read : unknown effective value type !");
     966           0 :                     }
     967             :                 }
     968             : 
     969             :                 // this property is only to be set if we have no control source : in all other cases the base class did a
     970             :                 // reset after it's read and this set the effective value to a default value
     971           0 :                 if ( m_xAggregateSet.is() && getControlSource().isEmpty() )
     972             :                 {
     973             :                     try
     974             :                     {
     975           0 :                         m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue);
     976             :                     }
     977           0 :                     catch(const Exception&)
     978             :                     {
     979             :                     }
     980           0 :                 }
     981             :             }
     982             :         }
     983           0 :         break;
     984             :         default :
     985             :             OSL_FAIL("OFormattedModel::read : unknown version !");
     986             :             // dann bleibt das Format des aggregierten Sets, wie es bei der Erzeugung ist : void
     987           0 :             defaultCommonEditProperties();
     988           0 :             break;
     989             :     }
     990             : 
     991           0 :     if ((nKey != -1) && m_xAggregateSet.is())
     992             :     {
     993           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     994           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey));
     995             :     }
     996             :     else
     997             :     {
     998           0 :         setPropertyToDefault(PROPERTY_FORMATSSUPPLIER);
     999           0 :         setPropertyToDefault(PROPERTY_FORMATKEY);
    1000           0 :     }
    1001           0 : }
    1002             : 
    1003             : //------------------------------------------------------------------------------
    1004           0 : sal_uInt16 OFormattedModel::getPersistenceFlags() const
    1005             : {
    1006           0 :     return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS);
    1007             :     // a) we do our own call to writeCommonEditProperties
    1008             : }
    1009             : 
    1010             : //------------------------------------------------------------------------------
    1011           0 : sal_Bool OFormattedModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
    1012             : {
    1013           0 :     Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
    1014           0 :     if ( aControlValue != m_aSaveValue )
    1015             :     {
    1016             :         // Leerstring + EmptyIsNull = void
    1017           0 :         if  (   !aControlValue.hasValue()
    1018           0 :             ||  (   ( aControlValue.getValueType().getTypeClass() == TypeClass_STRING )
    1019           0 :                 &&  getString( aControlValue ).isEmpty()
    1020           0 :                 &&  m_bEmptyIsNull
    1021             :                 )
    1022             :             )
    1023           0 :             m_xColumnUpdate->updateNull();
    1024             :         else
    1025             :         {
    1026             :             try
    1027             :             {
    1028           0 :                 double f = 0.0;
    1029           0 :                 if ( aControlValue.getValueType().getTypeClass() == TypeClass_DOUBLE || (aControlValue >>= f)) // #i110323
    1030             :                 {
    1031           0 :                     DBTypeConversion::setValue( m_xColumnUpdate, m_aNullDate, getDouble( aControlValue ), m_nKeyType );
    1032             :                 }
    1033             :                 else
    1034             :                 {
    1035             :                     DBG_ASSERT( aControlValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::commitControlValueToDbColumn: invalud value type !" );
    1036           0 :                     m_xColumnUpdate->updateString( getString( aControlValue ) );
    1037             :                 }
    1038             :             }
    1039           0 :             catch(const Exception&)
    1040             :             {
    1041           0 :                 return sal_False;
    1042             :             }
    1043             :         }
    1044           0 :         m_aSaveValue = aControlValue;
    1045             :     }
    1046           0 :     return sal_True;
    1047             : }
    1048             : 
    1049             : //------------------------------------------------------------------------------
    1050           0 : void OFormattedModel::onConnectedExternalValue( )
    1051             : {
    1052           0 :     OEditBaseModel::onConnectedExternalValue();
    1053           0 :     updateFormatterNullDate();
    1054           0 : }
    1055             : 
    1056             : //------------------------------------------------------------------------------
    1057           0 : Any OFormattedModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
    1058             : {
    1059           0 :     Any aControlValue;
    1060           0 :     switch( _rExternalValue.getValueTypeClass() )
    1061             :     {
    1062             :     case TypeClass_VOID:
    1063           0 :         break;
    1064             : 
    1065             :     case TypeClass_STRING:
    1066           0 :         aControlValue = _rExternalValue;
    1067           0 :         break;
    1068             : 
    1069             :     case TypeClass_BOOLEAN:
    1070             :     {
    1071           0 :         sal_Bool bExternalValue = sal_False;
    1072           0 :         _rExternalValue >>= bExternalValue;
    1073           0 :         aControlValue <<= (double)( bExternalValue ? 1 : 0 );
    1074             :     }
    1075           0 :     break;
    1076             : 
    1077             :     default:
    1078             :     {
    1079           0 :         if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) )
    1080             :         {
    1081           0 :             UNODate aDate;
    1082           0 :             _rExternalValue >>= aDate;
    1083           0 :             aControlValue <<= DBTypeConversion::toDouble( aDate, m_aNullDate );
    1084             :         }
    1085           0 :         else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) )
    1086             :         {
    1087           0 :             UNOTime aTime;
    1088           0 :             _rExternalValue >>= aTime;
    1089           0 :             aControlValue <<= DBTypeConversion::toDouble( aTime );
    1090             :         }
    1091           0 :         else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) )
    1092             :         {
    1093           0 :             UNODateTime aDateTime;
    1094           0 :             _rExternalValue >>= aDateTime;
    1095           0 :             aControlValue <<= DBTypeConversion::toDouble( aDateTime, m_aNullDate );
    1096             :         }
    1097             :         else
    1098             :         {
    1099             :             OSL_ENSURE( _rExternalValue.getValueTypeClass() == TypeClass_DOUBLE,
    1100             :                 "OFormattedModel::translateExternalValueToControlValue: don't know how to translate this type!" );
    1101           0 :             double fValue = 0;
    1102           0 :             OSL_VERIFY( _rExternalValue >>= fValue );
    1103           0 :             aControlValue <<= fValue;
    1104             :         }
    1105             :     }
    1106             :     }
    1107             : 
    1108           0 :     return aControlValue;
    1109             : }
    1110             : 
    1111             : //------------------------------------------------------------------------------
    1112           0 : Any OFormattedModel::translateControlValueToExternalValue( ) const
    1113             : {
    1114             :     OSL_PRECOND( hasExternalValueBinding(),
    1115             :         "OFormattedModel::translateControlValueToExternalValue: precondition not met!" );
    1116             : 
    1117           0 :     Any aControlValue( getControlValue() );
    1118           0 :     if ( !aControlValue.hasValue() )
    1119           0 :         return aControlValue;
    1120             : 
    1121           0 :     Any aExternalValue;
    1122             : 
    1123             :     // translate into the external value type
    1124           0 :     Type aExternalValueType( getExternalValueType() );
    1125           0 :     switch ( aExternalValueType.getTypeClass() )
    1126             :     {
    1127             :     case TypeClass_STRING:
    1128             :     {
    1129           0 :         OUString sString;
    1130           0 :         if ( aControlValue >>= sString )
    1131             :         {
    1132           0 :             aExternalValue <<= sString;
    1133           0 :             break;
    1134           0 :         }
    1135             :     }
    1136             :     // NO break here!
    1137             : 
    1138             :     case TypeClass_BOOLEAN:
    1139             :     {
    1140           0 :         double fValue = 0;
    1141           0 :         OSL_VERIFY( aControlValue >>= fValue );
    1142             :             // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
    1143             :             // and the control value is a string. This implies some weird misconfiguration
    1144             :             // of the FormattedModel, so we won't care for it for the moment.
    1145           0 :         aExternalValue <<= (sal_Bool)( fValue ? sal_True : sal_False );
    1146             :     }
    1147           0 :     break;
    1148             : 
    1149             :     default:
    1150             :     {
    1151           0 :         double fValue = 0;
    1152           0 :         OSL_VERIFY( aControlValue >>= fValue );
    1153             :             // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
    1154             :             // and the control value is a string. This implies some weird misconfiguration
    1155             :             // of the FormattedModel, so we won't care for it for the moment.
    1156             : 
    1157           0 :         if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) )
    1158             :         {
    1159           0 :             aExternalValue <<= DBTypeConversion::toDate( fValue, m_aNullDate );
    1160             :         }
    1161           0 :         else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) )
    1162             :         {
    1163           0 :             aExternalValue <<= DBTypeConversion::toTime( fValue );
    1164             :         }
    1165           0 :         else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) )
    1166             :         {
    1167           0 :             aExternalValue <<= DBTypeConversion::toDateTime( fValue, m_aNullDate );
    1168             :         }
    1169             :         else
    1170             :         {
    1171             :             OSL_ENSURE( aExternalValueType.equals( ::getCppuType( static_cast< double* >( NULL ) ) ),
    1172             :                 "OFormattedModel::translateControlValueToExternalValue: don't know how to translate this type!" );
    1173           0 :             aExternalValue <<= fValue;
    1174             :         }
    1175             :     }
    1176           0 :     break;
    1177             :     }
    1178           0 :     return aExternalValue;
    1179             : }
    1180             : 
    1181             : //------------------------------------------------------------------------------
    1182          19 : Any OFormattedModel::translateDbColumnToControlValue()
    1183             : {
    1184          19 :     if ( m_bNumeric )
    1185           0 :         m_aSaveValue <<= DBTypeConversion::getValue( m_xColumn, m_aNullDate ); // #100056# OJ
    1186             :     else
    1187          19 :         m_aSaveValue <<= m_xColumn->getString();
    1188             : 
    1189          19 :     if ( m_xColumn->wasNull() )
    1190           9 :         m_aSaveValue.clear();
    1191             : 
    1192          19 :     return m_aSaveValue;
    1193             : }
    1194             : 
    1195             : // -----------------------------------------------------------------------------
    1196           0 : Sequence< Type > OFormattedModel::getSupportedBindingTypes()
    1197             : {
    1198           0 :     ::std::list< Type > aTypes;
    1199           0 :     aTypes.push_back( ::getCppuType( static_cast< double* >( NULL ) ) );
    1200             : 
    1201           0 :     switch ( m_nKeyType & ~NumberFormat::DEFINED )
    1202             :     {
    1203             :     case NumberFormat::DATE:
    1204           0 :         aTypes.push_front(::getCppuType( static_cast< UNODate* >( NULL ) ) );
    1205           0 :         break;
    1206             :     case NumberFormat::TIME:
    1207           0 :         aTypes.push_front(::getCppuType( static_cast< UNOTime* >( NULL ) ) );
    1208           0 :         break;
    1209             :     case NumberFormat::DATETIME:
    1210           0 :         aTypes.push_front(::getCppuType( static_cast< UNODateTime* >( NULL ) ) );
    1211           0 :         break;
    1212             :     case NumberFormat::TEXT:
    1213           0 :         aTypes.push_front(::getCppuType( static_cast< OUString* >( NULL ) ) );
    1214           0 :         break;
    1215             :     case NumberFormat::LOGICAL:
    1216           0 :         aTypes.push_front(::getCppuType( static_cast< sal_Bool* >( NULL ) ) );
    1217           0 :         break;
    1218             :     }
    1219             : 
    1220           0 :     Sequence< Type > aTypesRet( aTypes.size() );
    1221           0 :     ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() );
    1222           0 :     return aTypesRet;
    1223             : }
    1224             : 
    1225             : //------------------------------------------------------------------------------
    1226           0 : Any OFormattedModel::getDefaultForReset() const
    1227             : {
    1228           0 :     return m_xAggregateSet->getPropertyValue( PROPERTY_EFFECTIVE_DEFAULT );
    1229             : }
    1230             : 
    1231             : //------------------------------------------------------------------------------
    1232           0 : void OFormattedModel::resetNoBroadcast()
    1233             : {
    1234           0 :     OEditBaseModel::resetNoBroadcast();
    1235           0 :     m_aSaveValue.clear();
    1236           0 : }
    1237             : 
    1238             : //.........................................................................
    1239          72 : }
    1240             : //.........................................................................
    1241             : 
    1242             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10