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

Generated by: LCOV version 1.10