LCOV - code coverage report
Current view: top level - libreoffice/forms/source/component - FormattedField.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2 514 0.4 %
Date: 2012-12-27 Functions: 2 60 3.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 <i18npool/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< XMultiServiceFactory >& _rxORB );
      96             : 
      97             :     using SvNumberFormatsSupplierObj::operator new;
      98             :     using SvNumberFormatsSupplierObj::operator delete;
      99             : 
     100             : protected:
     101             :     StandardFormatsSupplier(const Reference<XMultiServiceFactory>& _rxFactory,LanguageType _eSysLanguage);
     102             :     ~StandardFormatsSupplier();
     103             : 
     104             : protected:
     105             :     virtual bool    queryTermination() const;
     106             :     virtual void    notifyTermination();
     107             : };
     108             : 
     109             : //------------------------------------------------------------------
     110           5 : WeakReference< XNumberFormatsSupplier > StandardFormatsSupplier::s_xDefaultFormatsSupplier;
     111             : 
     112             : //------------------------------------------------------------------
     113           0 : StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XMultiServiceFactory > & _rxFactory,LanguageType _eSysLanguage)
     114             :     :SvNumberFormatsSupplierObj()
     115           0 :     ,m_pMyPrivateFormatter(new SvNumberFormatter(_rxFactory, _eSysLanguage))
     116             : {
     117           0 :     SetNumberFormatter(m_pMyPrivateFormatter);
     118             : 
     119             :     // #i29147#
     120           0 :     ::utl::DesktopTerminationObserver::registerTerminationListener( this );
     121           0 : }
     122             : 
     123             : //------------------------------------------------------------------
     124           0 : StandardFormatsSupplier::~StandardFormatsSupplier()
     125             : {
     126           0 :     ::utl::DesktopTerminationObserver::revokeTerminationListener( this );
     127             : 
     128           0 :     DELETEZ( m_pMyPrivateFormatter );
     129           0 : }
     130             : 
     131             : //------------------------------------------------------------------
     132           0 : Reference< XNumberFormatsSupplier > StandardFormatsSupplier::get( const Reference< XMultiServiceFactory >& _rxORB )
     133             : {
     134           0 :     LanguageType eSysLanguage = LANGUAGE_SYSTEM;
     135             :     {
     136           0 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     137           0 :         Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
     138           0 :         if ( xSupplier.is() )
     139           0 :             return xSupplier;
     140             : 
     141             :         // get the Office's locale
     142           0 :         eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
     143             :     }
     144             : 
     145           0 :     StandardFormatsSupplier* pSupplier = new StandardFormatsSupplier( _rxORB, eSysLanguage );
     146           0 :     Reference< XNumberFormatsSupplier > xNewlyCreatedSupplier( pSupplier );
     147             : 
     148             :     {
     149           0 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     150           0 :         Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
     151           0 :         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           0 :         s_xDefaultFormatsSupplier = xNewlyCreatedSupplier;
     157             :     }
     158             : 
     159           0 :     return xNewlyCreatedSupplier;
     160             : }
     161             : 
     162             : //------------------------------------------------------------------
     163           0 : bool StandardFormatsSupplier::queryTermination() const
     164             : {
     165           0 :     return true;
     166             : }
     167             : 
     168             : //------------------------------------------------------------------
     169           0 : void StandardFormatsSupplier::notifyTermination()
     170             : {
     171           0 :     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           0 :     s_xDefaultFormatsSupplier = WeakReference< XNumberFormatsSupplier >( );
     176             : 
     177           0 :     SetNumberFormatter( NULL );
     178           0 :     DELETEZ( m_pMyPrivateFormatter );
     179           0 : }
     180             : 
     181             : /*************************************************************************/
     182             : //------------------------------------------------------------------
     183           0 : InterfaceRef SAL_CALL OFormattedControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
     184             : {
     185           0 :     return *(new OFormattedControl(_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           0 : Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException)
     199             : {
     200           0 :     Any aReturn = OBoundControl::queryAggregation(_rType);
     201           0 :     if (!aReturn.hasValue())
     202           0 :         aReturn = OFormattedControl_BASE::queryInterface(_rType);
     203           0 :     return aReturn;
     204             : }
     205             : 
     206             : 
     207             : DBG_NAME(OFormattedControl);
     208             : //------------------------------------------------------------------------------
     209           0 : OFormattedControl::OFormattedControl(const Reference<XMultiServiceFactory>& _rxFactory)
     210             :                :OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD)
     211           0 :                ,m_nKeyEvent(0)
     212             : {
     213             :     DBG_CTOR(OFormattedControl,NULL);
     214             : 
     215           0 :     increment(m_refCount);
     216             :     {
     217           0 :         Reference<XWindow>  xComp;
     218           0 :         if (query_aggregation(m_xAggregate, xComp))
     219             :         {
     220           0 :             xComp->addKeyListener(this);
     221           0 :         }
     222             :     }
     223           0 :     decrement(m_refCount);
     224           0 : }
     225             : 
     226             : //------------------------------------------------------------------------------
     227           0 : OFormattedControl::~OFormattedControl()
     228             : {
     229           0 :     if( m_nKeyEvent )
     230           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     231             : 
     232           0 :     if (!OComponentHelper::rBHelper.bDisposed)
     233             :     {
     234           0 :         acquire();
     235           0 :         dispose();
     236             :     }
     237             : 
     238             :     DBG_DTOR(OFormattedControl,NULL);
     239           0 : }
     240             : 
     241             : // XKeyListener
     242             : //------------------------------------------------------------------------------
     243           0 : void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException)
     244             : {
     245           0 :     OBoundControl::disposing(_rSource);
     246           0 : }
     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             :         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             :         return;
     258             : 
     259           0 :     Reference<XFormComponent>  xFComp(xSet, UNO_QUERY);
     260           0 :     InterfaceRef  xParent = xFComp->getParent();
     261           0 :     if( !xParent.is() )
     262             :         return;
     263             : 
     264           0 :     Reference<com::sun::star::beans::XPropertySet>  xFormSet(xParent, UNO_QUERY);
     265           0 :     if( !xFormSet.is() )
     266             :         return;
     267             : 
     268           0 :     Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL ));
     269           0 :     if (!isA(aTmp, static_cast< ::rtl::OUString* >(NULL)) ||
     270           0 :         getString(aTmp).isEmpty() )
     271             :         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             :                     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 :     ::rtl::OUString*pArray = aSupported.getArray();
     326           0 :     pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_FORMATTEDFIELD;
     327           0 :     return aSupported;
     328             : }
     329             : 
     330             : //------------------------------------------------------------------------------
     331           0 : void OFormattedControl::setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException)
     332             : {
     333           0 :     OBoundControl::setDesignMode(bOn);
     334           0 : }
     335             : 
     336             : /*************************************************************************/
     337             : DBG_NAME(OFormattedModel)
     338             : //------------------------------------------------------------------
     339           0 : void OFormattedModel::implConstruct()
     340             : {
     341             :     // members
     342           0 :     m_bOriginalNumeric = sal_False;
     343           0 :     m_bNumeric = sal_False;
     344           0 :     m_xOriginalFormatter = NULL;
     345           0 :     m_nKeyType = NumberFormat::UNDEFINED;
     346           0 :     m_aNullDate = DBTypeConversion::getStandardDate();
     347           0 :     m_nFieldType =  DataType::OTHER;
     348             : 
     349             :     // default our formats supplier
     350           0 :     increment(m_refCount);
     351           0 :     setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
     352           0 :     decrement(m_refCount);
     353             : 
     354           0 :     startAggregatePropertyListening( PROPERTY_FORMATKEY );
     355           0 :     startAggregatePropertyListening( PROPERTY_FORMATSSUPPLIER );
     356           0 : }
     357             : 
     358             : //------------------------------------------------------------------
     359           0 : OFormattedModel::OFormattedModel(const Reference<XMultiServiceFactory>& _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           0 :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     363             : {
     364             :     DBG_CTOR(OFormattedModel, NULL);
     365             : 
     366           0 :     implConstruct();
     367             : 
     368           0 :     m_nClassId = FormComponentType::TEXTFIELD;
     369           0 :     initValueProperty( PROPERTY_EFFECTIVE_VALUE, PROPERTY_ID_EFFECTIVE_VALUE );
     370           0 : }
     371             : 
     372             : //------------------------------------------------------------------
     373           0 : OFormattedModel::OFormattedModel( const OFormattedModel* _pOriginal, const Reference< XMultiServiceFactory >& _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           0 : OFormattedModel::~OFormattedModel()
     384             : {
     385             :     DBG_DTOR(OFormattedModel, NULL);
     386           0 : }
     387             : 
     388             : // XCloneable
     389             : //------------------------------------------------------------------------------
     390           0 : IMPLEMENT_DEFAULT_CLONING( OFormattedModel )
     391             : 
     392             : //------------------------------------------------------------------------------
     393           0 : void SAL_CALL OFormattedModel::disposing()
     394             : {
     395           0 :     OErrorBroadcaster::disposing();
     396           0 :     OEditBaseModel::disposing();
     397           0 : }
     398             : 
     399             : // XServiceInfo
     400             : //------------------------------------------------------------------------------
     401           0 : StringSequence OFormattedModel::getSupportedServiceNames() throw()
     402             : {
     403           0 :     StringSequence aSupported = OEditBaseModel::getSupportedServiceNames();
     404             : 
     405           0 :     sal_Int32 nOldLen = aSupported.getLength();
     406           0 :     aSupported.realloc( nOldLen + 8 );
     407           0 :     ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
     408             : 
     409           0 :     *pStoreTo++ = BINDABLE_CONTROL_MODEL;
     410           0 :     *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
     411           0 :     *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
     412             : 
     413           0 :     *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
     414           0 :     *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
     415             : 
     416           0 :     *pStoreTo++ = FRM_SUN_COMPONENT_FORMATTEDFIELD;
     417           0 :     *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD;
     418           0 :     *pStoreTo++ = BINDABLE_DATABASE_FORMATTED_FIELD;
     419             : 
     420           0 :     return aSupported;
     421             : }
     422             : 
     423             : // XAggregation
     424             : //------------------------------------------------------------------------------
     425           0 : Any SAL_CALL OFormattedModel::queryAggregation(const Type& _rType) throw(RuntimeException)
     426             : {
     427           0 :     Any aReturn = OEditBaseModel::queryAggregation( _rType );
     428           0 :     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 : ::rtl::OUString SAL_CALL OFormattedModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
     444             : {
     445           0 :     return ::rtl::OUString(FRM_COMPONENT_EDIT);
     446             : }
     447             : 
     448             : // XPropertySet
     449             : //------------------------------------------------------------------------------
     450           0 : void OFormattedModel::describeFixedProperties( Sequence< Property >& _rProps ) const
     451             : {
     452           0 :     BEGIN_DESCRIBE_PROPERTIES( 3, OEditBaseModel )
     453           0 :         DECL_BOOL_PROP1(EMPTY_IS_NULL,                          BOUND);
     454           0 :         DECL_PROP1(TABINDEX,            sal_Int16,              BOUND);
     455           0 :         DECL_BOOL_PROP2(FILTERPROPOSAL,                         BOUND, MAYBEDEFAULT);
     456             :     END_DESCRIBE_PROPERTIES();
     457           0 : }
     458             : 
     459             : //------------------------------------------------------------------------------
     460           0 : void OFormattedModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
     461             : {
     462           0 :     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           0 :     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           0 :     ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, PropertyAttribute::TRANSIENT);
     471             : 
     472           0 :     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           0 : }
     477             : 
     478             : //------------------------------------------------------------------------------
     479           0 : void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
     480             : {
     481           0 :     OEditBaseModel::getFastPropertyValue(rValue, nHandle);
     482           0 : }
     483             : 
     484             : //------------------------------------------------------------------------------
     485           0 : void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception)
     486             : {
     487           0 :     OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
     488           0 : }
     489             : 
     490             : //------------------------------------------------------------------------------
     491           0 : sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
     492             :                                                         throw( IllegalArgumentException )
     493             : {
     494           0 :     return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
     495             : }
     496             : 
     497             : //------------------------------------------------------------------------------
     498           0 : void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle)
     499             : {
     500           0 :     if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
     501             :     {
     502           0 :         Reference<XNumberFormatsSupplier>  xSupplier = calcDefaultFormatsSupplier();
     503             :         DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !");
     504           0 :         if (m_xAggregateSet.is())
     505           0 :             m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     506             :     }
     507             :     else
     508           0 :         OEditBaseModel::setPropertyToDefaultByHandle(nHandle);
     509           0 : }
     510             : 
     511             : //------------------------------------------------------------------------------
     512           0 : void OFormattedModel::setPropertyToDefault(const ::rtl::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 ::rtl::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           0 : 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           0 :     if ( evt.Source == m_xAggregateSet )
     554             :     {
     555           0 :         Reference< XPropertySet > xSourceSet( evt.Source, UNO_QUERY );
     556           0 :         if ( evt.PropertyName.equals( PROPERTY_FORMATKEY ) )
     557             :         {
     558           0 :             if ( evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG )
     559             :             {
     560             :                 try
     561             :                 {
     562           0 :                     ::osl::MutexGuard aGuard( m_aMutex );
     563             : 
     564           0 :                     Reference<XNumberFormatsSupplier> xSupplier( calcFormatsSupplier() );
     565           0 :                     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           0 :                     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           0 :                     if ( hasExternalValueBinding() )
     577             :                     {
     578           0 :                         calculateExternalValueType();
     579           0 :                     }
     580             :                 }
     581           0 :                 catch(const Exception&)
     582             :                 {
     583             :                 }
     584             :             }
     585             :             return;
     586             :         }
     587             : 
     588           0 :         if ( evt.PropertyName.equals( PROPERTY_FORMATSSUPPLIER ) )
     589             :         {
     590           0 :             updateFormatterNullDate();
     591             :             return;
     592             :         }
     593             : 
     594           0 :         OBoundControlModel::_propertyChanged( evt );
     595             :     }
     596             : }
     597             : 
     598             : //------------------------------------------------------------------------------
     599           0 : void OFormattedModel::updateFormatterNullDate()
     600             : {
     601             :     // calc the current NULL date
     602           0 :     Reference< XNumberFormatsSupplier > xSupplier( calcFormatsSupplier() );
     603           0 :     if ( xSupplier.is() )
     604           0 :         xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ) ) ) >>= m_aNullDate;
     605           0 : }
     606             : 
     607             : //------------------------------------------------------------------------------
     608           0 : Reference< XNumberFormatsSupplier > OFormattedModel::calcFormatsSupplier() const
     609             : {
     610           0 :     Reference<XNumberFormatsSupplier>  xSupplier;
     611             : 
     612             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !");
     613             :     // hat mein aggregiertes Model einen FormatSupplier ?
     614           0 :     if( m_xAggregateSet.is() )
     615           0 :         m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier;
     616             : 
     617           0 :     if (!xSupplier.is())
     618             :         // check if my parent form has a supplier
     619           0 :         xSupplier = calcFormFormatsSupplier();
     620             : 
     621           0 :     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           0 :     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().getUNOContext() );
     658           0 :     return xSupplier;
     659             : }
     660             : 
     661             : //------------------------------------------------------------------------------
     662           0 : Reference< XNumberFormatsSupplier > OFormattedModel::calcDefaultFormatsSupplier() const
     663             : {
     664           0 :     return StandardFormatsSupplier::get( getContext().getLegacyServiceFactory() );
     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           0 : void OFormattedModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
     686             : {
     687           0 :     m_xOriginalFormatter = NULL;
     688             : 
     689             :     // get some properties of the field
     690           0 :     m_nFieldType = DataType::OTHER;
     691           0 :     Reference<XPropertySet> xField = getField();
     692           0 :     if ( xField.is() )
     693           0 :         xField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= m_nFieldType;
     694             : 
     695           0 :     sal_Int32 nFormatKey = 0;
     696             : 
     697             :     DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::onConnectedDbColumn : have no aggregate !");
     698           0 :     if (m_xAggregateSet.is())
     699             :     {   // all the following doesn't make any sense if we have no aggregate ...
     700           0 :         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           0 :         Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
     705           0 :         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           0 :         }
     772             :     }
     773             : 
     774           0 :     Reference<XNumberFormatsSupplier>  xSupplier = calcFormatsSupplier();
     775           0 :     m_bNumeric = getBOOL( getPropertyValue( PROPERTY_TREATASNUMERIC ) );
     776           0 :     m_nKeyType  = getNumberFormatType( xSupplier->getNumberFormats(), nFormatKey );
     777           0 :     xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NullDate") ) ) >>= m_aNullDate;
     778             : 
     779           0 :     OEditBaseModel::onConnectedDbColumn( _rxForm );
     780           0 : }
     781             : 
     782             : //------------------------------------------------------------------------------
     783           0 : void OFormattedModel::onDisconnectedDbColumn()
     784             : {
     785           0 :     OEditBaseModel::onDisconnectedDbColumn();
     786           0 :     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           0 :     m_nFieldType = DataType::OTHER;
     795           0 :     m_nKeyType   = NumberFormat::UNDEFINED;
     796           0 :     m_aNullDate  = DBTypeConversion::getStandardDate();
     797           0 : }
     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 :         ::rtl::OUString         sFormatDescription;
     837           0 :         LanguageType    eFormatLanguage = LANGUAGE_DONTKNOW;
     838             : 
     839           0 :         static const ::rtl::OUString s_aLocaleProp (RTL_CONSTASCII_USTRINGPARAM("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 ::rtl::OUString s_aFormatStringProp (RTL_CONSTASCII_USTRINGPARAM("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 :         Reference< XDataOutputStream > xOut(_rxOutStream, UNO_QUERY);
     871           0 :         OStreamSection aDownCompat(xOut);
     872             : 
     873             :         // a sub version within the skippable block
     874           0 :         _rxOutStream->writeShort(0x0000);
     875             : 
     876             :         // version 0: the effective value of the aggregate
     877           0 :                 Any aEffectiveValue;
     878           0 :         if (m_xAggregateSet.is())
     879             :         {
     880           0 :             try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(const Exception&) { }
     881             :         }
     882             : 
     883             :         {
     884           0 :             OStreamSection aDownCompat2(xOut);
     885           0 :             switch (aEffectiveValue.getValueType().getTypeClass())
     886             :             {
     887             :                 case TypeClass_STRING:
     888           0 :                     _rxOutStream->writeShort(0x0000);
     889           0 :                     _rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue));
     890           0 :                     break;
     891             :                 case TypeClass_DOUBLE:
     892           0 :                     _rxOutStream->writeShort(0x0001);
     893           0 :                     _rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue));
     894           0 :                     break;
     895             :                 default:    // void and all unknown states
     896             :                     DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !");
     897           0 :                     _rxOutStream->writeShort(0x0002);
     898           0 :                     break;
     899           0 :             }
     900           0 :         }
     901           0 :     }
     902           0 : }
     903             : 
     904             : //------------------------------------------------------------------------------
     905           0 : void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
     906             : {
     907           0 :     OEditBaseModel::read(_rxInStream);
     908           0 :     sal_uInt16 nVersion = _rxInStream->readShort();
     909             : 
     910           0 :     Reference<XNumberFormatsSupplier>  xSupplier;
     911           0 :     sal_Int32 nKey = -1;
     912           0 :     switch (nVersion)
     913             :     {
     914             :         case 0x0001 :
     915             :         case 0x0002 :
     916             :         case 0x0003 :
     917             :         {
     918           0 :             sal_Bool bNonVoidKey = _rxInStream->readBoolean();
     919           0 :             if (bNonVoidKey)
     920             :             {
     921             :                 // den String und die Language lesen ....
     922           0 :                 ::rtl::OUString sFormatDescription = _rxInStream->readUTF();
     923           0 :                 LanguageType eDescriptionLanguage = (LanguageType)_rxInStream->readLong();
     924             : 
     925             :                 // und daraus von einem Formatter zu einem Key zusammenwuerfeln lassen ...
     926           0 :                 xSupplier = calcFormatsSupplier();
     927             :                     // calcFormatsSupplier nimmt erst den vom Model, dann einen von der starform, dann einen ganz neuen ....
     928           0 :                 Reference<XNumberFormats>  xFormats = xSupplier->getNumberFormats();
     929             : 
     930           0 :                 if (xFormats.is())
     931             :                 {
     932           0 :                     Locale aDescriptionLanguage( LanguageTag(eDescriptionLanguage).getLocale());
     933             : 
     934           0 :                     nKey = xFormats->queryKey(sFormatDescription, aDescriptionLanguage, sal_False);
     935           0 :                     if (nKey == (sal_Int32)-1)
     936             :                     {   // noch nicht vorhanden in meinem Formatter ...
     937           0 :                         nKey = xFormats->addNew(sFormatDescription, aDescriptionLanguage);
     938           0 :                     }
     939           0 :                 }
     940             :             }
     941           0 :             if ((nVersion == 0x0002) || (nVersion == 0x0003))
     942           0 :                 readCommonEditProperties(_rxInStream);
     943             : 
     944           0 :             if (nVersion == 0x0003)
     945             :             {   // since version 3 there is a "skippable" block at this position
     946           0 :                 Reference< XDataInputStream > xIn(_rxInStream, UNO_QUERY);
     947           0 :                 OStreamSection aDownCompat(xIn);
     948             : 
     949           0 :                 sal_Int16 nSubVersion = _rxInStream->readShort();
     950             :                 (void)nSubVersion;
     951             : 
     952             :                 // version 0 and higher : the "effective value" property
     953           0 :                 Any aEffectiveValue;
     954             :                 {
     955           0 :                     OStreamSection aDownCompat2(xIn);
     956           0 :                     switch (_rxInStream->readShort())
     957             :                     {
     958             :                         case 0: // String
     959           0 :                             aEffectiveValue <<= _rxInStream->readUTF();
     960           0 :                             break;
     961             :                         case 1: // double
     962           0 :                             aEffectiveValue <<= (double)_rxInStream->readDouble();
     963           0 :                             break;
     964             :                         case 2:
     965           0 :                             break;
     966             :                         case 3:
     967             :                             OSL_FAIL("FmXFormattedModel::read : unknown effective value type !");
     968           0 :                     }
     969             :                 }
     970             : 
     971             :                 // this property is only to be set if we have no control source : in all other cases the base class did a
     972             :                 // reset after it's read and this set the effective value to a default value
     973           0 :                 if ( m_xAggregateSet.is() && getControlSource().isEmpty() )
     974             :                 {
     975             :                     try
     976             :                     {
     977           0 :                         m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue);
     978             :                     }
     979           0 :                     catch(const Exception&)
     980             :                     {
     981             :                     }
     982           0 :                 }
     983             :             }
     984             :         }
     985           0 :         break;
     986             :         default :
     987             :             OSL_FAIL("OFormattedModel::read : unknown version !");
     988             :             // dann bleibt das Format des aggregierten Sets, wie es bei der Erzeugung ist : void
     989           0 :             defaultCommonEditProperties();
     990           0 :             break;
     991             :     }
     992             : 
     993           0 :     if ((nKey != -1) && m_xAggregateSet.is())
     994             :     {
     995           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
     996           0 :                 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey));
     997             :     }
     998             :     else
     999             :     {
    1000           0 :         setPropertyToDefault(PROPERTY_FORMATSSUPPLIER);
    1001           0 :         setPropertyToDefault(PROPERTY_FORMATKEY);
    1002           0 :     }
    1003           0 : }
    1004             : 
    1005             : //------------------------------------------------------------------------------
    1006           0 : sal_uInt16 OFormattedModel::getPersistenceFlags() const
    1007             : {
    1008           0 :     return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS);
    1009             :     // a) we do our own call to writeCommonEditProperties
    1010             : }
    1011             : 
    1012             : //------------------------------------------------------------------------------
    1013           0 : sal_Bool OFormattedModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
    1014             : {
    1015           0 :     Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
    1016           0 :     if ( aControlValue != m_aSaveValue )
    1017             :     {
    1018             :         // Leerstring + EmptyIsNull = void
    1019           0 :         if  (   !aControlValue.hasValue()
    1020           0 :             ||  (   ( aControlValue.getValueType().getTypeClass() == TypeClass_STRING )
    1021           0 :                 &&  getString( aControlValue ).isEmpty()
    1022             :                 &&  m_bEmptyIsNull
    1023             :                 )
    1024             :             )
    1025           0 :             m_xColumnUpdate->updateNull();
    1026             :         else
    1027             :         {
    1028             :             try
    1029             :             {
    1030           0 :                 double f = 0.0;
    1031           0 :                 if ( aControlValue.getValueType().getTypeClass() == TypeClass_DOUBLE || (aControlValue >>= f)) // #i110323
    1032             :                 {
    1033           0 :                     DBTypeConversion::setValue( m_xColumnUpdate, m_aNullDate, getDouble( aControlValue ), m_nKeyType );
    1034             :                 }
    1035             :                 else
    1036             :                 {
    1037             :                     DBG_ASSERT( aControlValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::commitControlValueToDbColumn: invalud value type !" );
    1038           0 :                     m_xColumnUpdate->updateString( getString( aControlValue ) );
    1039             :                 }
    1040             :             }
    1041           0 :             catch(const Exception&)
    1042             :             {
    1043           0 :                 return sal_False;
    1044             :             }
    1045             :         }
    1046           0 :         m_aSaveValue = aControlValue;
    1047             :     }
    1048           0 :     return sal_True;
    1049             : }
    1050             : 
    1051             : //------------------------------------------------------------------------------
    1052           0 : void OFormattedModel::onConnectedExternalValue( )
    1053             : {
    1054           0 :     OEditBaseModel::onConnectedExternalValue();
    1055           0 :     updateFormatterNullDate();
    1056           0 : }
    1057             : 
    1058             : //------------------------------------------------------------------------------
    1059           0 : Any OFormattedModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
    1060             : {
    1061           0 :     Any aControlValue;
    1062           0 :     switch( _rExternalValue.getValueTypeClass() )
    1063             :     {
    1064             :     case TypeClass_VOID:
    1065           0 :         break;
    1066             : 
    1067             :     case TypeClass_STRING:
    1068           0 :         aControlValue = _rExternalValue;
    1069           0 :         break;
    1070             : 
    1071             :     case TypeClass_BOOLEAN:
    1072             :     {
    1073           0 :         sal_Bool bExternalValue = sal_False;
    1074           0 :         _rExternalValue >>= bExternalValue;
    1075           0 :         aControlValue <<= (double)( bExternalValue ? 1 : 0 );
    1076             :     }
    1077           0 :     break;
    1078             : 
    1079             :     default:
    1080             :     {
    1081           0 :         if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) )
    1082             :         {
    1083           0 :             UNODate aDate;
    1084           0 :             _rExternalValue >>= aDate;
    1085           0 :             aControlValue <<= DBTypeConversion::toDouble( aDate, m_aNullDate );
    1086             :         }
    1087           0 :         else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) )
    1088             :         {
    1089           0 :             UNOTime aTime;
    1090           0 :             _rExternalValue >>= aTime;
    1091           0 :             aControlValue <<= DBTypeConversion::toDouble( aTime );
    1092             :         }
    1093           0 :         else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) )
    1094             :         {
    1095           0 :             UNODateTime aDateTime;
    1096           0 :             _rExternalValue >>= aDateTime;
    1097           0 :             aControlValue <<= DBTypeConversion::toDouble( aDateTime, m_aNullDate );
    1098             :         }
    1099             :         else
    1100             :         {
    1101             :             OSL_ENSURE( _rExternalValue.getValueTypeClass() == TypeClass_DOUBLE,
    1102             :                 "OFormattedModel::translateExternalValueToControlValue: don't know how to translate this type!" );
    1103           0 :             double fValue = 0;
    1104           0 :             OSL_VERIFY( _rExternalValue >>= fValue );
    1105           0 :             aControlValue <<= fValue;
    1106             :         }
    1107             :     }
    1108             :     }
    1109             : 
    1110           0 :     return aControlValue;
    1111             : }
    1112             : 
    1113             : //------------------------------------------------------------------------------
    1114           0 : Any OFormattedModel::translateControlValueToExternalValue( ) const
    1115             : {
    1116             :     OSL_PRECOND( hasExternalValueBinding(),
    1117             :         "OFormattedModel::translateControlValueToExternalValue: precondition not met!" );
    1118             : 
    1119           0 :     Any aControlValue( getControlValue() );
    1120           0 :     if ( !aControlValue.hasValue() )
    1121           0 :         return aControlValue;
    1122             : 
    1123           0 :     Any aExternalValue;
    1124             : 
    1125             :     // translate into the the external value type
    1126           0 :     Type aExternalValueType( getExternalValueType() );
    1127           0 :     switch ( aExternalValueType.getTypeClass() )
    1128             :     {
    1129             :     case TypeClass_STRING:
    1130             :     {
    1131           0 :         ::rtl::OUString sString;
    1132           0 :         if ( aControlValue >>= sString )
    1133             :         {
    1134           0 :             aExternalValue <<= sString;
    1135             :             break;
    1136           0 :         }
    1137             :     }
    1138             :     // NO break here!
    1139             : 
    1140             :     case TypeClass_BOOLEAN:
    1141             :     {
    1142           0 :         double fValue = 0;
    1143           0 :         OSL_VERIFY( aControlValue >>= fValue );
    1144             :             // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
    1145             :             // and the control value is a string. This implies some weird misconfiguration
    1146             :             // of the FormattedModel, so we won't care for it for the moment.
    1147           0 :         aExternalValue <<= (sal_Bool)( fValue ? sal_True : sal_False );
    1148             :     }
    1149           0 :     break;
    1150             : 
    1151             :     default:
    1152             :     {
    1153           0 :         double fValue = 0;
    1154           0 :         OSL_VERIFY( aControlValue >>= fValue );
    1155             :             // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
    1156             :             // and the control value is a string. This implies some weird misconfiguration
    1157             :             // of the FormattedModel, so we won't care for it for the moment.
    1158             : 
    1159           0 :         if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) )
    1160             :         {
    1161           0 :             aExternalValue <<= DBTypeConversion::toDate( fValue, m_aNullDate );
    1162             :         }
    1163           0 :         else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) )
    1164             :         {
    1165           0 :             aExternalValue <<= DBTypeConversion::toTime( fValue );
    1166             :         }
    1167           0 :         else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) )
    1168             :         {
    1169           0 :             aExternalValue <<= DBTypeConversion::toDateTime( fValue, m_aNullDate );
    1170             :         }
    1171             :         else
    1172             :         {
    1173             :             OSL_ENSURE( aExternalValueType.equals( ::getCppuType( static_cast< double* >( NULL ) ) ),
    1174             :                 "OFormattedModel::translateControlValueToExternalValue: don't know how to translate this type!" );
    1175           0 :             aExternalValue <<= fValue;
    1176             :         }
    1177             :     }
    1178           0 :     break;
    1179             :     }
    1180           0 :     return aExternalValue;
    1181             : }
    1182             : 
    1183             : //------------------------------------------------------------------------------
    1184           0 : Any OFormattedModel::translateDbColumnToControlValue()
    1185             : {
    1186           0 :     if ( m_bNumeric )
    1187           0 :         m_aSaveValue <<= DBTypeConversion::getValue( m_xColumn, m_aNullDate ); // #100056# OJ
    1188             :     else
    1189           0 :         m_aSaveValue <<= m_xColumn->getString();
    1190             : 
    1191           0 :     if ( m_xColumn->wasNull() )
    1192           0 :         m_aSaveValue.clear();
    1193             : 
    1194           0 :     return m_aSaveValue;
    1195             : }
    1196             : 
    1197             : // -----------------------------------------------------------------------------
    1198           0 : Sequence< Type > OFormattedModel::getSupportedBindingTypes()
    1199             : {
    1200           0 :     ::std::list< Type > aTypes;
    1201           0 :     aTypes.push_back( ::getCppuType( static_cast< double* >( NULL ) ) );
    1202             : 
    1203           0 :     switch ( m_nKeyType & ~NumberFormat::DEFINED )
    1204             :     {
    1205             :     case NumberFormat::DATE:
    1206           0 :         aTypes.push_front(::getCppuType( static_cast< UNODate* >( NULL ) ) );
    1207           0 :         break;
    1208             :     case NumberFormat::TIME:
    1209           0 :         aTypes.push_front(::getCppuType( static_cast< UNOTime* >( NULL ) ) );
    1210           0 :         break;
    1211             :     case NumberFormat::DATETIME:
    1212           0 :         aTypes.push_front(::getCppuType( static_cast< UNODateTime* >( NULL ) ) );
    1213           0 :         break;
    1214             :     case NumberFormat::TEXT:
    1215           0 :         aTypes.push_front(::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) );
    1216           0 :         break;
    1217             :     case NumberFormat::LOGICAL:
    1218           0 :         aTypes.push_front(::getCppuType( static_cast< sal_Bool* >( NULL ) ) );
    1219           0 :         break;
    1220             :     }
    1221             : 
    1222           0 :     Sequence< Type > aTypesRet( aTypes.size() );
    1223           0 :     ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() );
    1224           0 :     return aTypesRet;
    1225             : }
    1226             : 
    1227             : //------------------------------------------------------------------------------
    1228           0 : Any OFormattedModel::getDefaultForReset() const
    1229             : {
    1230           0 :     return m_xAggregateSet->getPropertyValue( PROPERTY_EFFECTIVE_DEFAULT );
    1231             : }
    1232             : 
    1233             : //------------------------------------------------------------------------------
    1234           0 : void OFormattedModel::resetNoBroadcast()
    1235             : {
    1236           0 :     OEditBaseModel::resetNoBroadcast();
    1237           0 :     m_aSaveValue.clear();
    1238           0 : }
    1239             : 
    1240             : //.........................................................................
    1241          15 : }
    1242             : //.........................................................................
    1243             : 
    1244             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10