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

Generated by: LCOV version 1.11