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

Generated by: LCOV version 1.10