LCOV - code coverage report
Current view: top level - libreoffice/forms/source/component - Edit.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 88 310 28.4 %
Date: 2012-12-27 Functions: 19 46 41.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 "Edit.hxx"
      22             : 
      23             : #include <com/sun/star/uno/Type.hxx>
      24             : #include <com/sun/star/awt/XWindow.hpp>
      25             : #include <com/sun/star/container/XIndexAccess.hpp>
      26             : #include <com/sun/star/form/XSubmit.hpp>
      27             : #include <com/sun/star/util/NumberFormat.hpp>
      28             : #include <com/sun/star/sdbc/DataType.hpp>
      29             : #include <com/sun/star/awt/XVclWindowPeer.hpp>
      30             : 
      31             : #include <vcl/svapp.hxx>
      32             : #include <tools/wintypes.hxx>
      33             : 
      34             : #include <connectivity/dbtools.hxx>
      35             : #include <connectivity/formattedcolumnvalue.hxx>
      36             : #include <connectivity/dbconversion.hxx>
      37             : 
      38             : #include <tools/diagnose_ex.h>
      39             : #include <tools/debug.hxx>
      40             : 
      41             : #include <comphelper/container.hxx>
      42             : #include <comphelper/numbers.hxx>
      43             : 
      44             : using namespace dbtools;
      45             : 
      46             : //.........................................................................
      47             : namespace frm
      48             : {
      49             : using namespace ::com::sun::star::uno;
      50             : using namespace ::com::sun::star::sdb;
      51             : using namespace ::com::sun::star::sdbc;
      52             : using namespace ::com::sun::star::sdbcx;
      53             : using namespace ::com::sun::star::beans;
      54             : using namespace ::com::sun::star::container;
      55             : using namespace ::com::sun::star::form;
      56             : using namespace ::com::sun::star::awt;
      57             : using namespace ::com::sun::star::io;
      58             : using namespace ::com::sun::star::lang;
      59             : using namespace ::com::sun::star::util;
      60             : using namespace ::com::sun::star::form::binding;
      61             : 
      62             : //------------------------------------------------------------------
      63           3 : InterfaceRef SAL_CALL OEditControl_CreateInstance(const Reference< XMultiServiceFactory > & _rxFactory)
      64             : {
      65           3 :     return *(new OEditControl(_rxFactory));
      66             : }
      67             : 
      68             : //------------------------------------------------------------------------------
      69           0 : Sequence<Type> OEditControl::_getTypes()
      70             : {
      71           0 :     static Sequence<Type> aTypes;
      72           0 :     if (!aTypes.getLength())
      73             :     {
      74             :         // my two base classes
      75           0 :         aTypes = concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes());
      76             :     }
      77           0 :     return aTypes;
      78             : }
      79             : 
      80             : //------------------------------------------------------------------------------
      81          76 : Any SAL_CALL OEditControl::queryAggregation(const Type& _rType) throw (RuntimeException)
      82             : {
      83          76 :     Any aReturn = OBoundControl::queryAggregation(_rType);
      84          76 :     if (!aReturn.hasValue())
      85           7 :         aReturn = OEditControl_BASE::queryInterface(_rType);
      86             : 
      87          76 :     return aReturn;
      88             : }
      89             : 
      90             : DBG_NAME(OEditControl);
      91             : //------------------------------------------------------------------------------
      92           3 : OEditControl::OEditControl(const Reference<XMultiServiceFactory>& _rxFactory)
      93             :                :OBoundControl( _rxFactory, FRM_SUN_CONTROL_RICHTEXTCONTROL )
      94             :                ,m_aChangeListeners(m_aMutex)
      95           3 :                ,m_nKeyEvent( 0 )
      96             : {
      97             :     DBG_CTOR(OEditControl,NULL);
      98             : 
      99           3 :     increment(m_refCount);
     100             :     {
     101           3 :         Reference<XWindow>  xComp;
     102           3 :         if (query_aggregation(m_xAggregate, xComp))
     103             :         {
     104           3 :             xComp->addFocusListener(this);
     105           3 :             xComp->addKeyListener(this);
     106           3 :         }
     107             :     }
     108           3 :     decrement(m_refCount);
     109           3 : }
     110             : 
     111             : //------------------------------------------------------------------------------
     112           6 : OEditControl::~OEditControl()
     113             : {
     114           2 :     if( m_nKeyEvent )
     115           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     116             : 
     117           2 :     if (!OComponentHelper::rBHelper.bDisposed)
     118             :     {
     119           0 :         acquire();
     120           0 :         dispose();
     121             :     }
     122             : 
     123             :     DBG_DTOR(OEditControl,NULL);
     124           4 : }
     125             : 
     126             : // XChangeBroadcaster
     127             : //------------------------------------------------------------------------------
     128           0 : void OEditControl::addChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
     129             : {
     130           0 :     m_aChangeListeners.addInterface( l );
     131           0 : }
     132             : 
     133             : //------------------------------------------------------------------------------
     134           0 : void OEditControl::removeChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
     135             : {
     136           0 :     m_aChangeListeners.removeInterface( l );
     137           0 : }
     138             : 
     139             : // OComponentHelper
     140             : //------------------------------------------------------------------------------
     141           2 : void OEditControl::disposing()
     142             : {
     143           2 :     OBoundControl::disposing();
     144             : 
     145           2 :     EventObject aEvt(static_cast<XWeak*>(this));
     146           2 :     m_aChangeListeners.disposeAndClear(aEvt);
     147           2 : }
     148             : 
     149             : // XServiceInfo
     150             : //------------------------------------------------------------------------------
     151           0 : StringSequence  OEditControl::getSupportedServiceNames() throw()
     152             : {
     153           0 :     StringSequence aSupported = OBoundControl::getSupportedServiceNames();
     154           0 :     aSupported.realloc(aSupported.getLength() + 1);
     155             : 
     156           0 :     ::rtl::OUString*pArray = aSupported.getArray();
     157           0 :     pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_TEXTFIELD;
     158           0 :     return aSupported;
     159             : }
     160             : 
     161             : // XEventListener
     162             : //------------------------------------------------------------------------------
     163           6 : void OEditControl::disposing(const EventObject& Source) throw( RuntimeException )
     164             : {
     165           6 :     OBoundControl::disposing(Source);
     166           6 : }
     167             : 
     168             : // XFocusListener
     169             : //------------------------------------------------------------------------------
     170           0 : void OEditControl::focusGained( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
     171             : {
     172           0 :     Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
     173           0 :     if (xSet.is())
     174           0 :         xSet->getPropertyValue( PROPERTY_TEXT ) >>= m_aHtmlChangeValue;
     175           0 : }
     176             : 
     177             : //------------------------------------------------------------------------------
     178           0 : void OEditControl::focusLost( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
     179             : {
     180           0 :     Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
     181           0 :     if (xSet.is())
     182             :     {
     183           0 :         ::rtl::OUString sNewHtmlChangeValue;
     184           0 :         xSet->getPropertyValue( PROPERTY_TEXT ) >>= sNewHtmlChangeValue;
     185           0 :         if( sNewHtmlChangeValue != m_aHtmlChangeValue )
     186             :         {
     187           0 :             EventObject aEvt( *this );
     188           0 :             m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvt );
     189           0 :         }
     190           0 :     }
     191           0 : }
     192             : 
     193             : // XKeyListener
     194             : //------------------------------------------------------------------------------
     195           0 : void OEditControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
     196             : {
     197           0 :     if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
     198             :         return;
     199             : 
     200             :     // Is the Control in a form with a submit URL?
     201           0 :     Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
     202           0 :     if( !xSet.is() )
     203             :         return;
     204             : 
     205             :     // Not for  multiline edits
     206           0 :     Any aTmp( xSet->getPropertyValue(PROPERTY_MULTILINE));
     207           0 :     if ((aTmp.getValueType().equals(::getBooleanCppuType())) && getBOOL(aTmp))
     208             :         return;
     209             : 
     210           0 :     Reference<XFormComponent>  xFComp(xSet, UNO_QUERY);
     211           0 :     InterfaceRef  xParent = xFComp->getParent();
     212           0 :     if( !xParent.is() )
     213             :         return;
     214             : 
     215           0 :     Reference<XPropertySet>  xFormSet(xParent, UNO_QUERY);
     216           0 :     if( !xFormSet.is() )
     217             :         return;
     218             : 
     219           0 :     aTmp = xFormSet->getPropertyValue( PROPERTY_TARGET_URL );
     220           0 :     if (!aTmp.getValueType().equals(::getCppuType((const ::rtl::OUString*)NULL)) ||
     221           0 :         getString(aTmp).isEmpty() )
     222             :         return;
     223             : 
     224           0 :     Reference<XIndexAccess>  xElements(xParent, UNO_QUERY);
     225           0 :     sal_Int32 nCount = xElements->getCount();
     226           0 :     if( nCount > 1 )
     227             :     {
     228           0 :         Reference<XPropertySet>  xFCSet;
     229           0 :         for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
     230             :         {
     231             :             //  Any aElement(xElements->getByIndex(nIndex));
     232           0 :             xElements->getByIndex(nIndex) >>= xFCSet;
     233             :             OSL_ENSURE(xFCSet.is(),"OEditControl::keyPressed: No XPropertySet!");
     234             : 
     235           0 :             if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
     236           0 :                 getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
     237             :             {
     238             :                 // Found another Edit -> then do not submit!
     239           0 :                 if (xFCSet != xSet)
     240             :                     return;
     241             :             }
     242           0 :         }
     243             :     }
     244             : 
     245             :     // Because we're still in the header, trigger submit asynchronously
     246           0 :     if( m_nKeyEvent )
     247           0 :         Application::RemoveUserEvent( m_nKeyEvent );
     248           0 :     m_nKeyEvent = Application::PostUserEvent( LINK(this, OEditControl,OnKeyPressed) );
     249             : }
     250             : 
     251             : //------------------------------------------------------------------------------
     252           0 : void OEditControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException)
     253             : {
     254           0 : }
     255             : 
     256             : //------------------------------------------------------------------------------
     257           0 : IMPL_LINK(OEditControl, OnKeyPressed, void*, /*EMPTYARG*/)
     258             : {
     259           0 :     m_nKeyEvent = 0;
     260             : 
     261           0 :     Reference<XFormComponent>  xFComp(getModel(), UNO_QUERY);
     262           0 :     InterfaceRef  xParent = xFComp->getParent();
     263           0 :     Reference<XSubmit>  xSubmit(xParent, UNO_QUERY);
     264           0 :     if (xSubmit.is())
     265           0 :         xSubmit->submit( Reference<XControl>(), ::com::sun::star::awt::MouseEvent() );
     266           0 :     return 0L;
     267             : }
     268             : 
     269             : //------------------------------------------------------------------
     270           3 : void SAL_CALL OEditControl::createPeer( const Reference< XToolkit>& _rxToolkit, const Reference< XWindowPeer>& _rxParent ) throw ( RuntimeException )
     271             : {
     272           3 :     OBoundControl::createPeer(_rxToolkit, _rxParent);
     273           3 : }
     274             : 
     275             : /*************************************************************************/
     276             : //------------------------------------------------------------------
     277           2 : InterfaceRef SAL_CALL OEditModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
     278             : {
     279           2 :     return *(new OEditModel(_rxFactory));
     280             : }
     281             : 
     282             : //------------------------------------------------------------------------------
     283           0 : Sequence<Type> OEditModel::_getTypes()
     284             : {
     285           0 :     return OEditBaseModel::_getTypes();
     286             : }
     287             : 
     288             : 
     289             : DBG_NAME(OEditModel);
     290             : //------------------------------------------------------------------
     291           2 : OEditModel::OEditModel(const Reference<XMultiServiceFactory>& _rxFactory)
     292             :     :OEditBaseModel( _rxFactory, FRM_SUN_COMPONENT_RICHTEXTCONTROL, FRM_SUN_CONTROL_TEXTFIELD, sal_True, sal_True )
     293             :     ,m_bMaxTextLenModified(sal_False)
     294           2 :     ,m_bWritingFormattedFake(sal_False)
     295             : {
     296             :     DBG_CTOR(OEditModel,NULL);
     297             : 
     298           2 :     m_nClassId = FormComponentType::TEXTFIELD;
     299           2 :     initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
     300           2 : }
     301             : 
     302             : //------------------------------------------------------------------
     303           0 : OEditModel::OEditModel( const OEditModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
     304             :     :OEditBaseModel( _pOriginal, _rxFactory )
     305             :     ,m_bMaxTextLenModified(sal_False)
     306           0 :     ,m_bWritingFormattedFake(sal_False)
     307             : {
     308             :     DBG_CTOR( OEditModel, NULL );
     309             : 
     310             :     // Note that most of the properties are not clone from the original object:
     311             :     // Things as the format key, it's type, and such, depend on the field being part of a loaded form
     312             :     // (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself
     313             :     // certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded,
     314             :     // they will be set to new values, anyway ....
     315           0 : }
     316             : 
     317             : //------------------------------------------------------------------
     318           3 : OEditModel::~OEditModel()
     319             : {
     320           1 :     if (!OComponentHelper::rBHelper.bDisposed)
     321             :     {
     322           0 :         acquire();
     323           0 :         dispose();
     324             :     }
     325             : 
     326             :     DBG_DTOR(OEditModel,NULL);
     327           2 : }
     328             : 
     329             : //------------------------------------------------------------------------------
     330           0 : IMPLEMENT_DEFAULT_CLONING( OEditModel )
     331             : 
     332             : //------------------------------------------------------------------------------
     333           1 : void OEditModel::disposing()
     334             : {
     335           1 :     OEditBaseModel::disposing();
     336           1 :     m_pValueFormatter.reset();
     337           1 : }
     338             : 
     339             : // XPersistObject
     340             : //------------------------------------------------------------------------------
     341           0 : ::rtl::OUString SAL_CALL OEditModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
     342             : {
     343           0 :     return FRM_COMPONENT_EDIT;  // old (non-sun) name for compatibility !
     344             : }
     345             : 
     346             : // XServiceInfo
     347             : //------------------------------------------------------------------------------
     348           1 : StringSequence SAL_CALL OEditModel::getSupportedServiceNames() throw()
     349             : {
     350           1 :     StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
     351             : 
     352           1 :     sal_Int32 nOldLen = aSupported.getLength();
     353           1 :     aSupported.realloc( nOldLen + 8 );
     354           1 :     ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
     355             : 
     356           1 :     *pStoreTo++ = BINDABLE_CONTROL_MODEL;
     357           1 :     *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
     358           1 :     *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
     359             : 
     360           1 :     *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
     361           1 :     *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
     362             : 
     363           1 :     *pStoreTo++ = FRM_SUN_COMPONENT_TEXTFIELD;
     364           1 :     *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD;
     365           1 :     *pStoreTo++ = BINDABLE_DATABASE_TEXT_FIELD;
     366             : 
     367           1 :     return aSupported;
     368             : }
     369             : 
     370             : // XPropertySet
     371         399 : void SAL_CALL OEditModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
     372             : {
     373         399 :     if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH == nHandle )
     374             :     {
     375           3 :         if ( m_bMaxTextLenModified )
     376           0 :             rValue <<= sal_Int16(0);
     377           3 :         else if ( m_xAggregateSet.is() )
     378           3 :             rValue = m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN);
     379             :     }
     380             :     else
     381             :     {
     382         396 :         OEditBaseModel::getFastPropertyValue(rValue, nHandle );
     383             :     }
     384         399 : }
     385             : 
     386             : //------------------------------------------------------------------------------
     387           2 : void OEditModel::describeFixedProperties( Sequence< Property >& _rProps ) const
     388             : {
     389           2 :     BEGIN_DESCRIBE_PROPERTIES( 5, OEditBaseModel )
     390           2 :         DECL_PROP2(PERSISTENCE_MAXTEXTLENGTH,sal_Int16,         READONLY, TRANSIENT);
     391           2 :         DECL_PROP2(DEFAULT_TEXT,        ::rtl::OUString,        BOUND, MAYBEDEFAULT);
     392           2 :         DECL_BOOL_PROP1(EMPTY_IS_NULL,                          BOUND);
     393           2 :         DECL_PROP1(TABINDEX,            sal_Int16,              BOUND);
     394           2 :         DECL_BOOL_PROP2(FILTERPROPOSAL,                         BOUND, MAYBEDEFAULT);
     395             :     END_DESCRIBE_PROPERTIES();
     396           2 : }
     397             : 
     398             : //------------------------------------------------------------------------------
     399           2 : void OEditModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
     400             : {
     401           2 :     OEditBaseModel::describeAggregateProperties( _rAggregateProps );
     402             : 
     403             :     // our aggregate is a rich text model, which also derives from OControlModel, as
     404             :     // do we, so we need to remove some duplicate properties
     405           2 :     RemoveProperty( _rAggregateProps, PROPERTY_TABINDEX );
     406           2 :     RemoveProperty( _rAggregateProps, PROPERTY_CLASSID );
     407           2 :     RemoveProperty( _rAggregateProps, PROPERTY_NAME );
     408           2 :     RemoveProperty( _rAggregateProps, PROPERTY_TAG );
     409           2 :     RemoveProperty( _rAggregateProps, PROPERTY_NATIVE_LOOK );
     410             : 
     411           2 : }
     412             : 
     413             : //------------------------------------------------------------------------------
     414           0 : bool OEditModel::implActsAsRichText( ) const
     415             : {
     416           0 :     sal_Bool bActAsRichText = sal_False;
     417           0 :     if ( m_xAggregateSet.is() )
     418             :     {
     419           0 :         OSL_VERIFY( m_xAggregateSet->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActAsRichText );
     420             :     }
     421           0 :     return bActAsRichText;
     422             : }
     423             : 
     424             : //------------------------------------------------------------------------------
     425           0 : void SAL_CALL OEditModel::reset(  ) throw(RuntimeException)
     426             : {
     427             :     // no reset if we currently act as rich text control
     428           0 :     if ( implActsAsRichText() )
     429           0 :         return;
     430             : 
     431           0 :     OEditBaseModel::reset();
     432             : }
     433             : 
     434             : //------------------------------------------------------------------------------
     435             : namespace
     436             : {
     437           0 :     void lcl_transferProperties( const Reference< XPropertySet >& _rxSource, const Reference< XPropertySet >& _rxDest )
     438             :     {
     439             :         try
     440             :         {
     441           0 :             Reference< XPropertySetInfo > xSourceInfo;
     442           0 :             if ( _rxSource.is() )
     443           0 :                 xSourceInfo = _rxSource->getPropertySetInfo();
     444             : 
     445           0 :             Reference< XPropertySetInfo > xDestInfo;
     446           0 :             if ( _rxDest.is() )
     447           0 :                 xDestInfo = _rxDest->getPropertySetInfo();
     448             : 
     449           0 :             if ( !xSourceInfo.is() || !xDestInfo.is() )
     450             :             {
     451             :                 OSL_FAIL( "lcl_transferProperties: invalid property set(s)!" );
     452           0 :                 return;
     453             :             }
     454             : 
     455           0 :             Sequence< Property > aSourceProps( xSourceInfo->getProperties() );
     456           0 :             const Property* pSourceProps = aSourceProps.getConstArray();
     457           0 :             const Property* pSourcePropsEnd = aSourceProps.getConstArray() + aSourceProps.getLength();
     458           0 :             while ( pSourceProps != pSourcePropsEnd )
     459             :             {
     460           0 :                 if ( !xDestInfo->hasPropertyByName( pSourceProps->Name ) )
     461             :                 {
     462           0 :                     ++pSourceProps;
     463           0 :                     continue;
     464             :                 }
     465             : 
     466           0 :                 Property aDestProp( xDestInfo->getPropertyByName( pSourceProps->Name ) );
     467           0 :                 if ( 0 != ( aDestProp.Attributes & PropertyAttribute::READONLY ) )
     468             :                 {
     469           0 :                     ++pSourceProps;
     470           0 :                     continue;
     471             :                 }
     472             : 
     473             :                 try
     474             :                 {
     475           0 :                     _rxDest->setPropertyValue( pSourceProps->Name, _rxSource->getPropertyValue( pSourceProps->Name ) );
     476             :                 }
     477           0 :                 catch(const IllegalArgumentException& e)
     478             :                 {
     479             : #if OSL_DEBUG_LEVEL > 0
     480             :                     ::rtl::OString sMessage( "could not transfer the property named '" );
     481             :                     sMessage += ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US );
     482             :                     sMessage += ::rtl::OString( "'." );
     483             :                     if ( !e.Message.isEmpty() )
     484             :                     {
     485             :                         sMessage += ::rtl::OString( "\n\nMessage:\n" );
     486             :                         sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US );
     487             :                     }
     488             :                     OSL_FAIL( sMessage.getStr() );
     489             : #else
     490             :                     (void)e;
     491             : #endif
     492             :                 }
     493             : 
     494           0 :                 ++pSourceProps;
     495           0 :             }
     496             :         }
     497           0 :         catch( const Exception& )
     498             :         {
     499             :             DBG_UNHANDLED_EXCEPTION();
     500             :         }
     501             :     }
     502             : }
     503             : 
     504             : //------------------------------------------------------------------------------
     505           0 : void OEditModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
     506             : {
     507             :     // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate,
     508             :     // but for compatibility, we need to use an "old" aggregate for writing and reading
     509             : 
     510             :     Reference< XPropertySet > xFakedAggregate(
     511           0 :         getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
     512             :         UNO_QUERY
     513           0 :     );
     514             :     OSL_ENSURE( xFakedAggregate.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" );
     515           0 :     if ( !xFakedAggregate.is() )
     516           0 :         return;
     517             : 
     518           0 :     lcl_transferProperties( m_xAggregateSet, xFakedAggregate );
     519             : 
     520           0 :     Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
     521             :     OSL_ENSURE( xFakedPersist.is(), "OEditModel::writeAggregate: no XPersistObject!" );
     522           0 :     if ( xFakedPersist.is() )
     523           0 :         xFakedPersist->write( _rxOutStream );
     524             : }
     525             : 
     526             : //------------------------------------------------------------------------------
     527           0 : void OEditModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
     528             : {
     529             :     // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate,
     530             :     // but for compatibility, we need to use an "old" aggregate for writing and reading
     531             : 
     532             :     Reference< XPropertySet > xFakedAggregate(
     533           0 :         getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
     534             :         UNO_QUERY
     535           0 :     );
     536           0 :     Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
     537             :     OSL_ENSURE( xFakedPersist.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" );
     538           0 :     if ( xFakedPersist.is() )
     539             :     {
     540           0 :         xFakedPersist->read( _rxInStream );
     541           0 :         lcl_transferProperties( xFakedAggregate, m_xAggregateSet );
     542           0 :     }
     543           0 : }
     544             : 
     545             : //------------------------------------------------------------------------------
     546           0 : void OEditModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
     547             : {
     548           0 :     Any aCurrentText;
     549           0 :     sal_Int16 nOldTextLen = 0;
     550             :     // Am I loaded at the moment and did I switch MaxTextLen temporarily?
     551           0 :     if ( m_bMaxTextLenModified )
     552             :     {   // -> for the duration of saving, make my aggregated model believe the old TextLen
     553             : 
     554             :         // before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len
     555           0 :         aCurrentText = m_xAggregateSet->getPropertyValue(PROPERTY_TEXT);
     556             : 
     557           0 :         m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN) >>= nOldTextLen;
     558           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny((sal_Int16)0));
     559             :     }
     560             : 
     561           0 :     OEditBaseModel::write(_rxOutStream);
     562             : 
     563           0 :     if ( m_bMaxTextLenModified )
     564             :     {   // Reset again
     565           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny(nOldTextLen));
     566             :         // and reset the text
     567             :         // First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks
     568             :         // we aren't changing the prop (it didn't notify the - implicite - change of the text prop while setting the max text len)
     569             :         // This seems to be a bug with in toolkit's EditControl-implementation.
     570           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, makeAny(::rtl::OUString()));
     571           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, aCurrentText);
     572           0 :     }
     573           0 : }
     574             : 
     575             : //------------------------------------------------------------------------------
     576           0 : void OEditModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
     577             : {
     578           0 :     OEditBaseModel::read(_rxInStream);
     579             : 
     580             :     // Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown
     581             :     // to older versions (5.0).
     582             :     // correct this ...
     583           0 :     if (m_xAggregateSet.is())
     584             :     {
     585           0 :         Any aDefaultControl = m_xAggregateSet->getPropertyValue(PROPERTY_DEFAULTCONTROL);
     586           0 :         if  (   (aDefaultControl.getValueType().getTypeClass() == TypeClass_STRING)
     587           0 :             &&  (getString(aDefaultControl).compareTo(STARDIV_ONE_FORM_CONTROL_TEXTFIELD) == COMPARE_EQUAL)
     588             :             )
     589             :         {
     590           0 :             m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( (::rtl::OUString)STARDIV_ONE_FORM_CONTROL_EDIT ) );
     591             :             // Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT,
     592             :             // the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD.
     593           0 :         }
     594             :     }
     595           0 : }
     596             : 
     597             : //------------------------------------------------------------------------------
     598           0 : sal_uInt16 OEditModel::getPersistenceFlags() const
     599             : {
     600           0 :     sal_uInt16 nFlags = OEditBaseModel::getPersistenceFlags();
     601             : 
     602           0 :     if (m_bWritingFormattedFake)
     603           0 :         nFlags |= PF_FAKE_FORMATTED_FIELD;
     604             : 
     605           0 :     return nFlags;
     606             : }
     607             : 
     608             : //------------------------------------------------------------------------------
     609           0 : void OEditModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
     610             : {
     611           0 :     Reference< XPropertySet > xField = getField();
     612           0 :     if ( xField.is() )
     613             :     {
     614           0 :         m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
     615             : 
     616           0 :         if ( m_pValueFormatter->getKeyType() != NumberFormat::SCIENTIFIC )
     617             :         {
     618           0 :             m_bMaxTextLenModified = getINT16(m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN)) != 0;
     619           0 :             if ( !m_bMaxTextLenModified )
     620             :             {
     621           0 :                 sal_Int32 nFieldLen = 0;
     622           0 :                 xField->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Precision") ) ) >>= nFieldLen;
     623             : 
     624           0 :                 if (nFieldLen && nFieldLen <= USHRT_MAX)
     625             :                 {
     626           0 :                     Any aVal;
     627           0 :                     aVal <<= (sal_Int16)nFieldLen;
     628           0 :                     m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
     629             : 
     630           0 :                     m_bMaxTextLenModified = sal_True;
     631             :                 }
     632             :             }
     633             :             else
     634           0 :                 m_bMaxTextLenModified = sal_False; // to get sure that the text len won't be set in unloaded
     635             :         }
     636           0 :     }
     637           0 : }
     638             : 
     639             : //------------------------------------------------------------------------------
     640           0 : void OEditModel::onDisconnectedDbColumn()
     641             : {
     642           0 :     OEditBaseModel::onDisconnectedDbColumn();
     643             : 
     644           0 :     m_pValueFormatter.reset();
     645             : 
     646           0 :     if ( hasField() && m_bMaxTextLenModified )
     647             :     {
     648           0 :         Any aVal;
     649           0 :         aVal <<= (sal_Int16)0;  // Only if it was 0, I switched it in onConnectedDbColumn
     650           0 :         m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
     651           0 :         m_bMaxTextLenModified = sal_False;
     652             :     }
     653           0 : }
     654             : 
     655             : //------------------------------------------------------------------------------
     656           0 : sal_Bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType )
     657             : {
     658             :     // if we act as rich text currently, we do not allow binding to a database column
     659           0 :     if ( implActsAsRichText() )
     660           0 :         return sal_False;
     661             : 
     662           0 :     return OEditBaseModel::approveDbColumnType( _nColumnType );
     663             : }
     664             : 
     665             : //------------------------------------------------------------------------------
     666           1 : void OEditModel::resetNoBroadcast()
     667             : {
     668           1 :     OEditBaseModel::resetNoBroadcast();
     669           1 : }
     670             : 
     671             : //------------------------------------------------------------------------------
     672           0 : sal_Bool OEditModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
     673             : {
     674           0 :     Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
     675             : 
     676           0 :     ::rtl::OUString sNewValue;
     677           0 :     aNewValue >>= sNewValue;
     678             : 
     679           0 :     if  (   !aNewValue.hasValue()
     680           0 :         ||  (   sNewValue.isEmpty()         // an empty string
     681             :             &&  m_bEmptyIsNull              // which should be interpreted as NULL
     682             :             )
     683             :         )
     684             :     {
     685           0 :         m_xColumnUpdate->updateNull();
     686             :     }
     687             :     else
     688             :     {
     689             :         OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::commitControlValueToDbColumn: no value formatter!" );
     690             :         try
     691             :         {
     692           0 :             if ( m_pValueFormatter.get() )
     693             :             {
     694           0 :                 if ( !m_pValueFormatter->setFormattedValue( sNewValue ) )
     695           0 :                     return sal_False;
     696             :             }
     697             :             else
     698           0 :                 m_xColumnUpdate->updateString( sNewValue );
     699             :         }
     700           0 :         catch ( const Exception& )
     701             :         {
     702           0 :             return sal_False;
     703             :         }
     704             :     }
     705             : 
     706           0 :     return sal_True;
     707             : }
     708             : 
     709             : //------------------------------------------------------------------------------
     710           0 : Any OEditModel::translateDbColumnToControlValue()
     711             : {
     712             :     OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::translateDbColumnToControlValue: no value formatter!" );
     713           0 :     Any aRet;
     714           0 :     if ( m_pValueFormatter.get() )
     715             :     {
     716           0 :         ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
     717           0 :         if  (   sValue.isEmpty()
     718           0 :             &&  m_pValueFormatter->getColumn().is()
     719           0 :             &&  m_pValueFormatter->getColumn()->wasNull()
     720             :             )
     721             :         {
     722             :         }
     723             :         else
     724             :         {
     725             :             // #i2817# OJ
     726           0 :             sal_uInt16 nMaxTextLen = getINT16( m_xAggregateSet->getPropertyValue( PROPERTY_MAXTEXTLEN ) );
     727           0 :             if ( nMaxTextLen && sValue.getLength() > nMaxTextLen )
     728             :             {
     729           0 :                 sal_Int32 nDiff = sValue.getLength() - nMaxTextLen;
     730           0 :                 sValue = sValue.replaceAt( nMaxTextLen, nDiff, ::rtl::OUString() );
     731             :             }
     732             : 
     733           0 :             aRet <<= sValue;
     734           0 :         }
     735             :     }
     736             : 
     737           0 :     return aRet.hasValue() ? aRet : makeAny( ::rtl::OUString() );
     738             : }
     739             : 
     740             : //------------------------------------------------------------------------------
     741           1 : Any OEditModel::getDefaultForReset() const
     742             : {
     743           1 :     return makeAny( m_aDefaultText );
     744             : }
     745             : 
     746             : //.........................................................................
     747             : }
     748             : //.........................................................................
     749             : 
     750             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10