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

Generated by: LCOV version 1.10