LCOV - code coverage report
Current view: top level - forms/source/xforms - datatypes.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 402 0.0 %
Date: 2014-04-14 Functions: 0 96 0.0 %
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             : #include "datatypes.hxx"
      21             : #include "resourcehelper.hxx"
      22             : #include "property.hrc"
      23             : #include "convert.hxx"
      24             : 
      25             : #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
      26             : #include <tools/datetime.hxx>
      27             : #include <rtl/math.hxx>
      28             : 
      29             : 
      30             : namespace xforms
      31             : {
      32             : 
      33             : 
      34             :     using ::com::sun::star::uno::Reference;
      35             :     using ::com::sun::star::uno::RuntimeException;
      36             :     using ::com::sun::star::uno::Any;
      37             :     using ::com::sun::star::uno::makeAny;
      38             :     using ::com::sun::star::uno::Type;
      39             :     using ::com::sun::star::uno::Sequence;
      40             :     using ::com::sun::star::uno::Exception;
      41             :     using ::com::sun::star::util::VetoException;
      42             :     using ::com::sun::star::util::Date;
      43             :     using ::com::sun::star::util::Time;
      44             :     using ::com::sun::star::util::DateTime;
      45             :     using ::com::sun::star::lang::IllegalArgumentException;
      46             :     using ::com::sun::star::lang::WrappedTargetException;
      47             :     using ::com::sun::star::beans::UnknownPropertyException;
      48             :     using ::com::sun::star::beans::PropertyVetoException;
      49             :     using ::com::sun::star::beans::XPropertyChangeListener;
      50             :     using ::com::sun::star::beans::XVetoableChangeListener;
      51             : 
      52             :     using ::com::sun::star::beans::PropertyAttribute::BOUND;
      53             :     using ::com::sun::star::beans::PropertyAttribute::READONLY;
      54             : 
      55             :     using namespace ::com::sun::star::xsd;
      56             :     using namespace ::frm;
      57             :     U_NAMESPACE_USE
      58             : 
      59             : 
      60             :     //= OXSDDataType
      61             : 
      62             : 
      63           0 :     OXSDDataType::OXSDDataType( const OUString& _rName, sal_Int16 _nTypeClass )
      64             :         :OXSDDataType_PBase( m_aBHelper )
      65             :         ,m_bIsBasic( sal_True )
      66             :         ,m_nTypeClass( _nTypeClass )
      67             :         ,m_sName( _rName )
      68             :         ,m_nWST( WhiteSpaceTreatment::Preserve )
      69           0 :         ,m_bPatternMatcherDirty( true )
      70             :     {
      71           0 :     }
      72             : 
      73             : 
      74           0 :     OXSDDataType::~OXSDDataType()
      75             :     {
      76           0 :     }
      77             : 
      78             : 
      79           0 :     void OXSDDataType::registerProperties()
      80             :     {
      81           0 :         registerProperty( PROPERTY_NAME,            PROPERTY_ID_NAME,           BOUND, &m_sName,    ::getCppuType( &m_sName ) );
      82           0 :         registerProperty( PROPERTY_XSD_WHITESPACE,  PROPERTY_ID_XSD_WHITESPACE, BOUND, &m_nWST,     ::getCppuType( &m_nWST ) );
      83           0 :         registerProperty( PROPERTY_XSD_PATTERN,     PROPERTY_ID_XSD_PATTERN,    BOUND, &m_sPattern, ::getCppuType( &m_sPattern ) );
      84             : 
      85           0 :         registerProperty( PROPERTY_XSD_IS_BASIC,    PROPERTY_ID_XSD_IS_BASIC,   READONLY, &m_bIsBasic,      ::getCppuType( &m_bIsBasic ) );
      86           0 :         registerProperty( PROPERTY_XSD_TYPE_CLASS,  PROPERTY_ID_XSD_TYPE_CLASS, READONLY, &m_nTypeClass,    ::getCppuType( &m_nTypeClass ) );
      87           0 :     }
      88             : 
      89             : 
      90           0 :     void OXSDDataType::initializeClone( const OXSDDataType& _rCloneSource )
      91             :     {
      92           0 :         m_bIsBasic   = sal_False;
      93           0 :         m_nTypeClass = _rCloneSource.m_nTypeClass;
      94           0 :         m_sPattern   = _rCloneSource.m_sPattern;
      95           0 :         m_nWST       = _rCloneSource.m_nWST;
      96           0 :     }
      97             : 
      98             : 
      99           0 :     OXSDDataType* OXSDDataType::clone( const OUString& _rNewName ) const
     100             :     {
     101           0 :         OXSDDataType* pClone = createClone( _rNewName );
     102           0 :         pClone->initializeClone( *this );
     103           0 :         return pClone;
     104             :     }
     105             : 
     106             : 
     107           0 :     IMPLEMENT_FORWARD_XINTERFACE2( OXSDDataType, OXSDDataType_Base, ::comphelper::OPropertyContainer )
     108             : 
     109             : 
     110           0 :     IMPLEMENT_FORWARD_XTYPEPROVIDER2( OXSDDataType, OXSDDataType_Base, ::comphelper::OPropertyContainer )
     111             : 
     112             : #define SET_PROPERTY( propertyid, value, member ) \
     113             :     setFastPropertyValue( PROPERTY_ID_##propertyid, makeAny( value ) ); \
     114             :     SAL_WARN_IF( member != value, "forms.misc", "OXSDDataType::setFoo: inconsistency!" );
     115             : 
     116             : 
     117           0 :     OUString SAL_CALL OXSDDataType::getName(  ) throw (RuntimeException, std::exception)
     118             :     {
     119           0 :         return m_sName;
     120             :     }
     121             : 
     122             : 
     123           0 :     void SAL_CALL OXSDDataType::setName( const OUString& aName ) throw (RuntimeException, VetoException, std::exception)
     124             :     {
     125             :         // TODO: check the name for conflicts in the repository
     126           0 :         SET_PROPERTY( NAME, aName, m_sName );
     127           0 :     }
     128             : 
     129             : 
     130           0 :     OUString SAL_CALL OXSDDataType::getPattern() throw (RuntimeException, std::exception)
     131             :     {
     132           0 :         return m_sPattern;
     133             :     }
     134             : 
     135             : 
     136           0 :     void SAL_CALL OXSDDataType::setPattern( const OUString& _pattern ) throw (RuntimeException, std::exception)
     137             :     {
     138           0 :         SET_PROPERTY( XSD_PATTERN, _pattern, m_sPattern );
     139           0 :     }
     140             : 
     141             : 
     142           0 :     sal_Int16 SAL_CALL OXSDDataType::getWhiteSpaceTreatment() throw (RuntimeException, std::exception)
     143             :     {
     144           0 :         return m_nWST;
     145             :     }
     146             : 
     147             : 
     148           0 :     void SAL_CALL OXSDDataType::setWhiteSpaceTreatment( sal_Int16 _whitespacetreatment ) throw (RuntimeException, IllegalArgumentException, std::exception)
     149             :     {
     150           0 :         SET_PROPERTY( XSD_WHITESPACE, _whitespacetreatment, m_nWST );
     151           0 :     }
     152             : 
     153             : 
     154           0 :     sal_Bool SAL_CALL OXSDDataType::getIsBasic() throw (RuntimeException, std::exception)
     155             :     {
     156           0 :         return m_bIsBasic;
     157             :     }
     158             : 
     159             : 
     160             : 
     161           0 :     sal_Int16 SAL_CALL OXSDDataType::getTypeClass() throw (RuntimeException, std::exception)
     162             :     {
     163           0 :         return m_nTypeClass;
     164             :     }
     165             : 
     166             : 
     167           0 :     sal_Bool OXSDDataType::validate( const OUString& sValue ) throw( RuntimeException, std::exception )
     168             :     {
     169           0 :         return ( _validate( sValue ) == 0 );
     170             :     }
     171             : 
     172             : 
     173           0 :   OUString OXSDDataType::explainInvalid( const OUString& sValue ) throw( RuntimeException, std::exception )
     174             :     {
     175             :         // get reason
     176           0 :         sal_uInt16 nReason = _validate( sValue );
     177             : 
     178             :         // get resource and return localized string
     179             :         return ( nReason == 0 )
     180             :             ? OUString()
     181             :             : getResource( nReason, sValue,
     182           0 :                                    _explainInvalid( nReason ) );
     183             :     }
     184             : 
     185             : 
     186           0 :     OUString OXSDDataType::_explainInvalid( sal_uInt16 nReason )
     187             :     {
     188           0 :         if ( RID_STR_XFORMS_PATTERN_DOESNT_MATCH == nReason )
     189             :         {
     190             :             OSL_ENSURE( !m_sPattern.isEmpty(), "OXSDDataType::_explainInvalid: how can this error occur without a regular expression?" );
     191           0 :             return m_sPattern;
     192             :         }
     193           0 :         return OUString();
     194             :     }
     195             : 
     196             : 
     197             :     namespace
     198             :     {
     199             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     200           0 :         static void lcl_initializePatternMatcher( ::std::auto_ptr< RegexMatcher >& _rpMatcher, const OUString& _rPattern )
     201             :         {
     202           0 :             UErrorCode nMatchStatus = U_ZERO_ERROR;
     203           0 :             UnicodeString aIcuPattern( reinterpret_cast<const UChar *>(_rPattern.getStr()), _rPattern.getLength() );    // UChar != sal_Unicode in MinGW
     204           0 :             _rpMatcher.reset( new RegexMatcher( aIcuPattern, 0, nMatchStatus ) );
     205           0 :             OSL_ENSURE( U_SUCCESS( nMatchStatus ), "lcl_initializePatternMatcher: invalid pattern property!" );
     206             :                 // if asserts, then something changed our pattern without going to convertFastPropertyValue/checkPropertySanity
     207           0 :         }
     208             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     209             : 
     210           0 :         static bool lcl_matchString( RegexMatcher& _rMatcher, const OUString& _rText )
     211             :         {
     212           0 :             UErrorCode nMatchStatus = U_ZERO_ERROR;
     213           0 :             UnicodeString aInput( reinterpret_cast<const UChar *>(_rText.getStr()), _rText.getLength() );   // UChar != sal_Unicode in MinGW
     214           0 :             _rMatcher.reset( aInput );
     215           0 :             if ( _rMatcher.matches( nMatchStatus ) )
     216             :             {
     217           0 :                 int32_t nStart = _rMatcher.start( nMatchStatus );
     218           0 :                 int32_t nEnd   = _rMatcher.end  ( nMatchStatus );
     219           0 :                 if ( ( nStart == 0 ) && ( nEnd == _rText.getLength() ) )
     220           0 :                     return true;
     221             :             }
     222             : 
     223           0 :             return false;
     224             :         }
     225             :     }
     226             : 
     227             : 
     228           0 :     sal_uInt16 OXSDDataType::_validate( const OUString& _rValue )
     229             :     {
     230             :         // care for the regular expression
     231           0 :         if ( !m_sPattern.isEmpty() )
     232             :         {
     233             :             // ensure our pattern matcher is up to date
     234           0 :             if ( m_bPatternMatcherDirty )
     235             :             {
     236           0 :                 lcl_initializePatternMatcher( m_pPatternMatcher, m_sPattern );
     237           0 :                 m_bPatternMatcherDirty = false;
     238             :             }
     239             : 
     240             :             // let it match the string
     241           0 :             if ( !lcl_matchString( *m_pPatternMatcher.get(), _rValue ) )
     242           0 :                 return RID_STR_XFORMS_PATTERN_DOESNT_MATCH;
     243             :         }
     244             : 
     245           0 :         return 0;
     246             :     }
     247             : 
     248             : 
     249           0 :     sal_Bool OXSDDataType::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw(IllegalArgumentException)
     250             :     {
     251             :         // let the base class do the conversion
     252           0 :         if ( !OXSDDataType_PBase::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ) )
     253           0 :             return sal_False;
     254             : 
     255             :         // sanity checks
     256           0 :         OUString sErrorMessage;
     257           0 :         if ( !checkPropertySanity( _nHandle, _rConvertedValue, sErrorMessage ) )
     258             :         {
     259           0 :             IllegalArgumentException aException;
     260           0 :             aException.Message = sErrorMessage;
     261           0 :             aException.Context = *this;
     262           0 :             throw IllegalArgumentException( aException );
     263             :         }
     264             : 
     265           0 :         return sal_True;
     266             :     }
     267             : 
     268             : 
     269           0 :     void SAL_CALL OXSDDataType::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception, std::exception)
     270             :     {
     271           0 :         OXSDDataType_PBase::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
     272           0 :         if ( _nHandle == PROPERTY_ID_XSD_PATTERN )
     273           0 :             m_bPatternMatcherDirty = true;
     274           0 :     }
     275             : 
     276             : 
     277           0 :     bool OXSDDataType::checkPropertySanity( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rNewValue, OUString& _rErrorMessage )
     278             :     {
     279           0 :         if ( _nHandle == PROPERTY_ID_XSD_PATTERN )
     280             :         {
     281           0 :             OUString sPattern;
     282           0 :             OSL_VERIFY( _rNewValue >>= sPattern );
     283             : 
     284           0 :             UnicodeString aIcuPattern( reinterpret_cast<const UChar *>(sPattern.getStr()), sPattern.getLength() );  // UChar != sal_Unicode in MinGW
     285           0 :             UErrorCode nMatchStatus = U_ZERO_ERROR;
     286           0 :             RegexMatcher aMatcher( aIcuPattern, 0, nMatchStatus );
     287           0 :             if ( U_FAILURE( nMatchStatus ) )
     288             :             {
     289           0 :                 _rErrorMessage = "This is no valid pattern.";
     290           0 :                 return false;
     291           0 :             }
     292             :         }
     293           0 :         return true;
     294             :     }
     295             : 
     296             : 
     297           0 :     void SAL_CALL OXSDDataType::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
     298             :     {
     299           0 :         OXSDDataType_PBase::setPropertyValue( aPropertyName, aValue );
     300           0 :     }
     301             : 
     302             : 
     303           0 :     Any SAL_CALL OXSDDataType::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
     304             :     {
     305           0 :         return OXSDDataType_PBase::getPropertyValue( PropertyName );
     306             :     }
     307             : 
     308             : 
     309           0 :     void SAL_CALL OXSDDataType::addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
     310             :     {
     311           0 :         OXSDDataType_PBase::addPropertyChangeListener( aPropertyName, xListener );
     312           0 :     }
     313             : 
     314             : 
     315           0 :     void SAL_CALL OXSDDataType::removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
     316             :     {
     317           0 :         OXSDDataType_PBase::removePropertyChangeListener( aPropertyName, aListener );
     318           0 :     }
     319             : 
     320             : 
     321           0 :     void SAL_CALL OXSDDataType::addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
     322             :     {
     323           0 :         OXSDDataType_PBase::addVetoableChangeListener( PropertyName, aListener );
     324           0 :     }
     325             : 
     326             : 
     327           0 :     void SAL_CALL OXSDDataType::removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
     328             :     {
     329           0 :         OXSDDataType_PBase::removeVetoableChangeListener( PropertyName, aListener );
     330           0 :     }
     331             : 
     332             : 
     333             :     //= OValueLimitedType_Base
     334             : 
     335           0 :     OValueLimitedType_Base::OValueLimitedType_Base( const OUString& _rName, sal_Int16 _nTypeClass )
     336             :         :OXSDDataType( _rName, _nTypeClass )
     337             :         ,m_fCachedMaxInclusive( 0 )
     338             :         ,m_fCachedMaxExclusive( 0 )
     339             :         ,m_fCachedMinInclusive( 0 )
     340           0 :         ,m_fCachedMinExclusive( 0 )
     341             :     {
     342           0 :     }
     343             : 
     344             : 
     345           0 :     void OValueLimitedType_Base::initializeClone( const OXSDDataType& _rCloneSource )
     346             :     {
     347           0 :         OXSDDataType::initializeClone( _rCloneSource );
     348           0 :         initializeTypedClone( static_cast< const OValueLimitedType_Base& >( _rCloneSource ) );
     349           0 :     }
     350             : 
     351             : 
     352           0 :     void OValueLimitedType_Base::initializeTypedClone( const OValueLimitedType_Base& _rCloneSource )
     353             :     {
     354           0 :         m_aMaxInclusive   = _rCloneSource.m_aMaxInclusive;
     355           0 :         m_aMaxExclusive   = _rCloneSource.m_aMaxExclusive;
     356           0 :         m_aMinInclusive   = _rCloneSource.m_aMinInclusive;
     357           0 :         m_aMinExclusive   = _rCloneSource.m_aMinExclusive;
     358           0 :         m_fCachedMaxInclusive   = _rCloneSource.m_fCachedMaxInclusive;
     359           0 :         m_fCachedMaxExclusive   = _rCloneSource.m_fCachedMaxExclusive;
     360           0 :         m_fCachedMinInclusive   = _rCloneSource.m_fCachedMinInclusive;
     361           0 :         m_fCachedMinExclusive   = _rCloneSource.m_fCachedMinExclusive;
     362           0 :     }
     363             : 
     364             : 
     365           0 :     void SAL_CALL OValueLimitedType_Base::setFastPropertyValue_NoBroadcast(
     366             :         sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::uno::Exception, std::exception)
     367             :     {
     368           0 :         OXSDDataType::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
     369             : 
     370             :         // if one of our limit properties has been set, translate it into a double
     371             :         // value, for later efficient validation
     372           0 :         switch ( _nHandle )
     373             :         {
     374             :         case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT:
     375             :         case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE:
     376             :         case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE:
     377             :         case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME:
     378             :         case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME:
     379           0 :             if ( m_aMaxInclusive.hasValue() )
     380           0 :                 normalizeValue( m_aMaxInclusive, m_fCachedMaxInclusive );
     381             :             else
     382           0 :                 m_fCachedMaxInclusive = 0;
     383           0 :             break;
     384             :         case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT:
     385             :         case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE:
     386             :         case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE:
     387             :         case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME:
     388             :         case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME:
     389           0 :             if ( m_aMaxExclusive.hasValue() )
     390           0 :                 normalizeValue( m_aMaxExclusive, m_fCachedMaxExclusive );
     391             :             else
     392           0 :                 m_fCachedMaxExclusive = 0;
     393           0 :             break;
     394             :         case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT:
     395             :         case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE:
     396             :         case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE:
     397             :         case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME:
     398             :         case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME:
     399           0 :             if ( m_aMinInclusive.hasValue() )
     400           0 :                 normalizeValue( m_aMinInclusive, m_fCachedMinInclusive );
     401             :             else
     402           0 :                 m_fCachedMinInclusive = 0;
     403           0 :             break;
     404             :         case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT:
     405             :         case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE:
     406             :         case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE:
     407             :         case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME:
     408             :         case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME:
     409           0 :             if ( m_aMinExclusive.hasValue() )
     410           0 :                 normalizeValue( m_aMinExclusive, m_fCachedMinExclusive );
     411             :             else
     412           0 :                 m_fCachedMinExclusive = 0;
     413           0 :             break;
     414             :         }
     415           0 :     }
     416             : 
     417             : 
     418           0 :     bool OValueLimitedType_Base::_getValue( const OUString& rValue, double& fValue )
     419             :     {
     420             :         // convert to double
     421             :         rtl_math_ConversionStatus eStatus;
     422             :         sal_Int32 nEnd;
     423             :         double f = ::rtl::math::stringToDouble(
     424           0 :             rValue, '.', sal_Unicode(0), &eStatus, &nEnd );
     425             : 
     426             :         // error checking...
     427           0 :         bool bReturn = false;
     428           0 :         if( eStatus == rtl_math_ConversionStatus_Ok
     429           0 :             && nEnd == rValue.getLength() )
     430             :         {
     431           0 :             bReturn = true;
     432           0 :             fValue = f;
     433             :         }
     434           0 :         return bReturn;
     435             :     }
     436             : 
     437             : 
     438           0 :     sal_uInt16 OValueLimitedType_Base::_validate( const OUString& rValue )
     439             :     {
     440           0 :         sal_uInt16 nReason = OXSDDataType::_validate( rValue );
     441           0 :         if( nReason == 0 )
     442             :         {
     443             : 
     444             :             // convert value and check format
     445             :             double f;
     446           0 :             if( ! _getValue( rValue, f ) )
     447           0 :                 nReason = RID_STR_XFORMS_VALUE_IS_NOT_A;
     448             : 
     449             :             // check range
     450           0 :             else if( ( m_aMaxInclusive.hasValue() ) && f > m_fCachedMaxInclusive )
     451           0 :                 nReason = RID_STR_XFORMS_VALUE_MAX_INCL;
     452           0 :             else if( ( m_aMaxExclusive.hasValue() ) && f >= m_fCachedMaxExclusive )
     453           0 :                 nReason = RID_STR_XFORMS_VALUE_MAX_EXCL;
     454           0 :             else if( ( m_aMinInclusive.hasValue() ) && f < m_fCachedMinInclusive )
     455           0 :                 nReason = RID_STR_XFORMS_VALUE_MIN_INCL;
     456           0 :             else if( ( m_aMinExclusive.hasValue() ) && f <= m_fCachedMinExclusive )
     457           0 :                 nReason = RID_STR_XFORMS_VALUE_MIN_EXCL;
     458             :         }
     459           0 :         return nReason;
     460             :     }
     461             : 
     462             : 
     463           0 :     OUString OValueLimitedType_Base::_explainInvalid( sal_uInt16 nReason )
     464             :     {
     465           0 :         OUStringBuffer sInfo;
     466           0 :         switch( nReason )
     467             :         {
     468             :         case 0:
     469             :             // nothing to do!
     470           0 :             break;
     471             : 
     472             :         case RID_STR_XFORMS_VALUE_IS_NOT_A:
     473           0 :             sInfo.append( getName() );
     474           0 :             break;
     475             : 
     476             :         case RID_STR_XFORMS_VALUE_MAX_INCL:
     477           0 :             sInfo.append( typedValueAsHumanReadableString( m_aMaxInclusive ) );
     478           0 :             break;
     479             : 
     480             :         case RID_STR_XFORMS_VALUE_MAX_EXCL:
     481           0 :             sInfo.append( typedValueAsHumanReadableString( m_aMaxExclusive ) );
     482           0 :             break;
     483             : 
     484             :         case RID_STR_XFORMS_VALUE_MIN_INCL:
     485           0 :             sInfo.append( typedValueAsHumanReadableString( m_aMinInclusive ) );
     486           0 :             break;
     487             : 
     488             :         case RID_STR_XFORMS_VALUE_MIN_EXCL:
     489           0 :             sInfo.append( typedValueAsHumanReadableString( m_aMinExclusive ) );
     490           0 :             break;
     491             : 
     492             :         default:
     493             :             OSL_FAIL( "OValueLimitedType::_explainInvalid: unknown reason!" );
     494           0 :             break;
     495             :         }
     496             : 
     497           0 :         return sInfo.makeStringAndClear();
     498             :     }
     499             : 
     500             : 
     501             :     //= OStringType
     502             : 
     503             : 
     504           0 :     OStringType::OStringType( const OUString& _rName, sal_Int16 _nTypeClass )
     505           0 :         :OStringType_Base( _rName, _nTypeClass )
     506             :     {
     507           0 :     }
     508             : 
     509             : 
     510           0 :     void OStringType::registerProperties()
     511             :     {
     512           0 :         OStringType_Base::registerProperties();
     513             : 
     514           0 :         REGISTER_VOID_PROP( XSD_LENGTH,     m_aLength,    sal_Int32 );
     515           0 :         REGISTER_VOID_PROP( XSD_MIN_LENGTH, m_aMinLength, sal_Int32 );
     516           0 :         REGISTER_VOID_PROP( XSD_MAX_LENGTH, m_aMaxLength, sal_Int32 );
     517           0 :     }
     518             : 
     519             : 
     520           0 :     IMPLEMENT_DEFAULT_TYPED_CLONING( OStringType, OStringType_Base )
     521             : 
     522             : 
     523           0 :     void OStringType::initializeTypedClone( const OStringType& _rCloneSource )
     524             :     {
     525           0 :         m_aLength       = _rCloneSource.m_aLength;
     526           0 :         m_aMinLength    = _rCloneSource.m_aMinLength;
     527           0 :         m_aMaxLength    = _rCloneSource.m_aMaxLength;
     528           0 :     }
     529             : 
     530             : 
     531           0 :     bool OStringType::checkPropertySanity( sal_Int32 _nHandle, const Any& _rNewValue, OUString& _rErrorMessage )
     532             :     {
     533             :         // let the base class do the conversion
     534           0 :         if ( !OStringType_Base::checkPropertySanity( _nHandle, _rNewValue, _rErrorMessage ) )
     535           0 :             return false;
     536             : 
     537           0 :         _rErrorMessage = OUString();
     538           0 :         switch ( _nHandle )
     539             :         {
     540             :             case PROPERTY_ID_XSD_LENGTH:
     541             :             case PROPERTY_ID_XSD_MIN_LENGTH:
     542             :             case PROPERTY_ID_XSD_MAX_LENGTH:
     543             :             {
     544           0 :                 sal_Int32 nValue( 0 );
     545           0 :                 OSL_VERIFY( _rNewValue >>= nValue );
     546           0 :                 if ( nValue <= 0 )
     547           0 :                     _rErrorMessage = "Length limits must denote positive integer values.";
     548             :                         // TODO/eforms: localize the error message
     549             :             }
     550           0 :             break;
     551             :         }
     552             : 
     553           0 :         return _rErrorMessage.isEmpty();
     554             :     }
     555             : 
     556             : 
     557           0 :     sal_uInt16 OStringType::_validate( const OUString& rValue )
     558             :     {
     559             :         // check regexp, whitespace etc. in parent class
     560           0 :         sal_uInt16 nReason = OStringType_Base::_validate( rValue );
     561             : 
     562           0 :         if( nReason == 0 )
     563             :         {
     564             :             // check string constraints
     565           0 :             sal_Int32 nLength = rValue.getLength();
     566           0 :             sal_Int32 nLimit = 0;
     567           0 :             if ( m_aLength >>= nLimit )
     568             :             {
     569           0 :                 if ( nLimit != nLength )
     570           0 :                     nReason = RID_STR_XFORMS_VALUE_LENGTH;
     571             :             }
     572             :             else
     573             :             {
     574           0 :                 if ( ( m_aMaxLength >>= nLimit ) && ( nLength > nLimit ) )
     575           0 :                     nReason = RID_STR_XFORMS_VALUE_MAX_LENGTH;
     576           0 :                 else if ( ( m_aMinLength >>= nLimit ) && ( nLength < nLimit ) )
     577           0 :                     nReason = RID_STR_XFORMS_VALUE_MIN_LENGTH;
     578             :             }
     579             :         }
     580           0 :         return nReason;
     581             :     }
     582             : 
     583             : 
     584           0 :     OUString OStringType::_explainInvalid( sal_uInt16 nReason )
     585             :     {
     586           0 :         sal_Int32 nValue = 0;
     587           0 :         OUStringBuffer sInfo;
     588           0 :         switch( nReason )
     589             :         {
     590             :         case 0:
     591             :             // nothing to do!
     592           0 :             break;
     593             : 
     594             :         case RID_STR_XFORMS_VALUE_LENGTH:
     595           0 :             if( m_aLength >>= nValue )
     596           0 :                 sInfo.append( nValue );
     597           0 :             break;
     598             : 
     599             :         case RID_STR_XFORMS_VALUE_MAX_LENGTH:
     600           0 :             if( m_aMaxLength >>= nValue )
     601           0 :                 sInfo.append( nValue );
     602           0 :             break;
     603             : 
     604             :         case RID_STR_XFORMS_VALUE_MIN_LENGTH:
     605           0 :             if( m_aMinLength >>= nValue )
     606           0 :                 sInfo.append( nValue );
     607           0 :             break;
     608             : 
     609             :         default:
     610           0 :             sInfo.append( OStringType_Base::_explainInvalid( nReason ) );
     611           0 :             break;
     612             :         }
     613           0 :         return sInfo.makeStringAndClear();
     614             :     }
     615             : 
     616             : 
     617             :     //= OBooleanType
     618             : 
     619             : 
     620           0 :     OBooleanType::OBooleanType( const OUString& _rName )
     621           0 :         :OBooleanType_Base( _rName, DataTypeClass::BOOLEAN )
     622             :     {
     623           0 :     }
     624             : 
     625             : 
     626           0 :     IMPLEMENT_DEFAULT_CLONING( OBooleanType, OBooleanType_Base )
     627             : 
     628             : 
     629           0 :     void OBooleanType::initializeTypedClone( const OBooleanType& /*_rCloneSource*/ )
     630             :     {
     631           0 :     }
     632             : 
     633             : 
     634           0 :     sal_uInt16 OBooleanType::_validate( const OUString& sValue )
     635             :     {
     636           0 :         sal_uInt16 nInvalidityReason = OBooleanType_Base::_validate( sValue );
     637           0 :         if ( nInvalidityReason )
     638           0 :             return nInvalidityReason;
     639             : 
     640           0 :         bool bValid = sValue == "0" || sValue == "1" || sValue == "true" || sValue == "false";
     641           0 :         return bValid ? 0 : RID_STR_XFORMS_INVALID_VALUE;
     642             :     }
     643             : 
     644             : 
     645           0 :     OUString OBooleanType::_explainInvalid( sal_uInt16 nReason )
     646             :     {
     647           0 :         return ( nReason == 0 ) ? OUString() : getName();
     648             :     }
     649             : 
     650             : 
     651             :     //= ODecimalType
     652             : 
     653             : 
     654           0 :     ODecimalType::ODecimalType( const OUString& _rName, sal_Int16 _nTypeClass )
     655           0 :         :ODecimalType_Base( _rName, _nTypeClass )
     656             :     {
     657           0 :     }
     658             : 
     659             : 
     660           0 :     IMPLEMENT_DEFAULT_TYPED_CLONING( ODecimalType, ODecimalType_Base )
     661             : 
     662             : 
     663           0 :     void ODecimalType::initializeTypedClone( const ODecimalType& _rCloneSource )
     664             :     {
     665           0 :         m_aTotalDigits    = _rCloneSource.m_aTotalDigits;
     666           0 :         m_aFractionDigits = _rCloneSource.m_aFractionDigits;
     667           0 :     }
     668             : 
     669             : 
     670           0 :     void ODecimalType::registerProperties()
     671             :     {
     672           0 :         ODecimalType_Base::registerProperties();
     673             : 
     674           0 :         REGISTER_VOID_PROP( XSD_TOTAL_DIGITS,    m_aTotalDigits,    sal_Int32 );
     675           0 :         REGISTER_VOID_PROP( XSD_FRACTION_DIGITS, m_aFractionDigits, sal_Int32 );
     676           0 :     }
     677             : 
     678             : 
     679             : 
     680             :     // validate decimals and return code for which facets failed
     681             :     // to be used by: ODecimalType::validate and ODecimalType::explainInvalid
     682           0 :     sal_uInt16 ODecimalType::_validate( const OUString& rValue )
     683             :     {
     684           0 :         sal_Int16 nReason = ODecimalType_Base::_validate( rValue );
     685             : 
     686             :         // check digits (if no other cause is available so far)
     687           0 :         if( nReason == 0 )
     688             :         {
     689           0 :             sal_Int32 nLength = rValue.getLength();
     690           0 :             sal_Int32 n = 0;
     691           0 :             sal_Int32 nTotalDigits = 0;
     692           0 :             sal_Int32 nFractionDigits = 0;
     693           0 :             const sal_Unicode* pValue = rValue.getStr();
     694           0 :             for( ; n < nLength && pValue[n] != '.'; n++ )
     695           0 :                 if( pValue[n] >= '0'
     696           0 :                     && pValue[n] <= '9')
     697           0 :                     nTotalDigits++;
     698           0 :             for( ; n < nLength; n++ )
     699           0 :                 if( pValue[n] >= '0'
     700           0 :                     && pValue[n] <= '9')
     701           0 :                     nFractionDigits++;
     702           0 :             nTotalDigits += nFractionDigits;
     703             : 
     704           0 :             sal_Int32 nValue = 0;
     705           0 :             if( ( m_aTotalDigits >>= nValue ) &&  nTotalDigits > nValue )
     706           0 :                 nReason = RID_STR_XFORMS_VALUE_TOTAL_DIGITS;
     707           0 :             else if( ( m_aFractionDigits >>= nValue ) &&
     708           0 :                      ( nFractionDigits > nValue ) )
     709           0 :                 nReason = RID_STR_XFORMS_VALUE_FRACTION_DIGITS;
     710             :         }
     711             : 
     712           0 :         return nReason;
     713             :     }
     714             : 
     715             : 
     716           0 :     OUString ODecimalType::_explainInvalid( sal_uInt16 nReason )
     717             :     {
     718           0 :         sal_Int32 nValue = 0;
     719           0 :         OUStringBuffer sInfo;
     720           0 :         switch( nReason )
     721             :         {
     722             :         case RID_STR_XFORMS_VALUE_TOTAL_DIGITS:
     723           0 :             if( m_aTotalDigits >>= nValue )
     724           0 :                 sInfo.append( nValue );
     725           0 :             break;
     726             : 
     727             :         case RID_STR_XFORMS_VALUE_FRACTION_DIGITS:
     728           0 :             if( m_aFractionDigits >>= nValue )
     729           0 :                 sInfo.append( nValue );
     730           0 :             break;
     731             : 
     732             :         default:
     733           0 :             sInfo.append( ODecimalType_Base::_explainInvalid( nReason ) );
     734           0 :             break;
     735             :         }
     736           0 :         return sInfo.makeStringAndClear();
     737             :     }
     738             : 
     739             : 
     740           0 :     OUString ODecimalType::typedValueAsHumanReadableString( const Any& _rValue ) const
     741             :     {
     742           0 :         double fValue( 0 );
     743           0 :         normalizeValue( _rValue, fValue );
     744           0 :         return OUString::number( fValue );
     745             :     }
     746             : 
     747             : 
     748           0 :     void ODecimalType::normalizeValue( const Any& _rValue, double& _rDoubleValue ) const
     749             :     {
     750           0 :         OSL_VERIFY( _rValue >>= _rDoubleValue );
     751           0 :     }
     752             : 
     753             : 
     754             :     //=
     755             : 
     756             : #define DEFAULT_IMPLEMNENT_SUBTYPE( classname, typeclass )      \
     757             :     classname::classname( const OUString& _rName )       \
     758             :         :classname##_Base( _rName, DataTypeClass::typeclass )   \
     759             :     {                                                           \
     760             :     }                                                           \
     761             :                                                                 \
     762             :     IMPLEMENT_DEFAULT_CLONING( classname, classname##_Base )    \
     763             :                                                                 \
     764             :     void classname::initializeTypedClone( const classname& /*_rCloneSource*/ )  \
     765             :     {                                                           \
     766             :     }                                                           \
     767             : 
     768             : 
     769             : 
     770             :     //= ODateType
     771             : 
     772             : 
     773           0 :     DEFAULT_IMPLEMNENT_SUBTYPE( ODateType, DATE )
     774             : 
     775             : 
     776           0 :     sal_uInt16 ODateType::_validate( const OUString& _rValue )
     777             :     {
     778           0 :         return ODateType_Base::_validate( _rValue );
     779             :     }
     780             : 
     781             : 
     782           0 :     bool ODateType::_getValue( const OUString& value, double& fValue )
     783             :     {
     784           0 :         Any aTypeValue = Convert::get().toAny( value, getCppuType() );
     785             : 
     786           0 :         Date aValue;
     787           0 :         if ( !( aTypeValue >>= aValue ) )
     788           0 :             return false;
     789             : 
     790           0 :         ::Date aToolsDate( aValue.Day, aValue.Month, aValue.Year );
     791           0 :         fValue = aToolsDate.GetDate();
     792           0 :         return true;
     793             :     }
     794             : 
     795             : 
     796           0 :     OUString ODateType::typedValueAsHumanReadableString( const Any& _rValue ) const
     797             :     {
     798             :         OSL_PRECOND( _rValue.getValueType().equals( getCppuType() ), "ODateType::typedValueAsHumanReadableString: unexpected type" );
     799           0 :         return Convert::get().toXSD( _rValue );
     800             :     }
     801             : 
     802             : 
     803           0 :     void ODateType::normalizeValue( const Any& _rValue, double& _rDoubleValue ) const
     804             :     {
     805           0 :         Date aValue;
     806           0 :         OSL_VERIFY( _rValue >>= aValue );
     807           0 :         ::Date aToolsDate( aValue.Day, aValue.Month, aValue.Year );
     808           0 :         _rDoubleValue = aToolsDate.GetDate();
     809           0 :     }
     810             : 
     811             : 
     812             :     //= OTimeType
     813             : 
     814             : 
     815           0 :     DEFAULT_IMPLEMNENT_SUBTYPE( OTimeType, TIME )
     816             : 
     817             : 
     818           0 :     sal_uInt16 OTimeType::_validate( const OUString& _rValue )
     819             :     {
     820           0 :         return OTimeType_Base::_validate( _rValue );
     821             :     }
     822             : 
     823             : 
     824           0 :     bool OTimeType::_getValue( const OUString& value, double& fValue )
     825             :     {
     826           0 :         Any aTypedValue = Convert::get().toAny( value, getCppuType() );
     827             : 
     828           0 :         Time aValue;
     829           0 :         if ( !( aTypedValue >>= aValue ) )
     830           0 :             return false;
     831             : 
     832           0 :         ::Time aToolsTime( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.NanoSeconds );
     833             :         // no loss/rounding; IEEE 754 double-precision floating-point
     834             :         // has a mantissa of 53 bits; we need at the very most 50 bits:
     835             :         // format of aToolsTime.GetTime() is (in decimal) hhmmssnnnnnnnnn
     836             :         // and 999999999999999 = 0x38D7EA4C67FFF
     837             :         // in reality I doubt we need (much) more than
     838             :         //     240000000000000 = 0x0DA475ABF0000
     839             :         // that is 48 bits
     840           0 :         fValue = aToolsTime.GetTime();
     841           0 :         return true;
     842             :     }
     843             : 
     844             : 
     845           0 :     OUString OTimeType::typedValueAsHumanReadableString( const Any& _rValue ) const
     846             :     {
     847             :         OSL_PRECOND( _rValue.getValueType().equals( getCppuType() ), "OTimeType::typedValueAsHumanReadableString: unexpected type" );
     848           0 :         return Convert::get().toXSD( _rValue );
     849             :     }
     850             : 
     851             : 
     852           0 :     void OTimeType::normalizeValue( const Any& _rValue, double& _rDoubleValue ) const
     853             :     {
     854           0 :         Time aValue;
     855           0 :         OSL_VERIFY( _rValue >>= aValue );
     856           0 :         ::Time aToolsTime( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.NanoSeconds );
     857           0 :         _rDoubleValue = aToolsTime.GetTime();
     858           0 :     }
     859             : 
     860             : 
     861             :     //= ODateTimeType
     862             : 
     863             : 
     864           0 :     DEFAULT_IMPLEMNENT_SUBTYPE( ODateTimeType, DATETIME )
     865             : 
     866             : 
     867           0 :     sal_uInt16 ODateTimeType::_validate( const OUString& _rValue )
     868             :     {
     869           0 :         return ODateTimeType_Base::_validate( _rValue );
     870             :     }
     871             : 
     872             : 
     873             :     namespace
     874             :     {
     875           0 :         double lcl_normalizeDateTime( const DateTime& _rValue )
     876             :         {
     877             :             ::DateTime aToolsValue(
     878             :                 ::Date( _rValue.Day, _rValue.Month, _rValue.Year ),
     879             :                 ::Time( _rValue.Hours, _rValue.Minutes, _rValue.Seconds, _rValue.NanoSeconds )
     880           0 :             );
     881             : 
     882           0 :             double fValue = 0;
     883             :             // days since 1.1.1900 (which is relatively arbitrary but fixed date)
     884           0 :             fValue += ::Date( aToolsValue ) - ::Date( 1, 1, 1900 );
     885             :             // time
     886           0 :             fValue += aToolsValue.GetTimeInDays();
     887           0 :             return fValue;
     888             :         }
     889             :     }
     890             : 
     891             : 
     892           0 :     bool ODateTimeType::_getValue( const OUString& value, double& fValue )
     893             :     {
     894           0 :         Any aTypedValue = Convert::get().toAny( value, getCppuType() );
     895             : 
     896           0 :         DateTime aValue;
     897           0 :         if ( !( aTypedValue >>= aValue ) )
     898           0 :             return false;
     899             : 
     900           0 :         fValue = lcl_normalizeDateTime( aValue );
     901           0 :         return true;
     902             :     }
     903             : 
     904             : 
     905           0 :     OUString ODateTimeType::typedValueAsHumanReadableString( const Any& _rValue ) const
     906             :     {
     907             :         OSL_PRECOND( _rValue.getValueType().equals( getCppuType() ), "OTimeType::typedValueAsHumanReadableString: unexpected type" );
     908           0 :         OUString sString = Convert::get().toXSD( _rValue );
     909             : 
     910             :         // ISO 8601 notation has a "T" to separate between date and time. Our only concession
     911             :         // to the "human readable" in the method name is to replace this T with a whitespace.
     912             :         OSL_ENSURE( sString.indexOf( 'T' ) != -1, "ODateTimeType::typedValueAsHumanReadableString: hmm - no ISO notation?" );
     913           0 :         return sString.replace( 'T', ' ' );
     914             :     }
     915             : 
     916             : 
     917           0 :     void ODateTimeType::normalizeValue( const Any& _rValue, double& _rDoubleValue ) const
     918             :     {
     919           0 :         DateTime aValue;
     920           0 :         OSL_VERIFY( _rValue >>= aValue );
     921           0 :         _rDoubleValue = lcl_normalizeDateTime( aValue );
     922           0 :     }
     923             : 
     924             : 
     925             :     //= OShortIntegerType
     926             : 
     927             : 
     928           0 :     OShortIntegerType::OShortIntegerType( const OUString& _rName, sal_Int16 _nTypeClass )
     929           0 :         :OShortIntegerType_Base( _rName, _nTypeClass )
     930             :     {
     931           0 :     }
     932             : 
     933             : 
     934           0 :     IMPLEMENT_DEFAULT_TYPED_CLONING( OShortIntegerType, OShortIntegerType_Base )
     935             : 
     936             : 
     937           0 :     void OShortIntegerType::initializeTypedClone( const OShortIntegerType& /*_rCloneSource*/ )
     938             :     {
     939           0 :     }
     940             : 
     941             : 
     942           0 :     bool OShortIntegerType::_getValue( const OUString& value, double& fValue )
     943             :     {
     944           0 :         fValue = (double)(sal_Int16)value.toInt32();
     945             :         // TODO/eforms
     946             :         // this does not care for values which do not fit into a sal_Int16, but simply
     947             :         // cuts them down. A better implementation here should probably return <FALSE/>
     948             :         // for those values.
     949             :         // Else, we may have a situation where the UI claims an input to be valid
     950             :         // (say "12345678"), while internally, and at submission time, this is cut to
     951             :         // some smaller value.
     952             : 
     953             :         // Additionally, this of course does not care for strings which are no numers ...
     954           0 :         return true;
     955             :     }
     956             : 
     957             : 
     958           0 :     OUString OShortIntegerType::typedValueAsHumanReadableString( const Any& _rValue ) const
     959             :     {
     960           0 :         sal_Int16 nValue( 0 );
     961           0 :         OSL_VERIFY( _rValue >>= nValue );
     962           0 :         return OUString::number( nValue );
     963             :     }
     964             : 
     965             : 
     966           0 :     void OShortIntegerType::normalizeValue( const Any& _rValue, double& _rDoubleValue ) const
     967             :     {
     968           0 :         sal_Int16 nValue( 0 );
     969           0 :         OSL_VERIFY( _rValue >>= nValue );
     970           0 :         _rDoubleValue = nValue;
     971           0 :     }
     972             : 
     973             : 
     974             : 
     975             : #define DATATYPES_INCLUDED_BY_MASTER_HEADER
     976             : #include "datatypes_impl.hxx"
     977             : #undef DATATYPES_INCLUDED_BY_MASTER_HEADER
     978             : 
     979             : 
     980             : } // namespace xforms
     981             : 
     982             : 
     983             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10