LCOV - code coverage report
Current view: top level - reportdesign/source/core/misc - conditionalexpression.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 69 0.0 %
Date: 2014-11-03 Functions: 0 4 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             : #include "conditionalexpression.hxx"
      20             : 
      21             : 
      22             : namespace rptui
      23             : {
      24             : 
      25             :     // = ConditionalExpression
      26             : 
      27             : 
      28           0 :     ConditionalExpression::ConditionalExpression( const sal_Char* _pAsciiPattern )
      29           0 :         :m_sPattern( OUString::createFromAscii( _pAsciiPattern ) )
      30             :     {
      31           0 :     }
      32             : 
      33             : 
      34           0 :     OUString ConditionalExpression::assembleExpression( const OUString& _rFieldDataSource, const OUString& _rLHS, const OUString& _rRHS ) const
      35             :     {
      36           0 :         OUString sExpression( m_sPattern );
      37             : 
      38           0 :         sal_Int32 nPatternIndex = sExpression.indexOf( '$' );
      39           0 :         while ( nPatternIndex > -1 )
      40             :         {
      41           0 :             const OUString* pReplace = NULL;
      42           0 :             switch ( sExpression[ nPatternIndex + 1 ] )
      43             :             {
      44           0 :             case '$': pReplace = &_rFieldDataSource; break;
      45           0 :             case '1': pReplace = &_rLHS; break;
      46           0 :             case '2': pReplace = &_rRHS; break;
      47           0 :             default: break;
      48             :             }
      49             : 
      50           0 :             if ( pReplace == NULL )
      51             :             {
      52             :                 OSL_FAIL( "ConditionalExpression::assembleExpression: illegal pattern!" );
      53           0 :                 break;
      54             :             }
      55             : 
      56           0 :             sExpression = sExpression.replaceAt( nPatternIndex, 2, *pReplace );
      57           0 :             nPatternIndex = sExpression.indexOf( '$', nPatternIndex + pReplace->getLength() + 1 );
      58             :         }
      59           0 :         return sExpression;
      60             :     }
      61             : 
      62             : 
      63           0 :     bool ConditionalExpression::matchExpression( const OUString& _rExpression, const OUString& _rFieldDataSource, OUString& _out_rLHS, OUString& _out_rRHS ) const
      64             :     {
      65             :         (void)_rExpression;
      66             :         (void)_rFieldDataSource;
      67             :         (void)_out_rLHS;
      68             :         (void)_out_rRHS;
      69             : 
      70             :         // if we had regular expression, the matching would be pretty easy ...
      71             :         // just replace $1 and $2 in the pattern with (.*), and then get them with \1 resp. \2.
      72             :         // Unfortunately, we don't have such a regexp engine ...
      73             : 
      74             :         // Okay, let's start with replacing all $$ in our pattern with the actual field data source
      75           0 :         OUString sMatchExpression( m_sPattern );
      76           0 :         const OUString sFieldDataPattern( "$$" );
      77           0 :         sal_Int32 nIndex( sMatchExpression.indexOf( sFieldDataPattern ) );
      78           0 :         while ( nIndex != -1 )
      79             :         {
      80           0 :             sMatchExpression = sMatchExpression.replaceAt( nIndex, sFieldDataPattern.getLength(), _rFieldDataSource );
      81           0 :             nIndex = sMatchExpression.indexOf( sFieldDataPattern, nIndex + _rFieldDataSource.getLength() );
      82             :         }
      83             : 
      84           0 :         const OUString sLHSPattern( "$1" );
      85           0 :         const OUString sRHSPattern( "$2" );
      86           0 :         sal_Int32 nLHSIndex( sMatchExpression.indexOf( sLHSPattern ) );
      87           0 :         sal_Int32 nRHSIndex( sMatchExpression.indexOf( sRHSPattern ) );
      88             : 
      89             :         // now we should have at most one occurrence of $1 and $2, resp.
      90             :         OSL_ENSURE( sMatchExpression.indexOf( sLHSPattern, nLHSIndex + 1 ) == -1,
      91             :             "ConditionalExpression::matchExpression: unsupported pattern (more than one LHS occurrence)!" );
      92             :         OSL_ENSURE( sMatchExpression.indexOf( sRHSPattern, nRHSIndex + 1 ) == -1,
      93             :             "ConditionalExpression::matchExpression: unsupported pattern (more than one RHS occurrence)!" );
      94             :         // Also, an LHS must be present, and precede the RHS (if present)
      95             :         OSL_ENSURE( ( nLHSIndex != -1 ) && ( ( nLHSIndex < nRHSIndex ) || ( nRHSIndex == -1 ) ),
      96             :             "ConditionalExpression::matchExpression: no LHS, or an RHS preceeding the LHS - this is not supported!" );
      97             : 
      98             :         // up to the occurrence of the LHS (which must exist, see above), the two expressions
      99             :         // must be identical
     100           0 :         if ( _rExpression.getLength() < nLHSIndex )
     101           0 :             return false;
     102           0 :         const OUString sExprPart1( _rExpression.copy( 0, nLHSIndex ) );
     103           0 :         const OUString sMatchExprPart1( sMatchExpression.copy( 0, nLHSIndex ) );
     104           0 :         if ( sExprPart1 != sMatchExprPart1 )
     105             :             // the left-most expression parts do not match
     106           0 :             return false;
     107             : 
     108             :         // after the occurrence of the RHS (or the LHS, if there is no RHS), the two expressions
     109             :         // must be identical, too
     110           0 :         bool bHaveRHS( nRHSIndex != -1 );
     111           0 :         sal_Int32 nRightMostIndex( bHaveRHS ? nRHSIndex : nLHSIndex );
     112           0 :         const OUString sMatchExprPart3( sMatchExpression.copy( nRightMostIndex + 2 ) );
     113           0 :         if ( _rExpression.getLength() < sMatchExprPart3.getLength() )
     114             :             // the expression is not even long enough to hold the right-most part of the match expression
     115           0 :             return false;
     116           0 :         const OUString sExprPart3( _rExpression.copy( _rExpression.getLength() - sMatchExprPart3.getLength() ) );
     117           0 :         if ( sExprPart3 != sMatchExprPart3 )
     118             :             // the right-most expression parts do not match
     119           0 :             return false;
     120             : 
     121             :         // if we don't have an RHS, we're done
     122           0 :         if ( !bHaveRHS )
     123             :         {
     124           0 :             _out_rLHS = _rExpression.copy( sExprPart1.getLength(), _rExpression.getLength() - sExprPart1.getLength() - sExprPart3.getLength() );
     125           0 :             return true;
     126             :         }
     127             : 
     128             :         // strip the match expression by its right-most and left-most part, and by the placeholders $1 and $2
     129           0 :         sal_Int32 nMatchExprPart2Start( nLHSIndex + sLHSPattern.getLength() );
     130             :         OUString sMatchExprPart2 = sMatchExpression.copy(
     131             :             nMatchExprPart2Start,
     132           0 :             sMatchExpression.getLength() - nMatchExprPart2Start - sMatchExprPart3.getLength() - 2
     133           0 :         );
     134             :         // strip the expression by its left-most and right-most part
     135             :         const OUString sExpression( _rExpression.copy(
     136             :             sExprPart1.getLength(),
     137           0 :             _rExpression.getLength() - sExprPart1.getLength() - sExprPart3.getLength()
     138           0 :         ) );
     139             : 
     140           0 :         sal_Int32 nPart2Index = sExpression.indexOf( sMatchExprPart2 );
     141           0 :         if ( nPart2Index == -1 )
     142             :             // the "middle" part of the match expression does not exist in the expression at all
     143           0 :             return false;
     144             : 
     145             :         OSL_ENSURE( sExpression.indexOf( sMatchExprPart2, nPart2Index + 1 ) == -1,
     146             :             "ConditionalExpression::matchExpression: ambiguous matching!" );
     147             :             // if this fires, then we're lost: The middle part exists two times in the expression,
     148             :             // so we cannot reliably determine what's the LHS and what's the RHS.
     149             :             // Well, the whole mechanism is flawed, anyway:
     150             :             // Encoding the field content in the conditional expression will break as soon
     151             :             // as somebody
     152             :             // - assigns a Data Field to a control
     153             :             // - creates a conditional format expression for the control
     154             :             // - assigns another Data Field to the control
     155             :             // - opens the Conditional Format Dialog, again
     156             :             // Here, at the latest, you can see that we need another mechanism, anyway, which does not
     157             :             // rely on those strange expression building/matching
     158             : 
     159           0 :         _out_rLHS = sExpression.copy( 0, nPart2Index );
     160           0 :         _out_rRHS = sExpression.copy( nPart2Index + sMatchExprPart2.getLength() );
     161             : 
     162           0 :         return true;
     163             :     }
     164             : 
     165             : 
     166             :     // = ConditionalExpressionFactory
     167             : 
     168             : 
     169           0 :     size_t ConditionalExpressionFactory::getKnownConditionalExpressions( ConditionalExpressions& _out_rCondExp )
     170             :     {
     171           0 :         ConditionalExpressions aEmpty;
     172           0 :         _out_rCondExp.swap( aEmpty );
     173             : 
     174           0 :         _out_rCondExp[ eBetween ]        = PConditionalExpression( new ConditionalExpression( "AND( ( $$ ) >= ( $1 ); ( $$ ) <= ( $2 ) )" ) );
     175           0 :         _out_rCondExp[ eNotBetween ]     = PConditionalExpression( new ConditionalExpression( "NOT( AND( ( $$ ) >= ( $1 ); ( $$ ) <= ( $2 ) ) )" ) );
     176           0 :         _out_rCondExp[ eEqualTo ]        = PConditionalExpression( new ConditionalExpression( "( $$ ) = ( $1 )" ) );
     177           0 :         _out_rCondExp[ eNotEqualTo ]     = PConditionalExpression( new ConditionalExpression( "( $$ ) <> ( $1 )" ) );
     178           0 :         _out_rCondExp[ eGreaterThan ]    = PConditionalExpression( new ConditionalExpression( "( $$ ) > ( $1 )" ) );
     179           0 :         _out_rCondExp[ eLessThan ]       = PConditionalExpression( new ConditionalExpression( "( $$ ) < ( $1 )" ) );
     180           0 :         _out_rCondExp[ eGreaterOrEqual ] = PConditionalExpression( new ConditionalExpression( "( $$ ) >= ( $1 )" ) );
     181           0 :         _out_rCondExp[ eLessOrEqual ]    = PConditionalExpression( new ConditionalExpression( "( $$ ) <= ( $1 )" ) );
     182             : 
     183           0 :         return _out_rCondExp.size();
     184             :     }
     185             : 
     186             : } // namespace rptui
     187             : 
     188             : 
     189             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10