LCOV - code coverage report
Current view: top level - reportdesign/source/core/misc - conditionalexpression.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 69 0.0 %
Date: 2012-08-25 Functions: 0 4 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 130 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : #include "conditionalexpression.hxx"
      29                 :            : 
      30                 :            : //........................................................................
      31                 :            : namespace rptui
      32                 :            : {
      33                 :            : //........................................................................
      34                 :            : 
      35                 :            :     /** === begin UNO using === **/
      36                 :            :     /** === end UNO using === **/
      37                 :            : 
      38                 :            :     // =============================================================================
      39                 :            :     // = ConditionalExpression
      40                 :            :     // =============================================================================
      41                 :            :     // -----------------------------------------------------------------------------
      42                 :          0 :     ConditionalExpression::ConditionalExpression( const sal_Char* _pAsciiPattern )
      43                 :          0 :         :m_sPattern( ::rtl::OUString::createFromAscii( _pAsciiPattern ) )
      44                 :            :     {
      45                 :          0 :     }
      46                 :            : 
      47                 :            :     // -----------------------------------------------------------------------------
      48                 :          0 :     ::rtl::OUString ConditionalExpression::assembleExpression( const ::rtl::OUString& _rFieldDataSource, const ::rtl::OUString& _rLHS, const ::rtl::OUString& _rRHS ) const
      49                 :            :     {
      50                 :          0 :         ::rtl::OUString sExpression( m_sPattern );
      51                 :            : 
      52                 :          0 :         sal_Int32 nPatternIndex = sExpression.indexOf( '$' );
      53         [ #  # ]:          0 :         while ( nPatternIndex > -1 )
      54                 :            :         {
      55                 :          0 :             const ::rtl::OUString* pReplace = NULL;
      56   [ #  #  #  # ]:          0 :             switch ( sExpression.getStr()[ nPatternIndex + 1 ] )
      57                 :            :             {
      58                 :          0 :             case '$': pReplace = &_rFieldDataSource; break;
      59                 :          0 :             case '1': pReplace = &_rLHS; break;
      60                 :          0 :             case '2': pReplace = &_rRHS; break;
      61                 :          0 :             default: break;
      62                 :            :             }
      63                 :            : 
      64         [ #  # ]:          0 :             if ( pReplace == NULL )
      65                 :            :             {
      66                 :            :                 OSL_FAIL( "ConditionalExpression::assembleExpression: illegal pattern!" );
      67                 :          0 :                 break;
      68                 :            :             }
      69                 :            : 
      70                 :          0 :             sExpression = sExpression.replaceAt( nPatternIndex, 2, *pReplace );
      71                 :          0 :             nPatternIndex = sExpression.indexOf( '$', nPatternIndex + pReplace->getLength() + 1 );
      72                 :            :         }
      73                 :          0 :         return sExpression;
      74                 :            :     }
      75                 :            : 
      76                 :            :     // -----------------------------------------------------------------------------
      77                 :          0 :     bool ConditionalExpression::matchExpression( const ::rtl::OUString& _rExpression, const ::rtl::OUString& _rFieldDataSource, ::rtl::OUString& _out_rLHS, ::rtl::OUString& _out_rRHS ) const
      78                 :            :     {
      79                 :            :         (void)_rExpression;
      80                 :            :         (void)_rFieldDataSource;
      81                 :            :         (void)_out_rLHS;
      82                 :            :         (void)_out_rRHS;
      83                 :            : 
      84                 :            :         // if we had regular expression, the matching would be pretty easy ...
      85                 :            :         // just replace $1 and $2 in the pattern with (.*), and then get them with \1 resp. \2.
      86                 :            :         // Unfortunately, we don't have such a regexp engine ...
      87                 :            : 
      88                 :            :         // Okay, let's start with replacing all $$ in our pattern with the actual field data source
      89                 :          0 :         ::rtl::OUString sMatchExpression( m_sPattern );
      90         [ #  # ]:          0 :         const ::rtl::OUString sFieldDataPattern( RTL_CONSTASCII_USTRINGPARAM( "$$" ) );
      91                 :          0 :         sal_Int32 nIndex( sMatchExpression.indexOf( sFieldDataPattern ) );
      92         [ #  # ]:          0 :         while ( nIndex != -1 )
      93                 :            :         {
      94                 :          0 :             sMatchExpression = sMatchExpression.replaceAt( nIndex, sFieldDataPattern.getLength(), _rFieldDataSource );
      95                 :          0 :             nIndex = sMatchExpression.indexOf( sFieldDataPattern, nIndex + _rFieldDataSource.getLength() );
      96                 :            :         }
      97                 :            : 
      98         [ #  # ]:          0 :         const ::rtl::OUString sLHSPattern( RTL_CONSTASCII_USTRINGPARAM( "$1" ) );
      99         [ #  # ]:          0 :         const ::rtl::OUString sRHSPattern( RTL_CONSTASCII_USTRINGPARAM( "$2" ) );
     100                 :          0 :         sal_Int32 nLHSIndex( sMatchExpression.indexOf( sLHSPattern ) );
     101                 :          0 :         sal_Int32 nRHSIndex( sMatchExpression.indexOf( sRHSPattern ) );
     102                 :            : 
     103                 :            :         // now we should have at most one occurrence of $1 and $2, resp.
     104                 :            :         OSL_ENSURE( sMatchExpression.indexOf( sLHSPattern, nLHSIndex + 1 ) == -1,
     105                 :            :             "ConditionalExpression::matchExpression: unsupported pattern (more than one LHS occurrence)!" );
     106                 :            :         OSL_ENSURE( sMatchExpression.indexOf( sRHSPattern, nRHSIndex + 1 ) == -1,
     107                 :            :             "ConditionalExpression::matchExpression: unsupported pattern (more than one RHS occurrence)!" );
     108                 :            :         // Also, an LHS must be present, and precede the RHS (if present)
     109                 :            :         OSL_ENSURE( ( nLHSIndex != -1 ) && ( ( nLHSIndex < nRHSIndex ) || ( nRHSIndex == -1 ) ),
     110                 :            :             "ConditionalExpression::matchExpression: no LHS, or an RHS preceeding the LHS - this is not supported!" );
     111                 :            : 
     112                 :            :         // up to the occurrence of the LHS (which must exist, see above), the two expressions
     113                 :            :         // must be identical
     114         [ #  # ]:          0 :         if ( _rExpression.getLength() < nLHSIndex )
     115                 :          0 :             return false;
     116                 :          0 :         const ::rtl::OUString sExprPart1( _rExpression.copy( 0, nLHSIndex ) );
     117                 :          0 :         const ::rtl::OUString sMatchExprPart1( sMatchExpression.copy( 0, nLHSIndex ) );
     118         [ #  # ]:          0 :         if ( sExprPart1 != sMatchExprPart1 )
     119                 :            :             // the left-most expression parts do not match
     120                 :          0 :             return false;
     121                 :            : 
     122                 :            :         // after the occurrence of the RHS (or the LHS, if there is no RHS), the two expressions
     123                 :            :         // must be identical, too
     124                 :          0 :         bool bHaveRHS( nRHSIndex != -1 );
     125         [ #  # ]:          0 :         sal_Int32 nRightMostIndex( bHaveRHS ? nRHSIndex : nLHSIndex );
     126                 :          0 :         const ::rtl::OUString sMatchExprPart3( sMatchExpression.copy( nRightMostIndex + 2 ) );
     127         [ #  # ]:          0 :         if ( _rExpression.getLength() < sMatchExprPart3.getLength() )
     128                 :            :             // the expression is not even long enough to hold the right-most part of the match expression
     129                 :          0 :             return false;
     130                 :          0 :         const ::rtl::OUString sExprPart3( _rExpression.copy( _rExpression.getLength() - sMatchExprPart3.getLength() ) );
     131         [ #  # ]:          0 :         if ( sExprPart3 != sMatchExprPart3 )
     132                 :            :             // the right-most expression parts do not match
     133                 :          0 :             return false;
     134                 :            : 
     135                 :            :         // if we don't have an RHS, we're done
     136         [ #  # ]:          0 :         if ( !bHaveRHS )
     137                 :            :         {
     138                 :          0 :             _out_rLHS = _rExpression.copy( sExprPart1.getLength(), _rExpression.getLength() - sExprPart1.getLength() - sExprPart3.getLength() );
     139                 :          0 :             return true;
     140                 :            :         }
     141                 :            : 
     142                 :            :         // strip the match expression by its right-most and left-most part, and by the placeholders $1 and $2
     143                 :          0 :         sal_Int32 nMatchExprPart2Start( nLHSIndex + sLHSPattern.getLength() );
     144                 :            :         ::rtl::OUString sMatchExprPart2 = sMatchExpression.copy(
     145                 :            :             nMatchExprPart2Start,
     146                 :          0 :             sMatchExpression.getLength() - nMatchExprPart2Start - sMatchExprPart3.getLength() - 2
     147                 :          0 :         );
     148                 :            :         // strip the expression by its left-most and right-most part
     149                 :            :         const ::rtl::OUString sExpression( _rExpression.copy(
     150                 :            :             sExprPart1.getLength(),
     151                 :          0 :             _rExpression.getLength() - sExprPart1.getLength() - sExprPart3.getLength()
     152                 :          0 :         ) );
     153                 :            : 
     154                 :          0 :         sal_Int32 nPart2Index = sExpression.indexOf( sMatchExprPart2 );
     155         [ #  # ]:          0 :         if ( nPart2Index == -1 )
     156                 :            :             // the "middle" part of the match expression does not exist in the expression at all
     157                 :          0 :             return false;
     158                 :            : 
     159                 :            :         OSL_ENSURE( sExpression.indexOf( sMatchExprPart2, nPart2Index + 1 ) == -1,
     160                 :            :             "ConditionalExpression::matchExpression: ambiguous matching!" );
     161                 :            :             // if this fires, then we're lost: The middle part exists two times in the expression,
     162                 :            :             // so we cannot reliably determine what's the LHS and what's the RHS.
     163                 :            :             // Well, the whole mechanism is flawed, anyway:
     164                 :            :             // Encoding the field content in the conditional expression will break as soon
     165                 :            :             // as somebody
     166                 :            :             // - assigns a Data Field to a control
     167                 :            :             // - creates a conditional format expression for the control
     168                 :            :             // - assigns another Data Field to the control
     169                 :            :             // - opens the Conditional Format Dialog, again
     170                 :            :             // Here, at the latest, you can see that we need another mechanism, anyway, which does not
     171                 :            :             // rely on those strange expression building/matching
     172                 :            : 
     173                 :          0 :         _out_rLHS = sExpression.copy( 0, nPart2Index );
     174                 :          0 :         _out_rRHS = sExpression.copy( nPart2Index + sMatchExprPart2.getLength() );
     175                 :            : 
     176                 :          0 :         return true;
     177                 :            :     }
     178                 :            : 
     179                 :            :     // =============================================================================
     180                 :            :     // = ConditionalExpressionFactory
     181                 :            :     // =============================================================================
     182                 :            :     // -----------------------------------------------------------------------------
     183                 :          0 :     size_t ConditionalExpressionFactory::getKnownConditionalExpressions( ConditionalExpressions& _out_rCondExp )
     184                 :            :     {
     185         [ #  # ]:          0 :         ConditionalExpressions aEmpty;
     186         [ #  # ]:          0 :         _out_rCondExp.swap( aEmpty );
     187                 :            : 
     188 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eBetween ]        = PConditionalExpression( new ConditionalExpression( "AND( ( $$ ) >= ( $1 ); ( $$ ) <= ( $2 ) )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     189 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eNotBetween ]     = PConditionalExpression( new ConditionalExpression( "NOT( AND( ( $$ ) >= ( $1 ); ( $$ ) <= ( $2 ) ) )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     190 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eEqualTo ]        = PConditionalExpression( new ConditionalExpression( "( $$ ) = ( $1 )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     191 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eNotEqualTo ]     = PConditionalExpression( new ConditionalExpression( "( $$ ) <> ( $1 )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     192 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eGreaterThan ]    = PConditionalExpression( new ConditionalExpression( "( $$ ) > ( $1 )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     193 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eLessThan ]       = PConditionalExpression( new ConditionalExpression( "( $$ ) < ( $1 )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     194 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eGreaterOrEqual ] = PConditionalExpression( new ConditionalExpression( "( $$ ) >= ( $1 )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     195 [ #  # ][ #  # ]:          0 :         _out_rCondExp[ eLessOrEqual ]    = PConditionalExpression( new ConditionalExpression( "( $$ ) <= ( $1 )" ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     196                 :            : 
     197                 :          0 :         return _out_rCondExp.size();
     198                 :            :     }
     199                 :            : //........................................................................
     200                 :            : } // namespace rptui
     201                 :            : //........................................................................
     202                 :            : 
     203                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10