LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - conditio.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 623 1124 55.4 %
Date: 2013-07-09 Functions: 80 114 70.2 %
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 "scitems.hxx"
      21             : #include <sfx2/objsh.hxx>
      22             : #include <svl/itemset.hxx>
      23             : #include <svl/zforlist.hxx>
      24             : #include <rtl/math.hxx>
      25             : #include <unotools/collatorwrapper.hxx>
      26             : 
      27             : #include <com/sun/star/sheet/ConditionOperator2.hpp>
      28             : 
      29             : #include "conditio.hxx"
      30             : #include "formulacell.hxx"
      31             : #include "document.hxx"
      32             : #include "hints.hxx"
      33             : #include "compiler.hxx"
      34             : #include "rechead.hxx"
      35             : #include "rangelst.hxx"
      36             : #include "stlpool.hxx"
      37             : #include "rangenam.hxx"
      38             : #include "colorscale.hxx"
      39             : #include "cellvalue.hxx"
      40             : #include "editutil.hxx"
      41             : #include "tokenarray.hxx"
      42             : 
      43             : using namespace formula;
      44             : //------------------------------------------------------------------------
      45             : 
      46         231 : ScFormatEntry::ScFormatEntry(ScDocument* pDoc):
      47         231 :     mpDoc(pDoc)
      48             : {
      49         231 : }
      50             : 
      51           1 : bool ScFormatEntry::operator==( const ScFormatEntry& r ) const
      52             : {
      53           1 :     if(GetType() != r.GetType())
      54           0 :         return false;
      55             : 
      56           1 :     switch(GetType())
      57             :     {
      58             :         case condformat::CONDITION:
      59           1 :             return static_cast<const ScCondFormatEntry&>(*this) == static_cast<const ScCondFormatEntry&>(r);
      60             :         default:
      61             :             // TODO: implement also this case
      62             :             // actually return false for these cases is not that bad
      63             :             // as soon as databar and color scale are tested we need
      64             :             // to think about the range
      65           0 :             return false;
      66             :     }
      67             : }
      68             : 
      69           0 : void ScFormatEntry::startRendering()
      70             : {
      71           0 : }
      72             : 
      73           0 : void ScFormatEntry::endRendering()
      74             : {
      75           0 : }
      76             : 
      77         125 : static bool lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, sal_uInt16 nRecursion = 0 )
      78             : {
      79         125 :     if (pFormula)
      80             :     {
      81          12 :         pFormula->Reset();
      82             :         FormulaToken* t;
      83          24 :         for( t = pFormula->Next(); t; t = pFormula->Next() )
      84             :         {
      85          18 :             switch( t->GetType() )
      86             :             {
      87             :                 case svDoubleRef:
      88             :                 {
      89           3 :                     ScSingleRefData& rRef2 = static_cast<ScToken*>(t)->GetDoubleRef().Ref2;
      90           3 :                     if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() )
      91           2 :                         return true;
      92             :                 }
      93             :                 // fall through
      94             : 
      95             :                 case svSingleRef:
      96             :                 {
      97           7 :                     ScSingleRefData& rRef1 = static_cast<ScToken*>(t)->GetSingleRef();
      98           7 :                     if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() )
      99           4 :                         return true;
     100             :                 }
     101           3 :                 break;
     102             : 
     103             :                 case svIndex:
     104             :                 {
     105           1 :                     if( t->GetOpCode() == ocName )      // DB areas always absolute
     106           1 :                         if( ScRangeData* pRangeData = pDoc->GetRangeName()->findByIndex( t->GetIndex() ) )
     107           1 :                             if( (nRecursion < 42) && lcl_HasRelRef( pDoc, pRangeData->GetCode(), nRecursion + 1 ) )
     108           0 :                                 return true;
     109             :                 }
     110           1 :                 break;
     111             : 
     112             :                 // #i34474# function result dependent on cell position
     113             :                 case svByte:
     114             :                 {
     115           4 :                     switch( t->GetOpCode() )
     116             :                     {
     117             :                         case ocRow:     // ROW() returns own row index
     118             :                         case ocColumn:  // COLUMN() returns own column index
     119             :                         case ocTable:   // SHEET() returns own sheet index
     120             :                         case ocCell:    // CELL() may return own cell address
     121           0 :                             return true;
     122             : //                        break;
     123             :                         default:
     124             :                         {
     125             :                             // added to avoid warnings
     126             :                         }
     127             :                     }
     128             :                 }
     129           4 :                 break;
     130             : 
     131             :                 default:
     132             :                 {
     133             :                     // added to avoid warnings
     134             :                 }
     135             :             }
     136             :         }
     137             :     }
     138         119 :     return false;
     139             : }
     140             : 
     141           3 : ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
     142             :     ScFormatEntry(r.mpDoc),
     143             :     eOp(r.eOp),
     144             :     nOptions(r.nOptions),
     145             :     nVal1(r.nVal1),
     146             :     nVal2(r.nVal2),
     147             :     aStrVal1(r.aStrVal1),
     148             :     aStrVal2(r.aStrVal2),
     149             :     aStrNmsp1(r.aStrNmsp1),
     150             :     aStrNmsp2(r.aStrNmsp2),
     151             :     eTempGrammar1(r.eTempGrammar1),
     152             :     eTempGrammar2(r.eTempGrammar2),
     153             :     bIsStr1(r.bIsStr1),
     154             :     bIsStr2(r.bIsStr2),
     155             :     pFormula1(NULL),
     156             :     pFormula2(NULL),
     157             :     aSrcPos(r.aSrcPos),
     158             :     aSrcString(r.aSrcString),
     159             :     pFCell1(NULL),
     160             :     pFCell2(NULL),
     161             :     bRelRef1(r.bRelRef1),
     162             :     bRelRef2(r.bRelRef2),
     163             :     bFirstRun(true),
     164           3 :     pCondFormat(r.pCondFormat)
     165             : {
     166             :     //  ScTokenArray copy ctor erzeugt flache Kopie
     167             : 
     168           3 :     if (r.pFormula1)
     169           1 :         pFormula1 = new ScTokenArray( *r.pFormula1 );
     170           3 :     if (r.pFormula2)
     171           0 :         pFormula2 = new ScTokenArray( *r.pFormula2 );
     172             : 
     173             :     //  Formelzellen werden erst bei IsValid angelegt
     174           3 : }
     175             : 
     176          50 : ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntry& r ) :
     177             :     ScFormatEntry(pDocument),
     178             :     eOp(r.eOp),
     179             :     nOptions(r.nOptions),
     180             :     nVal1(r.nVal1),
     181             :     nVal2(r.nVal2),
     182             :     aStrVal1(r.aStrVal1),
     183             :     aStrVal2(r.aStrVal2),
     184             :     aStrNmsp1(r.aStrNmsp1),
     185             :     aStrNmsp2(r.aStrNmsp2),
     186             :     eTempGrammar1(r.eTempGrammar1),
     187             :     eTempGrammar2(r.eTempGrammar2),
     188             :     bIsStr1(r.bIsStr1),
     189             :     bIsStr2(r.bIsStr2),
     190             :     pFormula1(NULL),
     191             :     pFormula2(NULL),
     192             :     aSrcPos(r.aSrcPos),
     193             :     aSrcString(r.aSrcString),
     194             :     pFCell1(NULL),
     195             :     pFCell2(NULL),
     196             :     bRelRef1(r.bRelRef1),
     197             :     bRelRef2(r.bRelRef2),
     198             :     bFirstRun(true),
     199          50 :     pCondFormat(r.pCondFormat)
     200             : {
     201             :     // echte Kopie der Formeln (fuer Ref-Undo)
     202             : 
     203          50 :     if (r.pFormula1)
     204          27 :         pFormula1 = r.pFormula1->Clone();
     205          50 :     if (r.pFormula2)
     206          13 :         pFormula2 = r.pFormula2->Clone();
     207             : 
     208             :     //  Formelzellen werden erst bei IsValid angelegt
     209             :     //! im Clipboard nicht - dann vorher interpretieren !!!
     210          50 : }
     211             : 
     212         103 : ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
     213             :         const OUString& rExpr1, const OUString& rExpr2, ScDocument* pDocument, const ScAddress& rPos,
     214             :         const OUString& rExprNmsp1, const OUString& rExprNmsp2,
     215             :         FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
     216             :     ScFormatEntry(pDocument),
     217             :     eOp(eOper),
     218             :     nOptions(0),
     219             :     nVal1(0.0),
     220             :     nVal2(0.0),
     221             :     aStrNmsp1(rExprNmsp1),
     222             :     aStrNmsp2(rExprNmsp2),
     223             :     eTempGrammar1(eGrammar1),
     224             :     eTempGrammar2(eGrammar2),
     225             :     bIsStr1(false),
     226             :     bIsStr2(false),
     227             :     pFormula1(NULL),
     228             :     pFormula2(NULL),
     229             :     aSrcPos(rPos),
     230             :     pFCell1(NULL),
     231             :     pFCell2(NULL),
     232             :     bRelRef1(false),
     233             :     bRelRef2(false),
     234             :     bFirstRun(true),
     235         103 :     pCondFormat(NULL)
     236             : {
     237         103 :     Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, false );
     238             : 
     239             :     //  Formelzellen werden erst bei IsValid angelegt
     240         103 : }
     241             : 
     242          29 : ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
     243             :                                 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
     244             :                                 ScDocument* pDocument, const ScAddress& rPos ) :
     245             :     ScFormatEntry(pDocument),
     246             :     eOp(eOper),
     247             :     nOptions(0),
     248             :     nVal1(0.0),
     249             :     nVal2(0.0),
     250             :     eTempGrammar1(FormulaGrammar::GRAM_DEFAULT),
     251             :     eTempGrammar2(FormulaGrammar::GRAM_DEFAULT),
     252             :     bIsStr1(false),
     253             :     bIsStr2(false),
     254             :     pFormula1(NULL),
     255             :     pFormula2(NULL),
     256             :     aSrcPos(rPos),
     257             :     pFCell1(NULL),
     258             :     pFCell2(NULL),
     259             :     bRelRef1(false),
     260             :     bRelRef2(false),
     261             :     bFirstRun(true),
     262          29 :     pCondFormat(NULL)
     263             : {
     264          29 :     if ( pArr1 )
     265             :     {
     266          27 :         pFormula1 = new ScTokenArray( *pArr1 );
     267          27 :         if ( pFormula1->GetLen() == 1 )
     268             :         {
     269             :             // einzelne (konstante Zahl) ?
     270          27 :             FormulaToken* pToken = pFormula1->First();
     271          27 :             if ( pToken->GetOpCode() == ocPush )
     272             :             {
     273          26 :                 if ( pToken->GetType() == svDouble )
     274             :                 {
     275          24 :                     nVal1 = pToken->GetDouble();
     276          24 :                     DELETEZ(pFormula1);             // nicht als Formel merken
     277             :                 }
     278           2 :                 else if ( pToken->GetType() == svString )
     279             :                 {
     280           0 :                     bIsStr1 = true;
     281           0 :                     aStrVal1 = pToken->GetString();
     282           0 :                     DELETEZ(pFormula1);             // nicht als Formel merken
     283             :                 }
     284             :             }
     285             :         }
     286          27 :         bRelRef1 = lcl_HasRelRef( mpDoc, pFormula1 );
     287             :     }
     288          29 :     if ( pArr2 )
     289             :     {
     290           1 :         pFormula2 = new ScTokenArray( *pArr2 );
     291           1 :         if ( pFormula2->GetLen() == 1 )
     292             :         {
     293             :             // einzelne (konstante Zahl) ?
     294           1 :             FormulaToken* pToken = pFormula2->First();
     295           1 :             if ( pToken->GetOpCode() == ocPush )
     296             :             {
     297           1 :                 if ( pToken->GetType() == svDouble )
     298             :                 {
     299           0 :                     nVal2 = pToken->GetDouble();
     300           0 :                     DELETEZ(pFormula2);             // nicht als Formel merken
     301             :                 }
     302           1 :                 else if ( pToken->GetType() == svString )
     303             :                 {
     304           0 :                     bIsStr2 = true;
     305           0 :                     aStrVal2 = pToken->GetString();
     306           0 :                     DELETEZ(pFormula2);             // nicht als Formel merken
     307             :                 }
     308             :             }
     309             :         }
     310           1 :         bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     311             :     }
     312             : 
     313             :     //  formula cells are created at IsValid
     314          29 : }
     315             : 
     316         368 : ScConditionEntry::~ScConditionEntry()
     317             : {
     318         184 :     delete pFCell1;
     319         184 :     delete pFCell2;
     320             : 
     321         184 :     delete pFormula1;
     322         184 :     delete pFormula2;
     323         184 : }
     324             : 
     325         140 : void ScConditionEntry::Compile( const OUString& rExpr1, const OUString& rExpr2,
     326             :         const OUString& rExprNmsp1, const OUString& rExprNmsp2,
     327             :         FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2, bool bTextToReal )
     328             : {
     329         140 :     if ( !rExpr1.isEmpty() || !rExpr2.isEmpty() )
     330             :     {
     331          87 :         ScCompiler aComp( mpDoc, aSrcPos );
     332             : 
     333          87 :         if ( !rExpr1.isEmpty() )
     334             :         {
     335          87 :             aComp.SetGrammar( eGrammar1 );
     336          87 :             if ( mpDoc->IsImportingXML() && !bTextToReal )
     337             :             {
     338             :                 //  temporary formula string as string tokens
     339             :                 //! merge with lcl_ScDocFunc_CreateTokenArrayXML
     340          37 :                 pFormula1 = new ScTokenArray;
     341          37 :                 pFormula1->AddStringXML( rExpr1 );
     342             :                 // bRelRef1 is set when the formula is compiled again (CompileXML)
     343             :             }
     344             :             else
     345             :             {
     346          50 :                 pFormula1 = aComp.CompileString( rExpr1, rExprNmsp1 );
     347          50 :                 if ( pFormula1->GetLen() == 1 )
     348             :                 {
     349             :                     // einzelne (konstante Zahl) ?
     350          46 :                     FormulaToken* pToken = pFormula1->First();
     351          46 :                     if ( pToken->GetOpCode() == ocPush )
     352             :                     {
     353          46 :                         if ( pToken->GetType() == svDouble )
     354             :                         {
     355          43 :                             nVal1 = pToken->GetDouble();
     356          43 :                             DELETEZ(pFormula1);             // nicht als Formel merken
     357             :                         }
     358           3 :                         else if ( pToken->GetType() == svString )
     359             :                         {
     360           0 :                             bIsStr1 = true;
     361           0 :                             aStrVal1 = pToken->GetString();
     362           0 :                             DELETEZ(pFormula1);             // nicht als Formel merken
     363             :                         }
     364             :                     }
     365             :                 }
     366          50 :                 bRelRef1 = lcl_HasRelRef( mpDoc, pFormula1 );
     367             :             }
     368             :         }
     369             : 
     370          87 :         if ( !rExpr2.isEmpty() )
     371             :         {
     372          59 :             aComp.SetGrammar( eGrammar2 );
     373          59 :             if ( mpDoc->IsImportingXML() && !bTextToReal )
     374             :             {
     375             :                 //  temporary formula string as string tokens
     376             :                 //! merge with lcl_ScDocFunc_CreateTokenArrayXML
     377          13 :                 pFormula2 = new ScTokenArray;
     378          13 :                 pFormula2->AddStringXML( rExpr2 );
     379             :                 // bRelRef2 is set when the formula is compiled again (CompileXML)
     380             :             }
     381             :             else
     382             :             {
     383          46 :                 pFormula2 = aComp.CompileString( rExpr2, rExprNmsp2 );
     384          46 :                 if ( pFormula2->GetLen() == 1 )
     385             :                 {
     386             :                     // einzelne (konstante Zahl) ?
     387          46 :                     FormulaToken* pToken = pFormula2->First();
     388          46 :                     if ( pToken->GetOpCode() == ocPush )
     389             :                     {
     390          46 :                         if ( pToken->GetType() == svDouble )
     391             :                         {
     392          46 :                             nVal2 = pToken->GetDouble();
     393          46 :                             DELETEZ(pFormula2);             // nicht als Formel merken
     394             :                         }
     395           0 :                         else if ( pToken->GetType() == svString )
     396             :                         {
     397           0 :                             bIsStr2 = true;
     398           0 :                             aStrVal2 = pToken->GetString();
     399           0 :                             DELETEZ(pFormula2);             // nicht als Formel merken
     400             :                         }
     401             :                     }
     402             :                 }
     403          46 :                 bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     404             :             }
     405          87 :         }
     406             :     }
     407         140 : }
     408             : 
     409         846 : void ScConditionEntry::MakeCells( const ScAddress& rPos )           // Formelzellen anlegen
     410             : {
     411         846 :     if ( !mpDoc->IsClipOrUndo() )            // nie im Clipboard rechnen!
     412             :     {
     413         846 :         if ( pFormula1 && !pFCell1 && !bRelRef1 )
     414             :         {
     415           3 :             pFCell1 = new ScFormulaCell( mpDoc, rPos, pFormula1 );
     416           3 :             pFCell1->StartListeningTo( mpDoc );
     417             :         }
     418             : 
     419         846 :         if ( pFormula2 && !pFCell2 && !bRelRef2 )
     420             :         {
     421           0 :             pFCell2 = new ScFormulaCell( mpDoc, rPos, pFormula2 );
     422           0 :             pFCell2->StartListeningTo( mpDoc );
     423             :         }
     424             :     }
     425         846 : }
     426             : 
     427          35 : void ScConditionEntry::SetIgnoreBlank(bool bSet)
     428             : {
     429             :     //  Das Bit SC_COND_NOBLANKS wird gesetzt, wenn Blanks nicht ignoriert werden
     430             :     //  (nur bei Gueltigkeit)
     431             : 
     432          35 :     if (bSet)
     433          34 :         nOptions &= ~SC_COND_NOBLANKS;
     434             :     else
     435           1 :         nOptions |= SC_COND_NOBLANKS;
     436          35 : }
     437             : 
     438           0 : void ScConditionEntry::CompileAll()
     439             : {
     440             :     //  Formelzellen loeschen, dann wird beim naechsten IsValid neu kompiliert
     441             : 
     442           0 :     DELETEZ(pFCell1);
     443           0 :     DELETEZ(pFCell2);
     444           0 : }
     445             : 
     446          37 : void ScConditionEntry::CompileXML()
     447             : {
     448             :     //  First parse the formula source position if it was stored as text
     449             : 
     450          37 :     if ( !aSrcString.isEmpty() )
     451             :     {
     452          37 :         ScAddress aNew;
     453             :         /* XML is always in OOo:A1 format, although R1C1 would be more amenable
     454             :          * to compression */
     455          37 :         if ( aNew.Parse( aSrcString, mpDoc ) & SCA_VALID )
     456          37 :             aSrcPos = aNew;
     457             :         // if the position is invalid, there isn't much we can do at this time
     458          37 :         aSrcString = OUString();
     459             :     }
     460             : 
     461             :     //  Convert the text tokens that were created during XML import into real tokens.
     462             : 
     463             :     Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
     464             :              GetExpression(aSrcPos, 1, 0, eTempGrammar2),
     465          37 :              aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true );
     466          37 : }
     467             : 
     468          51 : void ScConditionEntry::SetSrcString( const OUString& rNew )
     469             : {
     470             :     // aSrcString is only evaluated in CompileXML
     471             :     SAL_WARN_IF( !mpDoc->IsImportingXML(), "sc", "SetSrcString is only valid for XML import" );
     472             : 
     473          51 :     aSrcString = rNew;
     474          51 : }
     475             : 
     476           0 : void ScConditionEntry::SetFormula1( const ScTokenArray& rArray )
     477             : {
     478           0 :     DELETEZ( pFormula1 );
     479           0 :     if( rArray.GetLen() > 0 )
     480             :     {
     481           0 :         pFormula1 = new ScTokenArray( rArray );
     482           0 :         bRelRef1 = lcl_HasRelRef( mpDoc, pFormula1 );
     483             :     }
     484           0 : }
     485             : 
     486           0 : void ScConditionEntry::SetFormula2( const ScTokenArray& rArray )
     487             : {
     488           0 :     DELETEZ( pFormula2 );
     489           0 :     if( rArray.GetLen() > 0 )
     490             :     {
     491           0 :         pFormula2 = new ScTokenArray( rArray );
     492           0 :         bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     493             :     }
     494           0 : }
     495             : 
     496           0 : static void lcl_CondUpdateInsertTab( ScTokenArray& rCode, SCTAB nInsTab, SCTAB nPosTab, bool& rChanged, SCTAB nTabs )
     497             : {
     498             :     //  Insert table: only update absolute table references.
     499             :     //  (Similar to ScCompiler::UpdateInsertTab with bIsName=true, result is the same as for named ranges)
     500             :     //  For deleting, ScCompiler::UpdateDeleteTab is used because of the handling of invalid references.
     501             : 
     502           0 :     rCode.Reset();
     503           0 :     ScToken* p = static_cast<ScToken*>(rCode.GetNextReference());
     504           0 :     while( p )
     505             :     {
     506           0 :         ScSingleRefData& rRef1 = p->GetSingleRef();
     507           0 :         if ( !rRef1.IsTabRel() && nInsTab <= rRef1.nTab )
     508             :         {
     509           0 :             rRef1.nTab += nTabs;
     510           0 :             rRef1.nRelTab = rRef1.nTab - nPosTab;
     511           0 :             rChanged = true;
     512             :         }
     513           0 :         if( p->GetType() == svDoubleRef )
     514             :         {
     515           0 :             ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
     516           0 :             if ( !rRef2.IsTabRel() && nInsTab <= rRef2.nTab )
     517             :             {
     518           0 :                 rRef2.nTab += nTabs;
     519           0 :                 rRef2.nRelTab = rRef2.nTab - nPosTab;
     520           0 :                 rChanged = true;
     521             :             }
     522             :         }
     523           0 :         p = static_cast<ScToken*>(rCode.GetNextReference());
     524             :     }
     525           0 : }
     526             : 
     527          15 : void ScConditionEntry::UpdateReference( UpdateRefMode eUpdateRefMode,
     528             :                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
     529             : {
     530          15 :     bool bInsertTab = ( eUpdateRefMode == URM_INSDEL && nDz >= 1 );
     531          15 :     bool bDeleteTab = ( eUpdateRefMode == URM_INSDEL && nDz <= -1 );
     532          15 :     if(pCondFormat)
     533           1 :         aSrcPos = pCondFormat->GetRange().Combine().aStart;
     534          15 :     ScAddress aOldSrcPos = aSrcPos;
     535          15 :     bool bChangedPos = false;
     536          15 :     if(eUpdateRefMode == URM_INSDEL && rRange.In(aSrcPos))
     537             :     {
     538           1 :         aSrcPos.Move(nDx, nDy, nDz);
     539           1 :         bChangedPos = aSrcPos != aOldSrcPos;
     540             :     }
     541             : 
     542          15 :     if (pFormula1)
     543             :     {
     544           1 :         bool bChanged1 = false;
     545           1 :         if ( bInsertTab )
     546           0 :             lcl_CondUpdateInsertTab( *pFormula1, rRange.aStart.Tab(), aOldSrcPos.Tab(), bChanged1, nDz );
     547             :         else
     548             :         {
     549           1 :             ScCompiler aComp( mpDoc, aSrcPos, *pFormula1 );
     550           1 :             aComp.SetGrammar(mpDoc->GetGrammar());
     551           1 :             if ( bDeleteTab )
     552           0 :                 aComp.UpdateDeleteTab( rRange.aStart.Tab(), false, true, bChanged1, static_cast<SCTAB>(-1 * nDz) );
     553             :             else
     554             :             {
     555             :                 bool bSizeChanged;
     556             :                 aComp.UpdateReference( eUpdateRefMode, aOldSrcPos, rRange, nDx,
     557           1 :                         nDy, nDz, bChanged1, bSizeChanged );
     558           1 :             }
     559             :         }
     560             : 
     561           1 :         if (bChanged1 || bChangedPos)
     562           1 :             DELETEZ(pFCell1);       // is created again in IsValid
     563             :     }
     564          15 :     if (pFormula2)
     565             :     {
     566           0 :         bool bChanged2 = false;
     567           0 :         if ( bInsertTab )
     568           0 :             lcl_CondUpdateInsertTab( *pFormula2, rRange.aStart.Tab(), aOldSrcPos.Tab(), bChanged2, nDz );
     569             :         else
     570             :         {
     571           0 :             ScCompiler aComp( mpDoc, aSrcPos, *pFormula2);
     572           0 :             aComp.SetGrammar(mpDoc->GetGrammar());
     573           0 :             if ( bDeleteTab )
     574           0 :                 aComp.UpdateDeleteTab( rRange.aStart.Tab(), false, true, bChanged2, static_cast<SCTAB>(-1*nDz) );
     575             :             else
     576             :             {
     577             :                 bool bSizeChanged;
     578             :                 aComp.UpdateReference( eUpdateRefMode, aOldSrcPos, rRange, nDx,
     579           0 :                         nDy, nDz, bChanged2, bSizeChanged );
     580           0 :             }
     581             :         }
     582             : 
     583           0 :         if (bChanged2 || bChangedPos)
     584           0 :             DELETEZ(pFCell2);       // is created again in IsValid
     585             :     }
     586          15 : }
     587             : 
     588           0 : void ScConditionEntry::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
     589             : {
     590           0 :     if (pFormula1)
     591             :     {
     592           0 :         ScCompiler aComp( mpDoc, aSrcPos, *pFormula1);
     593           0 :         aComp.SetGrammar(mpDoc->GetGrammar());
     594           0 :         aComp.UpdateMoveTab(nOldPos, nNewPos, true );
     595           0 :         DELETEZ(pFCell1);
     596             :     }
     597           0 :     if (pFormula2)
     598             :     {
     599           0 :         ScCompiler aComp( mpDoc, aSrcPos, *pFormula2);
     600           0 :         aComp.SetGrammar(mpDoc->GetGrammar());
     601           0 :         aComp.UpdateMoveTab(nOldPos, nNewPos, true );
     602           0 :         DELETEZ(pFCell2);
     603             :     }
     604           0 : }
     605             : 
     606             : //! als Vergleichsoperator ans TokenArray ???
     607             : 
     608          95 : static bool lcl_IsEqual( const ScTokenArray* pArr1, const ScTokenArray* pArr2 )
     609             : {
     610             :     //  verglichen wird nur das nicht-UPN Array
     611             : 
     612          95 :     if ( pArr1 && pArr2 )
     613             :     {
     614          22 :         sal_uInt16 nLen = pArr1->GetLen();
     615          22 :         if ( pArr2->GetLen() != nLen )
     616           0 :             return false;
     617             : 
     618          22 :         FormulaToken** ppToken1 = pArr1->GetArray();
     619          22 :         FormulaToken** ppToken2 = pArr2->GetArray();
     620          43 :         for (sal_uInt16 i=0; i<nLen; i++)
     621             :         {
     622          44 :             if ( ppToken1[i] != ppToken2[i] &&
     623          22 :                  !(*ppToken1[i] == *ppToken2[i]) )
     624           1 :                 return false;                       // Unterschied
     625             :         }
     626          21 :         return true;                    // alle Eintraege gleich
     627             :     }
     628             :     else
     629          73 :         return !pArr1 && !pArr2;        // beide 0 -> gleich
     630             : }
     631             : 
     632         115 : int ScConditionEntry::operator== ( const ScConditionEntry& r ) const
     633             : {
     634         218 :     bool bEq = (eOp == r.eOp && nOptions == r.nOptions &&
     635         210 :                 lcl_IsEqual( pFormula1, r.pFormula1 ) &&
     636         162 :                 lcl_IsEqual( pFormula2, r.pFormula2 ));
     637         115 :     if (bEq)
     638             :     {
     639             :         // for formulas, the reference positions must be compared, too
     640             :         // (including aSrcString, for inserting the entries during XML import)
     641          47 :         if ( ( pFormula1 || pFormula2 ) && ( aSrcPos != r.aSrcPos || aSrcString != r.aSrcString ) )
     642           0 :             bEq = false;
     643             : 
     644             :         //  wenn keine Formeln, Werte vergleichen
     645          47 :         if ( !pFormula1 && ( nVal1 != r.nVal1 || aStrVal1 != r.aStrVal1 || bIsStr1 != r.bIsStr1 ) )
     646           7 :             bEq = false;
     647          47 :         if ( !pFormula2 && ( nVal2 != r.nVal2 || aStrVal2 != r.aStrVal2 || bIsStr2 != r.bIsStr2 ) )
     648           7 :             bEq = false;
     649             :     }
     650             : 
     651         115 :     return bEq;
     652             : }
     653             : 
     654        2704 : void ScConditionEntry::Interpret( const ScAddress& rPos )
     655             : {
     656             :     //  Formelzellen anlegen
     657             :     //  dabei koennen neue Broadcaster (Note-Zellen) ins Dokument eingefuegt werden !!!!
     658             : 
     659        2704 :     if ( ( pFormula1 && !pFCell1 ) || ( pFormula2 && !pFCell2 ) )
     660         846 :         MakeCells( rPos );
     661             : 
     662             :     //  Formeln auswerten
     663             : 
     664        2704 :     bool bDirty = false;        //! 1 und 2 getrennt ???
     665             : 
     666        2704 :     ScFormulaCell* pTemp1 = NULL;
     667        2704 :     ScFormulaCell* pEff1 = pFCell1;
     668        2704 :     if ( bRelRef1 )
     669             :     {
     670         843 :         pTemp1 = new ScFormulaCell( mpDoc, rPos, pFormula1 );    // ohne Listening
     671         843 :         pEff1 = pTemp1;
     672             :     }
     673        2704 :     if ( pEff1 )
     674             :     {
     675        2021 :         if (!pEff1->IsRunning())        // keine 522 erzeugen
     676             :         {
     677             :             //! Changed statt Dirty abfragen !!!
     678        2021 :             if (pEff1->GetDirty() && !bRelRef1 && mpDoc->GetAutoCalc())
     679           3 :                 bDirty = true;
     680        2021 :             if (pEff1->IsValue())
     681             :             {
     682        2021 :                 bIsStr1 = false;
     683        2021 :                 nVal1 = pEff1->GetValue();
     684        2021 :                 aStrVal1 = OUString();
     685             :             }
     686             :             else
     687             :             {
     688           0 :                 bIsStr1 = true;
     689           0 :                 aStrVal1 = pEff1->GetString();
     690           0 :                 nVal1 = 0.0;
     691             :             }
     692             :         }
     693             :     }
     694        2704 :     delete pTemp1;
     695             : 
     696        2704 :     ScFormulaCell* pTemp2 = NULL;
     697        2704 :     ScFormulaCell* pEff2 = pFCell2; //@ 1!=2
     698        2704 :     if ( bRelRef2 )
     699             :     {
     700          98 :         pTemp2 = new ScFormulaCell( mpDoc, rPos, pFormula2 );    // ohne Listening
     701          98 :         pEff2 = pTemp2;
     702             :     }
     703        2704 :     if ( pEff2 )
     704             :     {
     705          98 :         if (!pEff2->IsRunning())        // keine 522 erzeugen
     706             :         {
     707          98 :             if (pEff2->GetDirty() && !bRelRef2 && mpDoc->GetAutoCalc())
     708           0 :                 bDirty = true;
     709          98 :             if (pEff2->IsValue())
     710             :             {
     711          98 :                 bIsStr2 = false;
     712          98 :                 nVal2 = pEff2->GetValue();
     713          98 :                 aStrVal2 = OUString();
     714             :             }
     715             :             else
     716             :             {
     717           0 :                 bIsStr2 = true;
     718           0 :                 aStrVal2 = pEff2->GetString();
     719           0 :                 nVal2 = 0.0;
     720             :             }
     721             :         }
     722             :     }
     723        2704 :     delete pTemp2;
     724             : 
     725             :     //  wenn IsRunning, bleiben die letzten Werte erhalten
     726             : 
     727        2704 :     if (bDirty && !bFirstRun)
     728             :     {
     729             :         //  bei bedingten Formaten neu painten
     730             : 
     731           0 :         DataChanged( NULL );    // alles
     732             :     }
     733             : 
     734        2704 :     bFirstRun = false;
     735        2704 : }
     736             : 
     737        3376 : static bool lcl_GetCellContent( ScRefCellValue& rCell, bool bIsStr1, double& rArg, OUString& rArgStr )
     738             : {
     739             : 
     740        3376 :     if (rCell.isEmpty())
     741        2003 :         return !bIsStr1;
     742             : 
     743        1373 :     bool bVal = true;
     744             : 
     745        1373 :     switch (rCell.meType)
     746             :     {
     747             :         case CELLTYPE_VALUE:
     748        1373 :             rArg = rCell.mfValue;
     749        1373 :         break;
     750             :         case CELLTYPE_FORMULA:
     751             :         {
     752           0 :             bVal = rCell.mpFormula->IsValue();
     753           0 :             if (bVal)
     754           0 :                 rArg = rCell.mpFormula->GetValue();
     755             :             else
     756           0 :                 rArgStr = rCell.mpFormula->GetString();
     757             :         }
     758           0 :         break;
     759             :         case CELLTYPE_STRING:
     760             :         case CELLTYPE_EDIT:
     761           0 :             bVal = false;
     762           0 :             if (rCell.meType == CELLTYPE_STRING)
     763           0 :                 rArgStr = *rCell.mpString;
     764           0 :             else if (rCell.mpEditText)
     765           0 :                 rArgStr = ScEditUtil::GetString(*rCell.mpEditText);
     766           0 :         break;
     767             :         default:
     768             :             ;
     769             :     }
     770             : 
     771        1373 :     return bVal;
     772             : }
     773             : 
     774         672 : void ScConditionEntry::FillCache() const
     775             : {
     776         672 :     if(!mpCache)
     777             :     {
     778          32 :         const ScRangeList& rRanges = pCondFormat->GetRange();
     779          32 :         mpCache.reset(new ScConditionEntryCache);
     780          32 :         size_t nListCount = rRanges.size();
     781          64 :         for( size_t i = 0; i < nListCount; i++ )
     782             :         {
     783          32 :             const ScRange *aRange = rRanges[i];
     784          32 :             SCROW nRow = aRange->aEnd.Row();
     785          32 :             SCCOL nCol = aRange->aEnd.Col();
     786          32 :             SCCOL nColStart = aRange->aStart.Col();
     787          32 :             SCROW nRowStart = aRange->aStart.Row();
     788          32 :             SCTAB nTab = aRange->aStart.Tab();
     789             : 
     790             :             // temporary fix to workaorund slow duplicate entry
     791             :             // conditions, prevent to use a whole row
     792          32 :             if(nRow == MAXROW)
     793             :             {
     794           0 :                 bool bShrunk = false;
     795             :                 mpDoc->ShrinkToUsedDataArea(bShrunk, nTab, nColStart, nRowStart,
     796           0 :                         nCol, nRow, false);
     797             :             }
     798             : 
     799         704 :             for( SCROW r = nRowStart; r <= nRow; r++ )
     800        1344 :                 for( SCCOL c = nColStart; c <= nCol; c++ )
     801             :                 {
     802         672 :                     ScRefCellValue aCell;
     803         672 :                     aCell.assign(*mpDoc, ScAddress(c, r, nTab));
     804         672 :                     if (aCell.isEmpty())
     805           0 :                         continue;
     806             : 
     807         672 :                     double nVal = 0.0;
     808        1344 :                     OUString aStr;
     809         672 :                     if (!lcl_GetCellContent(aCell, false, nVal, aStr))
     810             :                     {
     811             :                         std::pair<ScConditionEntryCache::StringCacheType::iterator, bool> aResult =
     812           0 :                             mpCache->maStrings.insert(
     813           0 :                                 ScConditionEntryCache::StringCacheType::value_type(aStr, 1));
     814             : 
     815           0 :                         if(!aResult.second)
     816           0 :                             aResult.first->second++;
     817             :                     }
     818             :                     else
     819             :                     {
     820             :                         std::pair<ScConditionEntryCache::ValueCacheType::iterator, bool> aResult =
     821         672 :                             mpCache->maValues.insert(
     822        1344 :                                 ScConditionEntryCache::ValueCacheType::value_type(nVal, 1));
     823             : 
     824         672 :                         if(!aResult.second)
     825         104 :                             aResult.first->second++;
     826             : 
     827         672 :                         ++(mpCache->nValueItems);
     828             :                     }
     829         672 :                 }
     830             :         }
     831             :     }
     832         672 : }
     833             : 
     834           0 : bool ScConditionEntry::IsDuplicate( double nArg, const OUString& rStr ) const
     835             : {
     836           0 :     FillCache();
     837             : 
     838           0 :     if(rStr.isEmpty())
     839             :     {
     840           0 :         ScConditionEntryCache::ValueCacheType::iterator itr = mpCache->maValues.find(nArg);
     841           0 :         if(itr == mpCache->maValues.end())
     842           0 :             return false;
     843             :         else
     844             :         {
     845           0 :             if(itr->second > 1)
     846           0 :                 return true;
     847             :             else
     848           0 :                 return false;
     849             :         }
     850             :     }
     851             :     else
     852             :     {
     853           0 :         ScConditionEntryCache::StringCacheType::iterator itr = mpCache->maStrings.find(rStr);
     854           0 :         if(itr == mpCache->maStrings.end())
     855           0 :             return false;
     856             :         else
     857             :         {
     858           0 :             if(itr->second > 1)
     859           0 :                 return true;
     860             :             else
     861           0 :                 return false;
     862             :         }
     863             :     }
     864             : }
     865             : 
     866          84 : bool ScConditionEntry::IsTopNElement( double nArg ) const
     867             : {
     868          84 :     FillCache();
     869             : 
     870          84 :     if(mpCache->nValueItems <= nVal1)
     871           0 :         return true;
     872             : 
     873          84 :     size_t nCells = 0;
     874         528 :     for(ScConditionEntryCache::ValueCacheType::const_reverse_iterator itr = mpCache->maValues.rbegin(),
     875          84 :             itrEnd = mpCache->maValues.rend(); itr != itrEnd; ++itr)
     876             :     {
     877         444 :         if(nCells >= nVal1)
     878         148 :             return false;
     879         380 :         if(itr->first <= nArg)
     880          20 :             return true;
     881         360 :         nCells += itr->second;
     882             :     }
     883             : 
     884           0 :     return true;
     885             : }
     886             : 
     887          84 : bool ScConditionEntry::IsBottomNElement( double nArg ) const
     888             : {
     889          84 :     FillCache();
     890             : 
     891          84 :     if(mpCache->nValueItems <= nVal1)
     892           0 :         return true;
     893             : 
     894          84 :     size_t nCells = 0;
     895         372 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     896          84 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     897             :     {
     898         288 :         if(nCells >= nVal1)
     899         144 :             return false;
     900         228 :         if(itr->first >= nArg)
     901          24 :             return true;
     902         204 :         nCells += itr->second;
     903             :     }
     904             : 
     905           0 :     return true;
     906             : }
     907             : 
     908          84 : bool ScConditionEntry::IsTopNPercent( double nArg ) const
     909             : {
     910          84 :     FillCache();
     911             : 
     912          84 :     size_t nCells = 0;
     913          84 :     size_t nLimitCells = static_cast<size_t>(mpCache->nValueItems*nVal1/100);
     914         324 :     for(ScConditionEntryCache::ValueCacheType::const_reverse_iterator itr = mpCache->maValues.rbegin(),
     915          84 :             itrEnd = mpCache->maValues.rend(); itr != itrEnd; ++itr)
     916             :     {
     917         240 :         if(nCells >= nLimitCells)
     918         160 :             return false;
     919         164 :         if(itr->first <= nArg)
     920           8 :             return true;
     921         156 :         nCells += itr->second;
     922             :     }
     923             : 
     924           0 :     return true;
     925             : }
     926             : 
     927          84 : bool ScConditionEntry::IsBottomNPercent( double nArg ) const
     928             : {
     929          84 :     FillCache();
     930             : 
     931          84 :     size_t nCells = 0;
     932          84 :     size_t nLimitCells = static_cast<size_t>(mpCache->nValueItems*nVal1/100);
     933         312 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     934          84 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     935             :     {
     936         228 :         if(nCells >= nLimitCells)
     937         152 :             return false;
     938         160 :         if(itr->first >= nArg)
     939          16 :             return true;
     940         144 :         nCells += itr->second;
     941             :     }
     942             : 
     943           0 :     return true;
     944             : }
     945             : 
     946         168 : bool ScConditionEntry::IsBelowAverage( double nArg, bool bEqual ) const
     947             : {
     948         168 :     FillCache();
     949             : 
     950         168 :     double nSum = 0;
     951        3276 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     952         168 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     953             :     {
     954        2940 :         nSum += itr->first * itr->second;
     955             :     }
     956             : 
     957         168 :     if(bEqual)
     958          84 :         return (nArg <= nSum/mpCache->nValueItems);
     959             :     else
     960          84 :         return (nArg < nSum/mpCache->nValueItems);
     961             : }
     962             : 
     963         168 : bool ScConditionEntry::IsAboveAverage( double nArg, bool bEqual ) const
     964             : {
     965         168 :     FillCache();
     966             : 
     967         168 :     double nSum = 0;
     968        3276 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     969         168 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     970             :     {
     971        2940 :         nSum += itr->first * itr->second;
     972             :     }
     973             : 
     974         168 :     if(bEqual)
     975          84 :         return (nArg >= nSum/mpCache->nValueItems);
     976             :     else
     977          84 :         return (nArg > nSum/mpCache->nValueItems);
     978             : }
     979             : 
     980           0 : bool ScConditionEntry::IsError( const ScAddress& rPos ) const
     981             : {
     982           0 :     switch (mpDoc->GetCellType(rPos))
     983             :     {
     984             :         case CELLTYPE_VALUE:
     985           0 :             return false;
     986             :         case CELLTYPE_FORMULA:
     987             :         {
     988           0 :             ScFormulaCell* pFormulaCell = const_cast<ScFormulaCell*>(mpDoc->GetFormulaCell(rPos));
     989           0 :             if(pFormulaCell->GetErrCode())
     990           0 :                 return true;
     991             :         }
     992             :         case CELLTYPE_STRING:
     993             :         case CELLTYPE_EDIT:
     994           0 :             return false;
     995             :         default:
     996           0 :             break;
     997             :     }
     998           0 :     return false;
     999             : }
    1000             : 
    1001        2704 : bool ScConditionEntry::IsValid( double nArg, const ScAddress& rPos ) const
    1002             : {
    1003             :     //  Interpret muss schon gerufen sein
    1004             : 
    1005        2704 :     if ( bIsStr1 )
    1006             :     {
    1007           0 :         switch( eOp )
    1008             :         {
    1009             :             case SC_COND_BEGINS_WITH:
    1010             :             case SC_COND_ENDS_WITH:
    1011             :             case SC_COND_CONTAINS_TEXT:
    1012             :             case SC_COND_NOT_CONTAINS_TEXT:
    1013           0 :                 break;
    1014             :             case SC_COND_NOTEQUAL:
    1015           0 :                 return true;
    1016             :             default:
    1017           0 :                 return false;
    1018             :         }
    1019             :     }
    1020             : 
    1021        2704 :     if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
    1022         102 :         if ( bIsStr2 )
    1023           0 :             return false;
    1024             : 
    1025        2704 :     double nComp1 = nVal1;      // Kopie, damit vertauscht werden kann
    1026        2704 :     double nComp2 = nVal2;
    1027             : 
    1028        2704 :     if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
    1029         102 :         if ( nComp1 > nComp2 )
    1030             :         {
    1031             :             //  richtige Reihenfolge fuer Wertebereich
    1032           0 :             double nTemp = nComp1; nComp1 = nComp2; nComp2 = nTemp;
    1033             :         }
    1034             : 
    1035             :     //  Alle Grenzfaelle muessen per ::rtl::math::approxEqual getestet werden!
    1036             : 
    1037        2704 :     bool bValid = false;
    1038        2704 :     switch (eOp)
    1039             :     {
    1040             :         case SC_COND_NONE:
    1041           0 :             break;                  // immer sal_False;
    1042             :         case SC_COND_EQUAL:
    1043        1179 :             bValid = ::rtl::math::approxEqual( nArg, nComp1 );
    1044        1179 :             break;
    1045             :         case SC_COND_NOTEQUAL:
    1046           0 :             bValid = !::rtl::math::approxEqual( nArg, nComp1 );
    1047           0 :             break;
    1048             :         case SC_COND_GREATER:
    1049         742 :             bValid = ( nArg > nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
    1050         742 :             break;
    1051             :         case SC_COND_EQGREATER:
    1052           1 :             bValid = ( nArg >= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
    1053           1 :             break;
    1054             :         case SC_COND_LESS:
    1055           4 :             bValid = ( nArg < nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
    1056           4 :             break;
    1057             :         case SC_COND_EQLESS:
    1058           0 :             bValid = ( nArg <= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
    1059           0 :             break;
    1060             :         case SC_COND_BETWEEN:
    1061         101 :             bValid = ( nArg >= nComp1 && nArg <= nComp2 ) ||
    1062         134 :                      ::rtl::math::approxEqual( nArg, nComp1 ) || ::rtl::math::approxEqual( nArg, nComp2 );
    1063         100 :             break;
    1064             :         case SC_COND_NOTBETWEEN:
    1065           3 :             bValid = ( nArg < nComp1 || nArg > nComp2 ) &&
    1066           4 :                      !::rtl::math::approxEqual( nArg, nComp1 ) && !::rtl::math::approxEqual( nArg, nComp2 );
    1067           2 :             break;
    1068             :         case SC_COND_DUPLICATE:
    1069             :         case SC_COND_NOTDUPLICATE:
    1070           0 :             if( pCondFormat )
    1071             :             {
    1072           0 :                 bValid = IsDuplicate( nArg, OUString() );
    1073           0 :                 if( eOp == SC_COND_NOTDUPLICATE )
    1074           0 :                     bValid = !bValid;
    1075             :             }
    1076           0 :             break;
    1077             :         case SC_COND_DIRECT:
    1078           4 :             bValid = !::rtl::math::approxEqual( nComp1, 0.0 );
    1079           4 :             break;
    1080             :         case SC_COND_TOP10:
    1081          84 :             bValid = IsTopNElement( nArg );
    1082          84 :             break;
    1083             :         case SC_COND_BOTTOM10:
    1084          84 :             bValid = IsBottomNElement( nArg );
    1085          84 :             break;
    1086             :         case SC_COND_TOP_PERCENT:
    1087          84 :             bValid = IsTopNPercent( nArg );
    1088          84 :             break;
    1089             :         case SC_COND_BOTTOM_PERCENT:
    1090          84 :             bValid = IsBottomNPercent( nArg );
    1091          84 :             break;
    1092             :         case SC_COND_ABOVE_AVERAGE:
    1093             :         case SC_COND_ABOVE_EQUAL_AVERAGE:
    1094         168 :             bValid = IsAboveAverage( nArg, eOp == SC_COND_ABOVE_EQUAL_AVERAGE );
    1095         168 :             break;
    1096             :         case SC_COND_BELOW_AVERAGE:
    1097             :         case SC_COND_BELOW_EQUAL_AVERAGE:
    1098         168 :             bValid = IsBelowAverage( nArg, eOp == SC_COND_BELOW_EQUAL_AVERAGE );
    1099         168 :             break;
    1100             :         case SC_COND_ERROR:
    1101             :         case SC_COND_NOERROR:
    1102           0 :             bValid = IsError( rPos );
    1103           0 :             if( eOp == SC_COND_NOERROR )
    1104           0 :                 bValid = !bValid;
    1105           0 :             break;
    1106             :         case SC_COND_BEGINS_WITH:
    1107           0 :             if(aStrVal1.isEmpty())
    1108             :             {
    1109           0 :                 OUString aStr = OUString::valueOf(nVal1);
    1110           0 :                 OUString aStr2 = OUString::valueOf(nArg);
    1111           0 :                 bValid = aStr2.indexOf(aStr) == 0;
    1112             :             }
    1113             :             else
    1114             :             {
    1115           0 :                 OUString aStr2 = OUString::valueOf(nArg);
    1116           0 :                 bValid = aStr2.indexOf(aStrVal1) == 0;
    1117             :             }
    1118           0 :             break;
    1119             :         case SC_COND_ENDS_WITH:
    1120           0 :             if(aStrVal1.isEmpty())
    1121             :             {
    1122           0 :                 OUString aStr = OUString::valueOf(nVal1);
    1123           0 :                 OUString aStr2 = OUString::valueOf(nArg);
    1124           0 :                 bValid = aStr2.endsWith(aStr) == 0;
    1125             :             }
    1126             :             else
    1127             :             {
    1128           0 :                 OUString aStr2 = OUString::valueOf(nArg);
    1129           0 :                 bValid = aStr2.endsWith(aStrVal1) == 0;
    1130             :             }
    1131           0 :             break;
    1132             :         case SC_COND_CONTAINS_TEXT:
    1133             :         case SC_COND_NOT_CONTAINS_TEXT:
    1134           0 :             if(aStrVal1.isEmpty())
    1135             :             {
    1136           0 :                 OUString aStr = OUString::valueOf(nVal1);
    1137           0 :                 OUString aStr2 = OUString::valueOf(nArg);
    1138           0 :                 bValid = aStr2.indexOf(aStr) != -1;
    1139             :             }
    1140             :             else
    1141             :             {
    1142           0 :                 OUString aStr2 = OUString::valueOf(nArg);
    1143           0 :                 bValid = aStr2.indexOf(aStrVal1) != -1;
    1144             :             }
    1145             : 
    1146           0 :             if( eOp == SC_COND_NOT_CONTAINS_TEXT )
    1147           0 :                 bValid = !bValid;
    1148           0 :             break;
    1149             :         default:
    1150             :             SAL_WARN("sc", "unknown operation at ScConditionEntry");
    1151           0 :             break;
    1152             :     }
    1153        2704 :     return bValid;
    1154             : }
    1155             : 
    1156           0 : bool ScConditionEntry::IsValidStr( const OUString& rArg, const ScAddress& rPos ) const
    1157             : {
    1158           0 :     bool bValid = false;
    1159             :     //  Interpret muss schon gerufen sein
    1160             : 
    1161           0 :     if ( eOp == SC_COND_DIRECT )                // Formel ist unabhaengig vom Inhalt
    1162           0 :         return !::rtl::math::approxEqual( nVal1, 0.0 );
    1163             : 
    1164           0 :     if ( eOp == SC_COND_DUPLICATE || eOp == SC_COND_NOTDUPLICATE )
    1165             :     {
    1166           0 :         if( pCondFormat && !rArg.isEmpty() )
    1167             :         {
    1168           0 :             bValid = IsDuplicate( 0.0, rArg );
    1169           0 :             if( eOp == SC_COND_NOTDUPLICATE )
    1170           0 :                 bValid = !bValid;
    1171           0 :             return bValid;
    1172             :         }
    1173             :     }
    1174             : 
    1175             :     // If number contains condition, always false, except for "not equal".
    1176             : 
    1177           0 :     if ( !bIsStr1 && (eOp != SC_COND_ERROR && eOp != SC_COND_NOERROR) )
    1178           0 :         return ( eOp == SC_COND_NOTEQUAL );
    1179           0 :     if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
    1180           0 :         if ( !bIsStr2 )
    1181           0 :             return false;
    1182             : 
    1183           0 :     OUString aUpVal1( aStrVal1 );     //! als Member? (dann auch in Interpret setzen)
    1184           0 :     OUString aUpVal2( aStrVal2 );
    1185             : 
    1186           0 :     if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
    1187           0 :         if ( ScGlobal::GetCollator()->compareString( aUpVal1, aUpVal2 )
    1188             :                 == COMPARE_GREATER )
    1189             :         {
    1190             :             //  richtige Reihenfolge fuer Wertebereich
    1191           0 :             OUString aTemp( aUpVal1 ); aUpVal1 = aUpVal2; aUpVal2 = aTemp;
    1192             :         }
    1193             : 
    1194           0 :     switch ( eOp )
    1195             :     {
    1196             :         case SC_COND_EQUAL:
    1197             :             bValid = (ScGlobal::GetCollator()->compareString(
    1198           0 :                 rArg, aUpVal1 ) == COMPARE_EQUAL);
    1199           0 :         break;
    1200             :         case SC_COND_NOTEQUAL:
    1201             :             bValid = (ScGlobal::GetCollator()->compareString(
    1202           0 :                 rArg, aUpVal1 ) != COMPARE_EQUAL);
    1203           0 :         break;
    1204             :         case SC_COND_TOP_PERCENT:
    1205             :         case SC_COND_BOTTOM_PERCENT:
    1206             :         case SC_COND_TOP10:
    1207             :         case SC_COND_BOTTOM10:
    1208             :         case SC_COND_ABOVE_AVERAGE:
    1209             :         case SC_COND_BELOW_AVERAGE:
    1210           0 :             return false;
    1211             :         case SC_COND_ERROR:
    1212             :         case SC_COND_NOERROR:
    1213           0 :             bValid = IsError( rPos );
    1214           0 :             if(eOp == SC_COND_NOERROR)
    1215           0 :                 bValid = !bValid;
    1216           0 :         break;
    1217             :         case SC_COND_BEGINS_WITH:
    1218           0 :             bValid = rArg.indexOf(aUpVal1) == 0;
    1219           0 :         break;
    1220             :         case SC_COND_ENDS_WITH:
    1221           0 :             bValid = rArg.endsWith(aUpVal1);
    1222           0 :         break;
    1223             :         case SC_COND_CONTAINS_TEXT:
    1224             :         case SC_COND_NOT_CONTAINS_TEXT:
    1225           0 :             bValid = rArg.indexOf(aUpVal1) != -1;
    1226           0 :             if(eOp == SC_COND_NOT_CONTAINS_TEXT)
    1227           0 :                 bValid = !bValid;
    1228           0 :         break;
    1229             :         default:
    1230             :         {
    1231             :             sal_Int32 nCompare = ScGlobal::GetCollator()->compareString(
    1232           0 :                 rArg, aUpVal1 );
    1233           0 :             switch ( eOp )
    1234             :             {
    1235             :                 case SC_COND_GREATER:
    1236           0 :                     bValid = ( nCompare == COMPARE_GREATER );
    1237           0 :                     break;
    1238             :                 case SC_COND_EQGREATER:
    1239           0 :                     bValid = ( nCompare == COMPARE_EQUAL || nCompare == COMPARE_GREATER );
    1240           0 :                     break;
    1241             :                 case SC_COND_LESS:
    1242           0 :                     bValid = ( nCompare == COMPARE_LESS );
    1243           0 :                     break;
    1244             :                 case SC_COND_EQLESS:
    1245           0 :                     bValid = ( nCompare == COMPARE_EQUAL || nCompare == COMPARE_LESS );
    1246           0 :                     break;
    1247             :                 case SC_COND_BETWEEN:
    1248             :                 case SC_COND_NOTBETWEEN:
    1249             :                     //  Test auf NOTBETWEEN:
    1250           0 :                     bValid = ( nCompare == COMPARE_LESS ||
    1251             :                         ScGlobal::GetCollator()->compareString( rArg,
    1252           0 :                         aUpVal2 ) == COMPARE_GREATER );
    1253           0 :                     if ( eOp == SC_COND_BETWEEN )
    1254           0 :                         bValid = !bValid;
    1255           0 :                     break;
    1256             :                 //  SC_COND_DIRECT schon oben abgefragt
    1257             :                 default:
    1258             :                     SAL_WARN("sc", "unbekannte Operation bei ScConditionEntry");
    1259           0 :                     bValid = false;
    1260           0 :                     break;
    1261             :             }
    1262             :         }
    1263             :     }
    1264           0 :     return bValid;
    1265             : }
    1266             : 
    1267        2704 : bool ScConditionEntry::IsCellValid( ScRefCellValue& rCell, const ScAddress& rPos ) const
    1268             : {
    1269        2704 :     ((ScConditionEntry*)this)->Interpret(rPos);         // Formeln auswerten
    1270             : 
    1271        2704 :     double nArg = 0.0;
    1272        2704 :     OUString aArgStr;
    1273        2704 :     bool bVal = lcl_GetCellContent( rCell, bIsStr1, nArg, aArgStr );
    1274        2704 :     if (bVal)
    1275        2704 :         return IsValid( nArg, rPos );
    1276             :     else
    1277           0 :         return IsValidStr( aArgStr, rPos );
    1278             : }
    1279             : 
    1280         195 : OUString ScConditionEntry::GetExpression( const ScAddress& rCursor, sal_uInt16 nIndex,
    1281             :                                         sal_uLong nNumFmt,
    1282             :                                         const FormulaGrammar::Grammar eGrammar ) const
    1283             : {
    1284             :     assert( nIndex <= 1);
    1285         195 :     OUString aRet;
    1286             : 
    1287         195 :     if ( FormulaGrammar::isEnglish( eGrammar) && nNumFmt == 0 )
    1288         170 :         nNumFmt = mpDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US );
    1289             : 
    1290         195 :     if ( nIndex==0 )
    1291             :     {
    1292         102 :         if ( pFormula1 )
    1293             :         {
    1294          26 :             ScCompiler aComp(mpDoc, rCursor, *pFormula1);
    1295          26 :             aComp.SetGrammar(eGrammar);
    1296          52 :             OUStringBuffer aBuffer;
    1297          26 :             aComp.CreateStringFromTokenArray( aBuffer );
    1298          52 :             aRet = aBuffer.makeStringAndClear();
    1299             :         }
    1300          76 :         else if (bIsStr1)
    1301             :         {
    1302           0 :             aRet = "\"";
    1303           0 :             aRet += aStrVal1;
    1304           0 :             aRet += "\"";
    1305             :         }
    1306             :         else
    1307          76 :             mpDoc->GetFormatTable()->GetInputLineString(nVal1, nNumFmt, aRet);
    1308             :     }
    1309          93 :     else if ( nIndex==1 )
    1310             :     {
    1311          93 :         if ( pFormula2 )
    1312             :         {
    1313           4 :             ScCompiler aComp(mpDoc, rCursor, *pFormula2);
    1314           4 :             aComp.SetGrammar(eGrammar);
    1315           8 :             OUStringBuffer aBuffer;
    1316           4 :             aComp.CreateStringFromTokenArray( aBuffer );
    1317           8 :             aRet = aBuffer.makeStringAndClear();
    1318             :         }
    1319          89 :         else if (bIsStr2)
    1320             :         {
    1321           0 :             aRet = "\"";
    1322           0 :             aRet += aStrVal2;
    1323           0 :             aRet += "\"";
    1324             :         }
    1325             :         else
    1326          89 :             mpDoc->GetFormatTable()->GetInputLineString(nVal2, nNumFmt, aRet);
    1327             :     }
    1328             : 
    1329         195 :     return aRet;
    1330             : }
    1331             : 
    1332          12 : ScTokenArray* ScConditionEntry::CreateTokenArry( sal_uInt16 nIndex ) const
    1333             : {
    1334             :     assert(nIndex <= 1);
    1335          12 :     ScTokenArray* pRet = NULL;
    1336          12 :     ScAddress aAddr;
    1337             : 
    1338          12 :     if ( nIndex==0 )
    1339             :     {
    1340          12 :         if ( pFormula1 )
    1341           0 :             pRet = new ScTokenArray( *pFormula1 );
    1342             :         else
    1343             :         {
    1344          12 :             pRet = new ScTokenArray();
    1345          12 :             if (bIsStr1)
    1346           0 :                 pRet->AddString( aStrVal1 );
    1347             :             else
    1348          12 :                 pRet->AddDouble( nVal1 );
    1349             :         }
    1350             :     }
    1351           0 :     else if ( nIndex==1 )
    1352             :     {
    1353           0 :         if ( pFormula2 )
    1354           0 :             pRet = new ScTokenArray( *pFormula2 );
    1355             :         else
    1356             :         {
    1357           0 :             pRet = new ScTokenArray();
    1358           0 :             if (bIsStr2)
    1359           0 :                 pRet->AddString( aStrVal2 );
    1360             :             else
    1361           0 :                 pRet->AddDouble( nVal2 );
    1362             :         }
    1363             :     }
    1364             : 
    1365          12 :     return pRet;
    1366             : }
    1367             : 
    1368          98 : void ScConditionEntry::SourceChanged( const ScAddress& rChanged )
    1369             : {
    1370         294 :     for (sal_uInt16 nPass = 0; nPass < 2; nPass++)
    1371             :     {
    1372         196 :         ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
    1373         196 :         if (pFormula)
    1374             :         {
    1375         147 :             pFormula->Reset();
    1376             :             ScToken* t;
    1377         441 :             while ( ( t = static_cast<ScToken*>(pFormula->GetNextReference()) ) != NULL )
    1378             :             {
    1379         147 :                 SingleDoubleRefProvider aProv( *t );
    1380         441 :                 if ( aProv.Ref1.IsColRel() || aProv.Ref1.IsRowRel() || aProv.Ref1.IsTabRel() ||
    1381         147 :                      aProv.Ref2.IsColRel() || aProv.Ref2.IsRowRel() || aProv.Ref2.IsTabRel() )
    1382             :                 {
    1383             :                     //  absolut muss getroffen sein, relativ bestimmt Bereich
    1384             : 
    1385         147 :                     bool bHit = true;
    1386             :                     SCsCOL nCol1;
    1387             :                     SCsROW nRow1;
    1388             :                     SCsTAB nTab1;
    1389             :                     SCsCOL nCol2;
    1390             :                     SCsROW nRow2;
    1391             :                     SCsTAB nTab2;
    1392             : 
    1393         147 :                     if ( aProv.Ref1.IsColRel() )
    1394           0 :                         nCol2 = rChanged.Col() - aProv.Ref1.nRelCol;
    1395             :                     else
    1396             :                     {
    1397         147 :                         bHit &= ( rChanged.Col() >= aProv.Ref1.nCol );
    1398         147 :                         nCol2 = MAXCOL;
    1399             :                     }
    1400         147 :                     if ( aProv.Ref1.IsRowRel() )
    1401           0 :                         nRow2 = rChanged.Row() - aProv.Ref1.nRelRow;
    1402             :                     else
    1403             :                     {
    1404         147 :                         bHit &= ( rChanged.Row() >= aProv.Ref1.nRow );
    1405         147 :                         nRow2 = MAXROW;
    1406             :                     }
    1407         147 :                     if ( aProv.Ref1.IsTabRel() )
    1408         147 :                         nTab2 = rChanged.Tab() - aProv.Ref1.nRelTab;
    1409             :                     else
    1410             :                     {
    1411           0 :                         bHit &= ( rChanged.Tab() >= aProv.Ref1.nTab );
    1412           0 :                         nTab2 = MAXTAB;
    1413             :                     }
    1414             : 
    1415         147 :                     if ( aProv.Ref2.IsColRel() )
    1416           0 :                         nCol1 = rChanged.Col() - aProv.Ref2.nRelCol;
    1417             :                     else
    1418             :                     {
    1419         147 :                         bHit &= ( rChanged.Col() <= aProv.Ref2.nCol );
    1420         147 :                         nCol1 = 0;
    1421             :                     }
    1422         147 :                     if ( aProv.Ref2.IsRowRel() )
    1423           0 :                         nRow1 = rChanged.Row() - aProv.Ref2.nRelRow;
    1424             :                     else
    1425             :                     {
    1426         147 :                         bHit &= ( rChanged.Row() <= aProv.Ref2.nRow );
    1427         147 :                         nRow1 = 0;
    1428             :                     }
    1429         147 :                     if ( aProv.Ref2.IsTabRel() )
    1430         147 :                         nTab1 = rChanged.Tab() - aProv.Ref2.nRelTab;
    1431             :                     else
    1432             :                     {
    1433           0 :                         bHit &= ( rChanged.Tab() <= aProv.Ref2.nTab );
    1434           0 :                         nTab1 = 0;
    1435             :                     }
    1436             : 
    1437         147 :                     if ( bHit )
    1438             :                     {
    1439             :                         //! begrenzen
    1440             : 
    1441          12 :                         ScRange aPaint( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 );
    1442             : 
    1443             :                         //  kein Paint, wenn es nur die Zelle selber ist
    1444          12 :                         if ( aPaint.IsValid() && (aPaint.aStart != rChanged || aPaint.aEnd != rChanged ))
    1445          12 :                             DataChanged( &aPaint );
    1446             :                     }
    1447             :                 }
    1448         147 :             }
    1449             :         }
    1450             :     }
    1451          98 : }
    1452             : 
    1453          60 : ScAddress ScConditionEntry::GetValidSrcPos() const
    1454             : {
    1455             :     // return a position that's adjusted to allow textual representation of expressions if possible
    1456             : 
    1457          60 :     SCTAB nMinTab = aSrcPos.Tab();
    1458          60 :     SCTAB nMaxTab = nMinTab;
    1459             : 
    1460         180 :     for (sal_uInt16 nPass = 0; nPass < 2; nPass++)
    1461             :     {
    1462         120 :         ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
    1463         120 :         if (pFormula)
    1464             :         {
    1465           0 :             pFormula->Reset();
    1466             :             ScToken* t;
    1467           0 :             while ( ( t = static_cast<ScToken*>(pFormula->GetNextReference()) ) != NULL )
    1468             :             {
    1469           0 :                 ScSingleRefData& rRef1 = t->GetSingleRef();
    1470           0 :                 if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
    1471             :                 {
    1472           0 :                     if ( rRef1.nTab < nMinTab )
    1473           0 :                         nMinTab = rRef1.nTab;
    1474           0 :                     if ( rRef1.nTab > nMaxTab )
    1475           0 :                         nMaxTab = rRef1.nTab;
    1476             :                 }
    1477           0 :                 if ( t->GetType() == svDoubleRef )
    1478             :                 {
    1479           0 :                     ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
    1480           0 :                     if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
    1481             :                     {
    1482           0 :                         if ( rRef2.nTab < nMinTab )
    1483           0 :                             nMinTab = rRef2.nTab;
    1484           0 :                         if ( rRef2.nTab > nMaxTab )
    1485           0 :                             nMaxTab = rRef2.nTab;
    1486             :                     }
    1487             :                 }
    1488             :             }
    1489             :         }
    1490             :     }
    1491             : 
    1492          60 :     ScAddress aValidPos = aSrcPos;
    1493          60 :     SCTAB nTabCount = mpDoc->GetTableCount();
    1494          60 :     if ( nMaxTab >= nTabCount && nMinTab > 0 )
    1495           0 :         aValidPos.SetTab( aSrcPos.Tab() - nMinTab );    // so the lowest tab ref will be on 0
    1496             : 
    1497          60 :     if ( aValidPos.Tab() >= nTabCount )
    1498           0 :         aValidPos.SetTab( nTabCount - 1 );  // ensure a valid position even if some references will be invalid
    1499             : 
    1500          60 :     return aValidPos;
    1501             : }
    1502             : 
    1503           0 : void ScConditionEntry::DataChanged( const ScRange* /* pModified */ ) const
    1504             : {
    1505             :     // nix
    1506           0 : }
    1507             : 
    1508           0 : bool ScConditionEntry::MarkUsedExternalReferences() const
    1509             : {
    1510           0 :     bool bAllMarked = false;
    1511           0 :     for (sal_uInt16 nPass = 0; !bAllMarked && nPass < 2; nPass++)
    1512             :     {
    1513           0 :         ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
    1514           0 :         if (pFormula)
    1515           0 :             bAllMarked = mpDoc->MarkUsedExternalReferences( *pFormula);
    1516             :     }
    1517           0 :     return bAllMarked;
    1518             : }
    1519             : 
    1520           0 : ScFormatEntry* ScConditionEntry::Clone(ScDocument* pDoc) const
    1521             : {
    1522           0 :     return new ScConditionEntry(pDoc, *this);
    1523             : }
    1524             : 
    1525          32 : ScConditionMode ScConditionEntry::GetModeFromApi(sal_Int32 nOperation)
    1526             : {
    1527          32 :     ScConditionMode eMode = SC_COND_NONE;
    1528          32 :     switch (nOperation)
    1529             :     {
    1530             :         case com::sun::star::sheet::ConditionOperator2::EQUAL:
    1531           9 :             eMode = SC_COND_EQUAL;
    1532           9 :             break;
    1533             :         case com::sun::star::sheet::ConditionOperator2::LESS:
    1534           1 :             eMode = SC_COND_LESS;
    1535           1 :             break;
    1536             :         case com::sun::star::sheet::ConditionOperator2::GREATER:
    1537           5 :             eMode = SC_COND_GREATER;
    1538           5 :             break;
    1539             :         case com::sun::star::sheet::ConditionOperator2::LESS_EQUAL:
    1540           0 :             eMode = SC_COND_EQLESS;
    1541           0 :             break;
    1542             :         case com::sun::star::sheet::ConditionOperator2::GREATER_EQUAL:
    1543           2 :             eMode = SC_COND_EQGREATER;
    1544           2 :             break;
    1545             :         case com::sun::star::sheet::ConditionOperator2::NOT_EQUAL:
    1546           0 :             eMode = SC_COND_NOTEQUAL;
    1547           0 :             break;
    1548             :         case com::sun::star::sheet::ConditionOperator2::BETWEEN:
    1549          11 :             eMode = SC_COND_BETWEEN;
    1550          11 :             break;
    1551             :         case com::sun::star::sheet::ConditionOperator2::NOT_BETWEEN:
    1552           2 :             eMode = SC_COND_NOTBETWEEN;
    1553           2 :             break;
    1554             :         case com::sun::star::sheet::ConditionOperator2::FORMULA:
    1555           2 :             eMode = SC_COND_DIRECT;
    1556           2 :             break;
    1557             :         case com::sun::star::sheet::ConditionOperator2::DUPLICATE:
    1558           0 :             eMode = SC_COND_DUPLICATE;
    1559           0 :             break;
    1560             :         case com::sun::star::sheet::ConditionOperator2::NOT_DUPLICATE:
    1561           0 :             eMode = SC_COND_NOTDUPLICATE;
    1562           0 :             break;
    1563             :         default:
    1564           0 :             break;
    1565             :     }
    1566          32 :     return eMode;
    1567             : }
    1568             : 
    1569         114 : void ScConditionEntry::startRendering()
    1570             : {
    1571         114 :     mpCache.reset();
    1572         114 : }
    1573             : 
    1574         114 : void ScConditionEntry::endRendering()
    1575             : {
    1576         114 :     mpCache.reset();
    1577         114 : }
    1578             : 
    1579             : //------------------------------------------------------------------------
    1580             : 
    1581          38 : ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
    1582             :                                         const OUString& rExpr1, const OUString& rExpr2,
    1583             :                                         ScDocument* pDocument, const ScAddress& rPos,
    1584             :                                         const OUString& rStyle,
    1585             :                                         const OUString& rExprNmsp1, const OUString& rExprNmsp2,
    1586             :                                         FormulaGrammar::Grammar eGrammar1,
    1587             :                                         FormulaGrammar::Grammar eGrammar2 ) :
    1588             :     ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
    1589          38 :     aStyleName( rStyle )
    1590             : {
    1591          38 : }
    1592             : 
    1593          26 : ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
    1594             :                                         const ScTokenArray* pArr1, const ScTokenArray* pArr2,
    1595             :                                         ScDocument* pDocument, const ScAddress& rPos,
    1596             :                                         const OUString& rStyle ) :
    1597             :     ScConditionEntry( eOper, pArr1, pArr2, pDocument, rPos ),
    1598          26 :     aStyleName( rStyle )
    1599             : {
    1600          26 : }
    1601             : 
    1602           0 : ScCondFormatEntry::ScCondFormatEntry( const ScCondFormatEntry& r ) :
    1603             :     ScConditionEntry( r ),
    1604           0 :     aStyleName( r.aStyleName )
    1605             : {
    1606           0 : }
    1607             : 
    1608          24 : ScCondFormatEntry::ScCondFormatEntry( ScDocument* pDocument, const ScCondFormatEntry& r ) :
    1609             :     ScConditionEntry( pDocument, r ),
    1610          24 :     aStyleName( r.aStyleName )
    1611             : {
    1612          24 : }
    1613             : 
    1614           1 : int ScCondFormatEntry::operator== ( const ScCondFormatEntry& r ) const
    1615             : {
    1616           1 :     return ScConditionEntry::operator==( r ) &&
    1617           1 :             aStyleName == r.aStyleName;
    1618             : }
    1619             : 
    1620         174 : ScCondFormatEntry::~ScCondFormatEntry()
    1621             : {
    1622         174 : }
    1623             : 
    1624          12 : void ScCondFormatEntry::DataChanged( const ScRange* pModified ) const
    1625             : {
    1626          12 :     if ( pCondFormat )
    1627          12 :         pCondFormat->DoRepaint( pModified );
    1628          12 : }
    1629             : 
    1630          24 : ScFormatEntry* ScCondFormatEntry::Clone( ScDocument* pDoc ) const
    1631             : {
    1632          24 :     return new ScCondFormatEntry( pDoc, *this );
    1633             : }
    1634             : 
    1635             : //------------------------------------------------------------------------
    1636             : 
    1637           0 : ScCondDateFormatEntry::ScCondDateFormatEntry( ScDocument* pDoc ):
    1638           0 :     ScFormatEntry( pDoc )
    1639             : {
    1640           0 : }
    1641             : 
    1642           0 : ScCondDateFormatEntry::ScCondDateFormatEntry( ScDocument* pDoc, const ScCondDateFormatEntry& rFormat ):
    1643             :     ScFormatEntry( pDoc ),
    1644             :     meType( rFormat.meType ),
    1645           0 :     maStyleName( rFormat.maStyleName )
    1646             : {
    1647           0 : }
    1648             : 
    1649           0 : bool ScCondDateFormatEntry::IsValid( const ScAddress& rPos ) const
    1650             : {
    1651           0 :     CellType eCellType = mpDoc->GetCellType(rPos);
    1652             : 
    1653           0 :     if (eCellType == CELLTYPE_NONE)
    1654             :         // empty cell.
    1655           0 :         return false;
    1656             : 
    1657           0 :     if (eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
    1658             :         // non-numerical cell.
    1659           0 :         return false;
    1660             : 
    1661           0 :     if( !mpCache )
    1662           0 :         mpCache.reset( new Date( Date::SYSTEM ) );
    1663             : 
    1664           0 :     const Date& rActDate = *mpCache;
    1665           0 :     SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
    1666           0 :     long nCurrentDate = rActDate - *(pFormatter->GetNullDate());
    1667             : 
    1668           0 :     double nVal = mpDoc->GetValue(rPos);
    1669           0 :     long nCellDate = (long) ::rtl::math::approxFloor(nVal);
    1670           0 :     Date aCellDate = *(pFormatter->GetNullDate());
    1671           0 :     aCellDate += (long) ::rtl::math::approxFloor(nVal);
    1672             : 
    1673           0 :     switch(meType)
    1674             :     {
    1675             :         case condformat::TODAY:
    1676           0 :             if( nCurrentDate == nCellDate )
    1677           0 :                 return true;
    1678           0 :             break;
    1679             :         case condformat::TOMORROW:
    1680           0 :             if( nCurrentDate == nCellDate -1 )
    1681           0 :                 return true;
    1682           0 :             break;
    1683             :         case condformat::YESTERDAY:
    1684           0 :             if( nCurrentDate == nCellDate + 1)
    1685           0 :                 return true;
    1686           0 :             break;
    1687             :         case condformat::LAST7DAYS:
    1688           0 :             if( nCurrentDate >= nCellDate && nCurrentDate - 7 < nCellDate )
    1689           0 :                 return true;
    1690           0 :             break;
    1691             :         case condformat::LASTWEEK:
    1692           0 :             if( rActDate.GetDayOfWeek() != SUNDAY )
    1693             :             {
    1694           0 :                 Date aBegin(rActDate - 8 - static_cast<long>(rActDate.GetDayOfWeek()));
    1695           0 :                 Date aEnd(rActDate - 2 -static_cast<long>(rActDate.GetDayOfWeek()));
    1696           0 :                 return aCellDate.IsBetween( aBegin, aEnd );
    1697             :             }
    1698             :             else
    1699             :             {
    1700           0 :                 Date aBegin(rActDate - 8);
    1701           0 :                 Date aEnd(rActDate - 1);
    1702           0 :                 return aCellDate.IsBetween( aBegin, aEnd );
    1703             :             }
    1704             :             break;
    1705             :         case condformat::THISWEEK:
    1706           0 :             if( rActDate.GetDayOfWeek() != SUNDAY )
    1707             :             {
    1708           0 :                 Date aBegin(rActDate - 1 - static_cast<long>(rActDate.GetDayOfWeek()));
    1709           0 :                 Date aEnd(rActDate + 5 - static_cast<long>(rActDate.GetDayOfWeek()));
    1710           0 :                 return aCellDate.IsBetween( aBegin, aEnd );
    1711             :             }
    1712             :             else
    1713             :             {
    1714           0 :                 Date aEnd( rActDate + 6);
    1715           0 :                 return aCellDate.IsBetween( rActDate, aEnd );
    1716             :             }
    1717             :             break;
    1718             :         case condformat::NEXTWEEK:
    1719           0 :             if( rActDate.GetDayOfWeek() != SUNDAY )
    1720             :             {
    1721           0 :                 return aCellDate.IsBetween( rActDate + 6 - static_cast<long>(rActDate.GetDayOfWeek()), rActDate + 12 - static_cast<long>(rActDate.GetDayOfWeek()) );
    1722             :             }
    1723             :             else
    1724             :             {
    1725           0 :                 return aCellDate.IsBetween( rActDate + 7, rActDate + 13 );
    1726             :             }
    1727             :             break;
    1728             :         case condformat::LASTMONTH:
    1729           0 :             if( rActDate.GetMonth() == 1 )
    1730             :             {
    1731           0 :                 if( aCellDate.GetMonth() == 12 && rActDate.GetYear() == aCellDate.GetYear() + 1 )
    1732           0 :                     return true;
    1733             :             }
    1734           0 :             else if( rActDate.GetYear() == aCellDate.GetYear() )
    1735             :             {
    1736           0 :                 if( rActDate.GetMonth() == aCellDate.GetMonth() + 1)
    1737           0 :                     return true;
    1738             :             }
    1739           0 :             break;
    1740             :         case condformat::THISMONTH:
    1741           0 :             if( rActDate.GetYear() == aCellDate.GetYear() )
    1742             :             {
    1743           0 :                 if( rActDate.GetMonth() == aCellDate.GetMonth() )
    1744           0 :                     return true;
    1745             :             }
    1746           0 :             break;
    1747             :         case condformat::NEXTMONTH:
    1748           0 :             if( rActDate.GetMonth() == 12 )
    1749             :             {
    1750           0 :                 if( aCellDate.GetMonth() == 1 && rActDate.GetYear() == aCellDate.GetYear() - 1 )
    1751           0 :                     return true;
    1752             :             }
    1753           0 :             else if( rActDate.GetYear() == aCellDate.GetYear() )
    1754             :             {
    1755           0 :                 if( rActDate.GetMonth() == aCellDate.GetMonth() - 1)
    1756           0 :                     return true;
    1757             :             }
    1758           0 :             break;
    1759             :         case condformat::LASTYEAR:
    1760           0 :             if( rActDate.GetYear() == aCellDate.GetYear() + 1 )
    1761           0 :                 return true;
    1762           0 :             break;
    1763             :         case condformat::THISYEAR:
    1764           0 :             if( rActDate.GetYear() == aCellDate.GetYear() )
    1765           0 :                 return true;
    1766           0 :             break;
    1767             :         case condformat::NEXTYEAR:
    1768           0 :             if( rActDate.GetYear() == aCellDate.GetYear() - 1 )
    1769           0 :                 return true;
    1770           0 :             break;
    1771             :     }
    1772             : 
    1773           0 :     return false;
    1774             : }
    1775             : 
    1776           0 : void ScCondDateFormatEntry::SetDateType( condformat::ScCondFormatDateType eType )
    1777             : {
    1778           0 :     meType = eType;
    1779           0 : }
    1780             : 
    1781           0 : condformat::ScCondFormatDateType ScCondDateFormatEntry::GetDateType() const
    1782             : {
    1783           0 :     return meType;
    1784             : }
    1785             : 
    1786           0 : const OUString& ScCondDateFormatEntry::GetStyleName() const
    1787             : {
    1788           0 :     return maStyleName;
    1789             : }
    1790             : 
    1791           0 : void ScCondDateFormatEntry::SetStyleName( const OUString& rStyleName )
    1792             : {
    1793           0 :     maStyleName = rStyleName;
    1794           0 : }
    1795             : 
    1796           0 : ScFormatEntry* ScCondDateFormatEntry::Clone( ScDocument* pDoc ) const
    1797             : {
    1798           0 :     return new ScCondDateFormatEntry( pDoc, *this );
    1799             : }
    1800             : 
    1801           0 : bool ScCondDateFormatEntry::operator==( const ScFormatEntry& r ) const
    1802             : {
    1803           0 :     if(r.GetType() != condformat::DATE)
    1804           0 :         return false;
    1805             : 
    1806           0 :     const ScCondDateFormatEntry& rEntry = static_cast<const ScCondDateFormatEntry&>(r);
    1807             : 
    1808           0 :     if(rEntry.meType != meType)
    1809           0 :         return false;
    1810             : 
    1811           0 :     return rEntry.maStyleName == maStyleName;
    1812             : }
    1813             : 
    1814           0 : void ScCondDateFormatEntry::startRendering()
    1815             : {
    1816           0 :     mpCache.reset();
    1817           0 : }
    1818             : 
    1819           0 : void ScCondDateFormatEntry::endRendering()
    1820             : {
    1821           0 :     mpCache.reset();
    1822           0 : }
    1823             : 
    1824             : //------------------------------------------------------------------------
    1825             : 
    1826        1248 : ScConditionalFormat::ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument) :
    1827             :     pDoc( pDocument ),
    1828        1248 :     nKey( nNewKey )
    1829             : {
    1830        1248 : }
    1831             : 
    1832        1140 : ScConditionalFormat* ScConditionalFormat::Clone(ScDocument* pNewDoc) const
    1833             : {
    1834             :     // echte Kopie der Formeln (fuer Ref-Undo / zwischen Dokumenten)
    1835             : 
    1836        1140 :     if (!pNewDoc)
    1837           2 :         pNewDoc = pDoc;
    1838             : 
    1839        1140 :     ScConditionalFormat* pNew = new ScConditionalFormat(nKey, pNewDoc);
    1840             : 
    1841        1164 :     for (CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1842             :     {
    1843          24 :         ScFormatEntry* pNewEntry = itr->Clone(pNewDoc);
    1844          24 :         pNew->maEntries.push_back( pNewEntry );
    1845          24 :         pNewEntry->SetParent(pNew);
    1846             :     }
    1847        1140 :     pNew->AddRange( maRanges );
    1848             : 
    1849        1140 :     return pNew;
    1850             : }
    1851             : 
    1852           3 : bool ScConditionalFormat::EqualEntries( const ScConditionalFormat& r ) const
    1853             : {
    1854           3 :     if( size() != r.size())
    1855           2 :         return false;
    1856             : 
    1857             :     //! auf gleiche Eintraege in anderer Reihenfolge testen ???
    1858             : 
    1859           1 :     for (sal_uInt16 i=0; i<size(); i++)
    1860           1 :         if ( ! (maEntries == r.maEntries ) )
    1861           1 :             return false;
    1862             : 
    1863             :     // right now don't check for same range
    1864             :     // we only use this method to merge same conditional formats from
    1865             :     // old ODF data structure
    1866           0 :     return true;
    1867             : }
    1868             : 
    1869        1806 : void ScConditionalFormat::AddRange( const ScRangeList& rRanges )
    1870             : {
    1871        1806 :     maRanges = rRanges;
    1872        1806 : }
    1873             : 
    1874         110 : void ScConditionalFormat::AddEntry( ScFormatEntry* pNew )
    1875             : {
    1876         110 :     maEntries.push_back(pNew);
    1877         110 :     pNew->SetParent(this);
    1878         110 : }
    1879             : 
    1880           0 : bool ScConditionalFormat::IsEmpty() const
    1881             : {
    1882           0 :     return maEntries.empty();
    1883             : }
    1884             : 
    1885       12782 : size_t ScConditionalFormat::size() const
    1886             : {
    1887       12782 :     return maEntries.size();
    1888             : }
    1889             : 
    1890        1247 : ScConditionalFormat::~ScConditionalFormat()
    1891             : {
    1892        1247 : }
    1893             : 
    1894        4439 : const ScFormatEntry* ScConditionalFormat::GetEntry( sal_uInt16 nPos ) const
    1895             : {
    1896        4439 :     if ( nPos < size() )
    1897        4439 :         return &maEntries[nPos];
    1898             :     else
    1899           0 :         return NULL;
    1900             : }
    1901             : 
    1902        3971 : const OUString& ScConditionalFormat::GetCellStyle( ScRefCellValue& rCell, const ScAddress& rPos ) const
    1903             : {
    1904        4412 :     for (CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1905             :     {
    1906         689 :         if(itr->GetType() == condformat::CONDITION)
    1907             :         {
    1908         689 :             const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(*itr);
    1909         689 :             if (rEntry.IsCellValid(rCell, rPos))
    1910         496 :                 return rEntry.GetStyle();
    1911             :         }
    1912           0 :         else if(itr->GetType() == condformat::DATE)
    1913             :         {
    1914           0 :             const ScCondDateFormatEntry& rEntry = static_cast<const ScCondDateFormatEntry&>(*itr);
    1915           0 :             if (rEntry.IsValid( rPos ))
    1916           0 :                 return rEntry.GetStyleName();
    1917             :         }
    1918             :     }
    1919             : 
    1920        3723 :     return EMPTY_OUSTRING;
    1921             : }
    1922             : 
    1923       17420 : ScCondFormatData ScConditionalFormat::GetData( ScRefCellValue& rCell, const ScAddress& rPos ) const
    1924             : {
    1925       17420 :     ScCondFormatData aData;
    1926       19435 :     for(CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1927             :     {
    1928        2015 :         if(itr->GetType() == condformat::CONDITION && aData.aStyleName.isEmpty())
    1929             :         {
    1930        2015 :             const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(*itr);
    1931        2015 :             if (rEntry.IsCellValid(rCell, rPos))
    1932          86 :                 aData.aStyleName = rEntry.GetStyle();
    1933             :         }
    1934           0 :         else if(itr->GetType() == condformat::COLORSCALE && !aData.pColorScale)
    1935             :         {
    1936           0 :             const ScColorScaleFormat& rEntry = static_cast<const ScColorScaleFormat&>(*itr);
    1937           0 :             aData.pColorScale = rEntry.GetColor(rPos);
    1938             :         }
    1939           0 :         else if(itr->GetType() == condformat::DATABAR && !aData.pDataBar)
    1940             :         {
    1941           0 :             const ScDataBarFormat& rEntry = static_cast<const ScDataBarFormat&>(*itr);
    1942           0 :             aData.pDataBar = rEntry.GetDataBarInfo(rPos);
    1943             :         }
    1944           0 :         else if(itr->GetType() == condformat::ICONSET && !aData.pIconSet)
    1945             :         {
    1946           0 :             const ScIconSetFormat& rEntry = static_cast<const ScIconSetFormat&>(*itr);
    1947           0 :             aData.pIconSet = rEntry.GetIconSetInfo(rPos);
    1948             :         }
    1949           0 :         else if(itr->GetType() == condformat::DATE && aData.aStyleName.isEmpty())
    1950             :         {
    1951           0 :             const ScCondDateFormatEntry& rEntry = static_cast<const ScCondDateFormatEntry&>(*itr);
    1952           0 :             if ( rEntry.IsValid( rPos ) )
    1953           0 :                 aData.aStyleName = rEntry.GetStyleName();
    1954             :         }
    1955             :     }
    1956       17420 :     return aData;
    1957             : }
    1958             : 
    1959          12 : void ScConditionalFormat::DoRepaint( const ScRange* pModified )
    1960             : {
    1961          12 :     if(pModified)
    1962             :     {
    1963          12 :         if(maRanges.Intersects(*pModified))
    1964          12 :             pDoc->RepaintRange(*pModified);
    1965             :     }
    1966             :     else
    1967             :     {
    1968             :         // all conditional format cells
    1969           0 :         pDoc->RepaintRange( maRanges );
    1970             :     }
    1971          12 : }
    1972             : 
    1973           0 : void ScConditionalFormat::CompileAll()
    1974             : {
    1975           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1976           0 :         if(itr->GetType() == condformat::CONDITION)
    1977           0 :             static_cast<ScCondFormatEntry&>(*itr).CompileAll();
    1978           0 : }
    1979             : 
    1980          50 : void ScConditionalFormat::CompileXML()
    1981             : {
    1982         108 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1983          58 :         if(itr->GetType() == condformat::CONDITION)
    1984          35 :             static_cast<ScCondFormatEntry&>(*itr).CompileXML();
    1985          50 : }
    1986             : 
    1987         559 : void ScConditionalFormat::UpdateReference( UpdateRefMode eUpdateRefMode,
    1988             :                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bCopyAsMove )
    1989             : {
    1990         560 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1991           1 :         itr->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz);
    1992             : 
    1993         559 :     if( eUpdateRefMode == URM_COPY && bCopyAsMove )
    1994         558 :         maRanges.UpdateReference( URM_MOVE, pDoc, rRange, nDx, nDy, nDz );
    1995             :     else
    1996           1 :         maRanges.UpdateReference( eUpdateRefMode, pDoc, rRange, nDx, nDy, nDz );
    1997         559 : }
    1998             : 
    1999         596 : void ScConditionalFormat::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    2000             : {
    2001         596 :     SCTAB nTab = maRanges[0]->aStart.Tab();
    2002         596 :     maRanges.DeleteArea( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
    2003         596 : }
    2004             : 
    2005           0 : void ScConditionalFormat::RenameCellStyle(const OUString& rOld, const OUString& rNew)
    2006             : {
    2007           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2008           0 :         if(itr->GetType() == condformat::CONDITION)
    2009             :         {
    2010           0 :             ScCondFormatEntry& rFormat = static_cast<ScCondFormatEntry&>(*itr);
    2011           0 :             if(rFormat.GetStyle() == rOld)
    2012           0 :                 rFormat.UpdateStyleName( rNew );
    2013             :         }
    2014           0 : }
    2015             : 
    2016           0 : void ScConditionalFormat::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
    2017             : {
    2018           0 :     size_t n = maRanges.size();
    2019           0 :     SCTAB nMinTab = std::min<SCTAB>(nOldPos, nNewPos);
    2020           0 :     SCTAB nMaxTab = std::max<SCTAB>(nOldPos, nNewPos);
    2021           0 :     for(size_t i = 0; i < n; ++i)
    2022             :     {
    2023           0 :         ScRange* pRange = maRanges[i];
    2024           0 :         SCTAB nTab = pRange->aStart.Tab();
    2025           0 :         if(nTab < nMinTab || nTab > nMaxTab)
    2026             :         {
    2027           0 :             continue;
    2028             :         }
    2029             : 
    2030           0 :         if(nTab == nOldPos)
    2031             :         {
    2032           0 :             pRange->aStart.SetTab(nNewPos);
    2033           0 :             pRange->aEnd.SetTab(nNewPos);
    2034           0 :             continue;
    2035             :         }
    2036             : 
    2037           0 :         if(nNewPos < nOldPos)
    2038             :         {
    2039           0 :             pRange->aStart.IncTab();
    2040           0 :             pRange->aEnd.IncTab();
    2041             :         }
    2042             :         else
    2043             :         {
    2044           0 :             pRange->aStart.IncTab(-1);
    2045           0 :             pRange->aEnd.IncTab(-1);
    2046             :         }
    2047             :     }
    2048             : 
    2049           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2050           0 :         itr->UpdateMoveTab( nOldPos, nNewPos );
    2051           0 : }
    2052             : 
    2053         104 : void ScConditionalFormat::SourceChanged( const ScAddress& rAddr )
    2054             : {
    2055         202 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2056             :     {
    2057          98 :         condformat::ScFormatEntryType eEntryType = itr->GetType();
    2058          98 :         if( eEntryType == condformat::CONDITION)
    2059             :         {
    2060          98 :             ScCondFormatEntry& rFormat = static_cast<ScCondFormatEntry&>(*itr);
    2061          98 :             rFormat.SourceChanged( rAddr );
    2062             :         }
    2063           0 :         else if( eEntryType == condformat::COLORSCALE ||
    2064           0 :                 eEntryType == condformat::DATABAR ||
    2065             :                 eEntryType == condformat::ICONSET )
    2066             :         {
    2067           0 :             ScColorFormat& rFormat = static_cast<ScColorFormat&>(*itr);
    2068           0 :             if(rFormat.NeedsRepaint())
    2069             :             {
    2070             :                 // we need to repaint the whole range anyway
    2071           0 :                 DoRepaint(NULL);
    2072           0 :                 return;
    2073             :             }
    2074             :         }
    2075             :     }
    2076             : }
    2077             : 
    2078           0 : bool ScConditionalFormat::MarkUsedExternalReferences() const
    2079             : {
    2080           0 :     bool bAllMarked = false;
    2081           0 :     for(CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end() && !bAllMarked; ++itr)
    2082           0 :         if(itr->GetType() == condformat::CONDITION)
    2083             :         {
    2084           0 :             const ScCondFormatEntry& rFormat = static_cast<const ScCondFormatEntry&>(*itr);
    2085           0 :             bAllMarked = rFormat.MarkUsedExternalReferences();
    2086             :         }
    2087             : 
    2088           0 :     return bAllMarked;
    2089             : }
    2090             : 
    2091         966 : void ScConditionalFormat::startRendering()
    2092             : {
    2093        1080 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2094             :     {
    2095         114 :         itr->startRendering();
    2096             :     }
    2097         966 : }
    2098             : 
    2099         966 : void ScConditionalFormat::endRendering()
    2100             : {
    2101        1080 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2102             :     {
    2103         114 :         itr->endRendering();
    2104             :     }
    2105         966 : }
    2106             : 
    2107             : //------------------------------------------------------------------------
    2108             : 
    2109           4 : ScConditionalFormatList::ScConditionalFormatList(const ScConditionalFormatList& rList)
    2110             : {
    2111           4 :     for(const_iterator itr = rList.begin(); itr != rList.end(); ++itr)
    2112           0 :         InsertNew( itr->Clone() );
    2113           4 : }
    2114             : 
    2115         725 : ScConditionalFormatList::ScConditionalFormatList(ScDocument* pDoc, const ScConditionalFormatList& rList)
    2116             : {
    2117        1305 :     for(const_iterator itr = rList.begin(); itr != rList.end(); ++itr)
    2118         580 :         InsertNew( itr->Clone(pDoc) );
    2119         725 : }
    2120             : 
    2121        1246 : void ScConditionalFormatList::InsertNew( ScConditionalFormat* pNew )
    2122             : {
    2123        1246 :     maConditionalFormats.insert(pNew);
    2124        1246 : }
    2125             : 
    2126           0 : bool ScConditionalFormatList::operator==( const ScConditionalFormatList& r ) const
    2127             : {
    2128             :     // fuer Ref-Undo - interne Variablen werden nicht verglichen
    2129             : 
    2130           0 :     sal_uInt16 nCount = size();
    2131           0 :     bool bEqual = ( nCount == r.size() );
    2132           0 :     const_iterator locIterator = begin();
    2133           0 :     for(const_iterator itr = r.begin(); itr != r.end() && bEqual; ++itr, ++locIterator)
    2134           0 :         if ( !locIterator->EqualEntries(*itr) )         // Eintraege unterschiedlich ?
    2135           0 :             bEqual = false;
    2136             : 
    2137           0 :     return bEqual;
    2138             : }
    2139             : 
    2140       25125 : ScConditionalFormat* ScConditionalFormatList::GetFormat( sal_uInt32 nKey )
    2141             : {
    2142             :     //! binaer suchen
    2143             : 
    2144       44720 :     for( iterator itr = begin(); itr != end(); ++itr)
    2145       44720 :         if (itr->GetKey() == nKey)
    2146       25125 :             return &(*itr);
    2147             : 
    2148             :     SAL_WARN("sc", "ScConditionalFormatList: Entry not found");
    2149           0 :     return NULL;
    2150             : }
    2151             : 
    2152        3971 : const ScConditionalFormat* ScConditionalFormatList::GetFormat( sal_uInt32 nKey ) const
    2153             : {
    2154             :     //! binaer suchen
    2155             : 
    2156        9621 :     for ( const_iterator itr = begin(); itr != end(); ++itr)
    2157        9621 :         if (itr->GetKey() == nKey)
    2158        3971 :             return &(*itr);
    2159             : 
    2160             :     SAL_WARN("sc", "ScConditionalFormatList: Entry not found");
    2161           0 :     return NULL;
    2162             : }
    2163             : 
    2164           3 : void ScConditionalFormatList::CompileAll()
    2165             : {
    2166           3 :     for( iterator itr = begin(); itr != end(); ++itr)
    2167           0 :         itr->CompileAll();
    2168           3 : }
    2169             : 
    2170         168 : void ScConditionalFormatList::CompileXML()
    2171             : {
    2172         218 :     for( iterator itr = begin(); itr != end(); ++itr)
    2173          50 :         itr->CompileXML();
    2174         168 : }
    2175             : 
    2176         271 : void ScConditionalFormatList::UpdateReference( UpdateRefMode eUpdateRefMode,
    2177             :                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    2178             : {
    2179         272 :     for( iterator itr = begin(); itr != end(); ++itr)
    2180           1 :         itr->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz );
    2181             : 
    2182         271 :     if( eUpdateRefMode == URM_INSDEL )
    2183             :     {
    2184             :         // need to check which must be deleted
    2185         238 :         iterator itr = begin();
    2186         477 :         while(itr != end())
    2187             :         {
    2188           1 :             if(itr->GetRange().empty())
    2189           0 :                 maConditionalFormats.erase(itr++);
    2190             :             else
    2191           1 :                 ++itr;
    2192             :         }
    2193             :     }
    2194         271 : }
    2195             : 
    2196           0 : void ScConditionalFormatList::RenameCellStyle( const OUString& rOld, const OUString& rNew )
    2197             : {
    2198           0 :     for( iterator itr = begin(); itr != end(); ++itr)
    2199           0 :         itr->RenameCellStyle(rOld,rNew);
    2200           0 : }
    2201             : 
    2202          10 : void ScConditionalFormatList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
    2203             : {
    2204          10 :     for( iterator itr = begin(); itr != end(); ++itr)
    2205           0 :         itr->UpdateMoveTab( nOldPos, nNewPos );
    2206          10 : }
    2207             : 
    2208        1026 : bool ScConditionalFormatList::CheckAllEntries()
    2209             : {
    2210        1026 :     bool bValid = true;
    2211             :     //
    2212             :     // need to check which must be deleted
    2213        1026 :     iterator itr = begin();
    2214        2695 :     while(itr != end())
    2215             :     {
    2216         643 :         if(itr->GetRange().empty())
    2217             :         {
    2218         558 :             bValid = false;
    2219         558 :             maConditionalFormats.erase(itr++);
    2220             :         }
    2221             :         else
    2222          85 :             ++itr;
    2223             :     }
    2224             : 
    2225        1026 :     return bValid;
    2226             : }
    2227             : 
    2228        1016 : void ScConditionalFormatList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    2229             : {
    2230        1612 :     for( iterator itr = begin(); itr != end(); ++itr)
    2231         596 :         itr->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
    2232             : 
    2233        1016 :     CheckAllEntries();
    2234        1016 : }
    2235             : 
    2236       50475 : void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
    2237             : {
    2238       50579 :     for( iterator itr = begin(); itr != end(); ++itr)
    2239         104 :         itr->SourceChanged( rAddr );
    2240       50475 : }
    2241             : 
    2242       98696 : ScConditionalFormatList::iterator ScConditionalFormatList::begin()
    2243             : {
    2244       98696 :     return maConditionalFormats.begin();
    2245             : }
    2246             : 
    2247        4726 : ScConditionalFormatList::const_iterator ScConditionalFormatList::begin() const
    2248             : {
    2249        4726 :     return maConditionalFormats.begin();
    2250             : }
    2251             : 
    2252      122460 : ScConditionalFormatList::iterator ScConditionalFormatList::end()
    2253             : {
    2254      122460 :     return maConditionalFormats.end();
    2255             : }
    2256             : 
    2257       10982 : ScConditionalFormatList::const_iterator ScConditionalFormatList::end() const
    2258             : {
    2259       10982 :     return maConditionalFormats.end();
    2260             : }
    2261             : 
    2262           9 : size_t ScConditionalFormatList::size() const
    2263             : {
    2264           9 :     return maConditionalFormats.size();
    2265             : }
    2266             : 
    2267           0 : void ScConditionalFormatList::erase( sal_uLong nIndex )
    2268             : {
    2269           0 :     for( iterator itr = begin(); itr != end(); ++itr )
    2270             :     {
    2271           0 :         if( itr->GetKey() == nIndex )
    2272             :         {
    2273           0 :             maConditionalFormats.erase(itr);
    2274           0 :             break;
    2275             :         }
    2276             :     }
    2277           0 : }
    2278             : 
    2279        9444 : void ScConditionalFormatList::startRendering()
    2280             : {
    2281       10410 :     for(iterator itr = begin(); itr != end(); ++itr)
    2282             :     {
    2283         966 :         itr->startRendering();
    2284             :     }
    2285        9444 : }
    2286             : 
    2287        9444 : void ScConditionalFormatList::endRendering()
    2288             : {
    2289       10410 :     for(iterator itr = begin(); itr != end(); ++itr)
    2290             :     {
    2291         966 :         itr->endRendering();
    2292             :     }
    2293        9537 : }
    2294             : 
    2295             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10