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 1102 43.9 %
Date: 2012-12-17 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         210 : ScFormatEntry::ScFormatEntry(ScDocument* pDoc):
      44         210 :     mpDoc(pDoc)
      45             : {
      46         210 : }
      47             : 
      48           2 : bool ScFormatEntry::operator==( const ScFormatEntry& r ) const
      49             : {
      50           2 :     if(GetType() != r.GetType())
      51           0 :         return false;
      52             : 
      53           2 :     switch(GetType())
      54             :     {
      55             :         case condformat::CONDITION:
      56           2 :             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         184 : static bool lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, sal_uInt16 nRecursion = 0 )
      75             : {
      76         184 :     if (pFormula)
      77             :     {
      78          28 :         pFormula->Reset();
      79             :         FormulaToken* t;
      80          80 :         for( t = pFormula->Next(); t; t = pFormula->Next() )
      81             :         {
      82          64 :             switch( t->GetType() )
      83             :             {
      84             :                 case svDoubleRef:
      85             :                 {
      86          14 :                     ScSingleRefData& rRef2 = static_cast<ScToken*>(t)->GetDoubleRef().Ref2;
      87          14 :                     if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() )
      88          12 :                         return true;
      89             :                 }
      90             :                 // fall through
      91             : 
      92             :                 case svSingleRef:
      93             :                 {
      94           2 :                     ScSingleRefData& rRef1 = static_cast<ScToken*>(t)->GetSingleRef();
      95           2 :                     if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() )
      96           0 :                         return true;
      97             :                 }
      98           2 :                 break;
      99             : 
     100             :                 case svIndex:
     101             :                 {
     102           2 :                     if( t->GetOpCode() == ocName )      // DB areas always absolute
     103           2 :                         if( ScRangeData* pRangeData = pDoc->GetRangeName()->findByIndex( t->GetIndex() ) )
     104           2 :                             if( (nRecursion < 42) && lcl_HasRelRef( pDoc, pRangeData->GetCode(), nRecursion + 1 ) )
     105           0 :                                 return true;
     106             :                 }
     107           2 :                 break;
     108             : 
     109             :                 // #i34474# function result dependent on cell position
     110             :                 case svByte:
     111             :                 {
     112          24 :                     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          24 :                 break;
     127             : 
     128             :                 default:
     129             :                 {
     130             :                     // added to avoid warnings
     131             :                 }
     132             :             }
     133             :         }
     134             :     }
     135         172 :     return false;
     136             : }
     137             : 
     138           2 : 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           2 :     pCondFormat(r.pCondFormat)
     162             : {
     163             :     //  ScTokenArray copy ctor erzeugt flache Kopie
     164             : 
     165           2 :     if (r.pFormula1)
     166           2 :         pFormula1 = new ScTokenArray( *r.pFormula1 );
     167           2 :     if (r.pFormula2)
     168           0 :         pFormula2 = new ScTokenArray( *r.pFormula2 );
     169             : 
     170             :     //  Formelzellen werden erst bei IsValid angelegt
     171           2 : }
     172             : 
     173          28 : 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          28 :     pCondFormat(r.pCondFormat)
     197             : {
     198             :     // echte Kopie der Formeln (fuer Ref-Undo)
     199             : 
     200          28 :     if (r.pFormula1)
     201          14 :         pFormula1 = r.pFormula1->Clone();
     202          28 :     if (r.pFormula2)
     203           2 :         pFormula2 = r.pFormula2->Clone();
     204             : 
     205             :     //  Formelzellen werden erst bei IsValid angelegt
     206             :     //! im Clipboard nicht - dann vorher interpretieren !!!
     207          28 : }
     208             : 
     209          84 : 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          84 :     pCondFormat(NULL)
     233             : {
     234          84 :     Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, false );
     235             : 
     236             :     //  Formelzellen werden erst bei IsValid angelegt
     237          84 : }
     238             : 
     239          96 : 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          96 :     pCondFormat(NULL)
     260             : {
     261          96 :     if ( pArr1 )
     262             :     {
     263          96 :         pFormula1 = new ScTokenArray( *pArr1 );
     264          96 :         if ( pFormula1->GetLen() == 1 )
     265             :         {
     266             :             // einzelne (konstante Zahl) ?
     267          80 :             FormulaToken* pToken = pFormula1->First();
     268          80 :             if ( pToken->GetOpCode() == ocPush )
     269             :             {
     270          78 :                 if ( pToken->GetType() == svDouble )
     271             :                 {
     272          78 :                     nVal1 = pToken->GetDouble();
     273          78 :                     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          96 :         bRelRef1 = lcl_HasRelRef( mpDoc, pFormula1 );
     284             :     }
     285          96 :     if ( pArr2 )
     286             :     {
     287          28 :         pFormula2 = new ScTokenArray( *pArr2 );
     288          28 :         if ( pFormula2->GetLen() == 1 )
     289             :         {
     290             :             // einzelne (konstante Zahl) ?
     291          28 :             FormulaToken* pToken = pFormula2->First();
     292          28 :             if ( pToken->GetOpCode() == ocPush )
     293             :             {
     294          28 :                 if ( pToken->GetType() == svDouble )
     295             :                 {
     296          28 :                     nVal2 = pToken->GetDouble();
     297          28 :                     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          28 :         bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     308             :     }
     309             : 
     310             :     //  formula cells are created at IsValid
     311          96 : }
     312             : 
     313         356 : ScConditionEntry::~ScConditionEntry()
     314             : {
     315         178 :     delete pFCell1;
     316         178 :     delete pFCell2;
     317             : 
     318         178 :     delete pFormula1;
     319         178 :     delete pFormula2;
     320         178 : }
     321             : 
     322         110 : 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         110 :     if ( !rExpr1.isEmpty() || !rExpr2.isEmpty() )
     327             :     {
     328          80 :         ScCompiler aComp( mpDoc, aSrcPos );
     329             : 
     330          80 :         if ( !rExpr1.isEmpty() )
     331             :         {
     332          80 :             aComp.SetGrammar( eGrammar1 );
     333          80 :             if ( mpDoc->IsImportingXML() && !bTextToReal )
     334             :             {
     335             :                 //  temporary formula string as string tokens
     336             :                 //! merge with lcl_ScDocFunc_CreateTokenArrayXML
     337          50 :                 pFormula1 = new ScTokenArray;
     338          50 :                 pFormula1->AddStringXML( rExpr1 );
     339             :                 // bRelRef1 is set when the formula is compiled again (CompileXML)
     340             :             }
     341             :             else
     342             :             {
     343          30 :                 pFormula1 = aComp.CompileString( rExpr1, rExprNmsp1 );
     344          30 :                 if ( pFormula1->GetLen() == 1 )
     345             :                 {
     346             :                     // einzelne (konstante Zahl) ?
     347          22 :                     FormulaToken* pToken = pFormula1->First();
     348          22 :                     if ( pToken->GetOpCode() == ocPush )
     349             :                     {
     350          22 :                         if ( pToken->GetType() == svDouble )
     351             :                         {
     352          22 :                             nVal1 = pToken->GetDouble();
     353          22 :                             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          30 :                 bRelRef1 = lcl_HasRelRef( mpDoc, pFormula1 );
     364             :             }
     365             :         }
     366             : 
     367          80 :         if ( !rExpr2.isEmpty() )
     368             :         {
     369          54 :             aComp.SetGrammar( eGrammar2 );
     370          54 :             if ( mpDoc->IsImportingXML() && !bTextToReal )
     371             :             {
     372             :                 //  temporary formula string as string tokens
     373             :                 //! merge with lcl_ScDocFunc_CreateTokenArrayXML
     374          26 :                 pFormula2 = new ScTokenArray;
     375          26 :                 pFormula2->AddStringXML( rExpr2 );
     376             :                 // bRelRef2 is set when the formula is compiled again (CompileXML)
     377             :             }
     378             :             else
     379             :             {
     380          28 :                 pFormula2 = aComp.CompileString( rExpr2, rExprNmsp2 );
     381          28 :                 if ( pFormula2->GetLen() == 1 )
     382             :                 {
     383             :                     // einzelne (konstante Zahl) ?
     384          28 :                     FormulaToken* pToken = pFormula2->First();
     385          28 :                     if ( pToken->GetOpCode() == ocPush )
     386             :                     {
     387          28 :                         if ( pToken->GetType() == svDouble )
     388             :                         {
     389          28 :                             nVal2 = pToken->GetDouble();
     390          28 :                             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          28 :                 bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     401             :             }
     402          80 :         }
     403             :     }
     404         110 : }
     405             : 
     406          22 : void ScConditionEntry::MakeCells( const ScAddress& rPos )           // Formelzellen anlegen
     407             : {
     408          22 :     if ( !mpDoc->IsClipOrUndo() )            // nie im Clipboard rechnen!
     409             :     {
     410          22 :         if ( pFormula1 && !pFCell1 && !bRelRef1 )
     411             :         {
     412           6 :             pFCell1 = new ScFormulaCell( mpDoc, rPos, pFormula1 );
     413           6 :             pFCell1->StartListeningTo( mpDoc );
     414             :         }
     415             : 
     416          22 :         if ( pFormula2 && !pFCell2 && !bRelRef2 )
     417             :         {
     418           0 :             pFCell2 = new ScFormulaCell( mpDoc, rPos, pFormula2 );
     419           0 :             pFCell2->StartListeningTo( mpDoc );
     420             :         }
     421             :     }
     422          22 : }
     423             : 
     424          34 : 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          34 :     if (bSet)
     430          34 :         nOptions &= ~SC_COND_NOBLANKS;
     431             :     else
     432           0 :         nOptions |= SC_COND_NOBLANKS;
     433          34 : }
     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          26 : void ScConditionEntry::CompileXML()
     444             : {
     445             :     //  First parse the formula source position if it was stored as text
     446             : 
     447          26 :     if ( !aSrcString.isEmpty() )
     448             :     {
     449          26 :         ScAddress aNew;
     450             :         /* XML is always in OOo:A1 format, although R1C1 would be more amenable
     451             :          * to compression */
     452          26 :         if ( aNew.Parse( aSrcString, mpDoc ) & SCA_VALID )
     453          26 :             aSrcPos = aNew;
     454             :         // if the position is invalid, there isn't much we can do at this time
     455          26 :         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          26 :              aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true );
     463          26 : }
     464             : 
     465          54 : 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          54 :     aSrcString = rNew;
     471          54 : }
     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          58 : static bool lcl_IsEqual( const ScTokenArray* pArr1, const ScTokenArray* pArr2 )
     598             : {
     599             :     //  verglichen wird nur das nicht-UPN Array
     600             : 
     601          58 :     if ( pArr1 && pArr2 )
     602             :     {
     603          44 :         sal_uInt16 nLen = pArr1->GetLen();
     604          44 :         if ( pArr2->GetLen() != nLen )
     605           0 :             return false;
     606             : 
     607          44 :         FormulaToken** ppToken1 = pArr1->GetArray();
     608          44 :         FormulaToken** ppToken2 = pArr2->GetArray();
     609          86 :         for (sal_uInt16 i=0; i<nLen; i++)
     610             :         {
     611          88 :             if ( ppToken1[i] != ppToken2[i] &&
     612          44 :                  !(*ppToken1[i] == *ppToken2[i]) )
     613           2 :                 return false;                       // Unterschied
     614             :         }
     615          42 :         return true;                    // alle Eintraege gleich
     616             :     }
     617             :     else
     618          14 :         return !pArr1 && !pArr2;        // beide 0 -> gleich
     619             : }
     620             : 
     621          80 : int ScConditionEntry::operator== ( const ScConditionEntry& r ) const
     622             : {
     623             :     bool bEq = (eOp == r.eOp && nOptions == r.nOptions &&
     624          30 :                 lcl_IsEqual( pFormula1, r.pFormula1 ) &&
     625         110 :                 lcl_IsEqual( pFormula2, r.pFormula2 ));
     626          80 :     if (bEq)
     627             :     {
     628             :         // for formulas, the reference positions must be compared, too
     629             :         // (including aSrcString, for inserting the entries during XML import)
     630          28 :         if ( ( pFormula1 || pFormula2 ) && ( aSrcPos != r.aSrcPos || aSrcString != r.aSrcString ) )
     631           0 :             bEq = false;
     632             : 
     633             :         //  wenn keine Formeln, Werte vergleichen
     634          28 :         if ( !pFormula1 && ( nVal1 != r.nVal1 || aStrVal1 != r.aStrVal1 || bIsStr1 != r.bIsStr1 ) )
     635           0 :             bEq = false;
     636          28 :         if ( !pFormula2 && ( nVal2 != r.nVal2 || aStrVal2 != r.aStrVal2 || bIsStr2 != r.bIsStr2 ) )
     637           0 :             bEq = false;
     638             :     }
     639             : 
     640          80 :     return bEq;
     641             : }
     642             : 
     643         758 : void ScConditionEntry::Interpret( const ScAddress& rPos )
     644             : {
     645             :     //  Formelzellen anlegen
     646             :     //  dabei koennen neue Broadcaster (Note-Zellen) ins Dokument eingefuegt werden !!!!
     647             : 
     648         758 :     if ( ( pFormula1 && !pFCell1 ) || ( pFormula2 && !pFCell2 ) )
     649          22 :         MakeCells( rPos );
     650             : 
     651             :     //  Formeln auswerten
     652             : 
     653         758 :     bool bDirty = false;        //! 1 und 2 getrennt ???
     654             : 
     655         758 :     ScFormulaCell* pTemp1 = NULL;
     656         758 :     ScFormulaCell* pEff1 = pFCell1;
     657         758 :     if ( bRelRef1 )
     658             :     {
     659          16 :         pTemp1 = new ScFormulaCell( mpDoc, rPos, pFormula1 );    // ohne Listening
     660          16 :         pEff1 = pTemp1;
     661             :     }
     662         758 :     if ( pEff1 )
     663             :     {
     664          26 :         if (!pEff1->IsRunning())        // keine 522 erzeugen
     665             :         {
     666             :             //! Changed statt Dirty abfragen !!!
     667          26 :             if (pEff1->GetDirty() && !bRelRef1 && mpDoc->GetAutoCalc())
     668           6 :                 bDirty = true;
     669          26 :             if (pEff1->IsValue())
     670             :             {
     671          26 :                 bIsStr1 = false;
     672          26 :                 nVal1 = pEff1->GetValue();
     673          26 :                 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         758 :     delete pTemp1;
     684             : 
     685         758 :     ScFormulaCell* pTemp2 = NULL;
     686         758 :     ScFormulaCell* pEff2 = pFCell2; //@ 1!=2
     687         758 :     if ( bRelRef2 )
     688             :     {
     689           0 :         pTemp2 = new ScFormulaCell( mpDoc, rPos, pFormula2 );    // ohne Listening
     690           0 :         pEff2 = pTemp2;
     691             :     }
     692         758 :     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         758 :     delete pTemp2;
     713             : 
     714             :     //  wenn IsRunning, bleiben die letzten Werte erhalten
     715             : 
     716         758 :     if (bDirty && !bFirstRun)
     717             :     {
     718             :         //  bei bedingten Formaten neu painten
     719             : 
     720           0 :         DataChanged( NULL );    // alles
     721             :     }
     722             : 
     723         758 :     bFirstRun = false;
     724         758 : }
     725             : 
     726        1430 : static bool lcl_GetCellContent( ScBaseCell* pCell, bool bIsStr1, double& rArg, rtl::OUString& rArgStr )
     727             : {
     728        1430 :     bool bVal = true;
     729             : 
     730        1430 :     if ( pCell )
     731             :     {
     732        1430 :         CellType eType = pCell->GetCellType();
     733        1430 :         switch( eType )
     734             :         {
     735             :             case CELLTYPE_VALUE:
     736        1430 :                 rArg = ((ScValueCell*)pCell)->GetValue();
     737        1430 :                 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        1430 :     if( !pCell )
     764           0 :         if( bIsStr1 )
     765           0 :             bVal = false;               // leere Zellen je nach Bedingung
     766             : 
     767        1430 :     return bVal;
     768             : }
     769             : 
     770         672 : void ScConditionEntry::FillCache() const
     771             : {
     772         672 :     if(!mpCache)
     773             :     {
     774          32 :         const ScRangeList& rRanges = pCondFormat->GetRange();
     775          32 :         mpCache.reset(new ScConditionEntryCache);
     776          32 :         size_t nListCount = rRanges.size();
     777          64 :         for( size_t i = 0; i < nListCount; i++ )
     778             :         {
     779          32 :             const ScRange *aRange = rRanges[i];
     780          32 :             SCROW nRow = aRange->aEnd.Row();
     781          32 :             SCCOL nCol = aRange->aEnd.Col();
     782          32 :             SCCOL nColStart = aRange->aStart.Col();
     783          32 :             SCROW nRowStart = aRange->aStart.Row();
     784          32 :             SCTAB nTab = aRange->aStart.Tab();
     785             : 
     786             :             // temporary fix to workaorund slow duplicate entry
     787             :             // conditions, prevent to use a whole row
     788          32 :             if(nRow == MAXROW)
     789             :             {
     790           0 :                 bool bShrunk = false;
     791             :                 mpDoc->ShrinkToUsedDataArea(bShrunk, nTab, nColStart, nRowStart,
     792           0 :                         nCol, nRow, false);
     793             :             }
     794             : 
     795         704 :             for( SCROW r = nRowStart; r <= nRow; r++ )
     796        1344 :                 for( SCCOL c = nColStart; c <= nCol; c++ )
     797             :                 {
     798         672 :                     double nVal = 0.0;
     799         672 :                     ScBaseCell *pCell = NULL;
     800             : 
     801         672 :                     mpDoc->GetCell( c, r, nTab, pCell );
     802         672 :                     if( !pCell )
     803           0 :                         continue;
     804             : 
     805         672 :                     rtl::OUString aStr;
     806         672 :                     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         672 :                         std::pair<ScConditionEntryCache::ValueCacheType::iterator, bool> aResult = mpCache->maValues.insert(std::pair<double, sal_Int32>(nVal, (sal_Int32)1));
     815         672 :                         if(!aResult.second)
     816         104 :                             aResult.first->second++;
     817             : 
     818         672 :                         ++(mpCache->nValueItems);
     819             :                     }
     820         672 :                 }
     821             :         }
     822             :     }
     823         672 : }
     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          84 : bool ScConditionEntry::IsTopNElement( double nArg ) const
     858             : {
     859          84 :     FillCache();
     860             : 
     861          84 :     if(mpCache->nValueItems <= nVal1)
     862           0 :         return true;
     863             : 
     864          84 :     size_t nCells = 0;
     865         528 :     for(ScConditionEntryCache::ValueCacheType::const_reverse_iterator itr = mpCache->maValues.rbegin(),
     866          84 :             itrEnd = mpCache->maValues.rend(); itr != itrEnd; ++itr)
     867             :     {
     868         444 :         if(itr->first <= nArg)
     869          24 :             return true;
     870         420 :         if(nCells >= nVal1)
     871          60 :             return false;
     872         360 :         nCells += itr->second;
     873             :     }
     874             : 
     875           0 :     return true;
     876             : }
     877             : 
     878          84 : bool ScConditionEntry::IsBottomNElement( double nArg ) const
     879             : {
     880          84 :     FillCache();
     881             : 
     882          84 :     if(mpCache->nValueItems <= nVal1)
     883           0 :         return true;
     884             : 
     885          84 :     size_t nCells = 0;
     886         372 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     887          84 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     888             :     {
     889         288 :         if(itr->first >= nArg)
     890          28 :             return true;
     891         260 :         if(nCells >= nVal1)
     892          56 :             return false;
     893         204 :         nCells += itr->second;
     894             :     }
     895             : 
     896           0 :     return true;
     897             : }
     898             : 
     899          84 : bool ScConditionEntry::IsTopNPercent( double nArg ) const
     900             : {
     901          84 :     FillCache();
     902             : 
     903          84 :     size_t nCells = 0;
     904          84 :     size_t nLimitCells = static_cast<size_t>(mpCache->nValueItems*nVal1/100);
     905         324 :     for(ScConditionEntryCache::ValueCacheType::const_reverse_iterator itr = mpCache->maValues.rbegin(),
     906          84 :             itrEnd = mpCache->maValues.rend(); itr != itrEnd; ++itr)
     907             :     {
     908         240 :         if(itr->first <= nArg)
     909          12 :             return true;
     910         228 :         if(nCells >= nLimitCells)
     911          72 :             return false;
     912         156 :         nCells += itr->second;
     913             :     }
     914             : 
     915           0 :     return true;
     916             : }
     917             : 
     918          84 : bool ScConditionEntry::IsBottomNPercent( double nArg ) const
     919             : {
     920          84 :     FillCache();
     921             : 
     922          84 :     size_t nCells = 0;
     923          84 :     size_t nLimitCells = static_cast<size_t>(mpCache->nValueItems*nVal1/100);
     924         312 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     925          84 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     926             :     {
     927         228 :         if(itr->first >= nArg)
     928          24 :             return true;
     929         204 :         if(nCells >= nLimitCells)
     930          60 :             return false;
     931         144 :         nCells += itr->second;
     932             :     }
     933             : 
     934           0 :     return true;
     935             : }
     936             : 
     937         168 : bool ScConditionEntry::IsBelowAverage( double nArg ) const
     938             : {
     939         168 :     FillCache();
     940             : 
     941         168 :     double nSum = 0;
     942        3276 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     943         168 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     944             :     {
     945        2940 :         nSum += itr->first * itr->second;
     946             :     }
     947             : 
     948         168 :     if(nVal1)
     949          84 :         return (nArg <= nSum/mpCache->nValueItems);
     950             :     else
     951          84 :         return (nArg < nSum/mpCache->nValueItems);
     952             : }
     953             : 
     954         168 : bool ScConditionEntry::IsAboveAverage( double nArg ) const
     955             : {
     956         168 :     FillCache();
     957             : 
     958         168 :     double nSum = 0;
     959        3276 :     for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(),
     960         168 :             itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr)
     961             :     {
     962        2940 :         nSum += itr->first * itr->second;
     963             :     }
     964             : 
     965         168 :     if(nVal1)
     966          84 :         return (nArg >= nSum/mpCache->nValueItems);
     967             :     else
     968          84 :         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         758 : bool ScConditionEntry::IsValid( double nArg, const ScAddress& rPos ) const
     997             : {
     998             :     //  Interpret muss schon gerufen sein
     999             : 
    1000         758 :     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         758 :     if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
    1017          22 :         if ( bIsStr2 )
    1018           0 :             return false;
    1019             : 
    1020         758 :     double nComp1 = nVal1;      // Kopie, damit vertauscht werden kann
    1021         758 :     double nComp2 = nVal2;
    1022             : 
    1023         758 :     if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
    1024          22 :         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         758 :     bool bValid = false;
    1033         758 :     switch (eOp)
    1034             :     {
    1035             :         case SC_COND_NONE:
    1036           0 :             break;                  // immer sal_False;
    1037             :         case SC_COND_EQUAL:
    1038          14 :             bValid = ::rtl::math::approxEqual( nArg, nComp1 );
    1039          14 :             break;
    1040             :         case SC_COND_NOTEQUAL:
    1041           0 :             bValid = !::rtl::math::approxEqual( nArg, nComp1 );
    1042           0 :             break;
    1043             :         case SC_COND_GREATER:
    1044           8 :             bValid = ( nArg > nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
    1045           8 :             break;
    1046             :         case SC_COND_EQGREATER:
    1047           6 :             bValid = ( nArg >= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
    1048           6 :             break;
    1049             :         case SC_COND_LESS:
    1050          20 :             bValid = ( nArg < nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
    1051          20 :             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          12 :                      ::rtl::math::approxEqual( nArg, nComp1 ) || ::rtl::math::approxEqual( nArg, nComp2 );
    1058          12 :             break;
    1059             :         case SC_COND_NOTBETWEEN:
    1060             :             bValid = ( nArg < nComp1 || nArg > nComp2 ) &&
    1061          10 :                      !::rtl::math::approxEqual( nArg, nComp1 ) && !::rtl::math::approxEqual( nArg, nComp2 );
    1062          10 :             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          16 :             bValid = !::rtl::math::approxEqual( nComp1, 0.0 );
    1074          16 :             break;
    1075             :         case SC_COND_TOP10:
    1076          84 :             bValid = IsTopNElement( nArg );
    1077          84 :             break;
    1078             :         case SC_COND_BOTTOM10:
    1079          84 :             bValid = IsBottomNElement( nArg );
    1080          84 :             break;
    1081             :         case SC_COND_TOP_PERCENT:
    1082          84 :             bValid = IsTopNPercent( nArg );
    1083          84 :             break;
    1084             :         case SC_COND_BOTTOM_PERCENT:
    1085          84 :             bValid = IsBottomNPercent( nArg );
    1086          84 :             break;
    1087             :         case SC_COND_ABOVE_AVERAGE:
    1088         168 :             bValid = IsAboveAverage( nArg );
    1089         168 :             break;
    1090             :         case SC_COND_BELOW_AVERAGE:
    1091         168 :             bValid = IsBelowAverage( nArg );
    1092         168 :             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         758 :     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         758 : bool ScConditionEntry::IsCellValid( ScBaseCell* pCell, const ScAddress& rPos ) const
    1259             : {
    1260         758 :     ((ScConditionEntry*)this)->Interpret(rPos);         // Formeln auswerten
    1261             : 
    1262         758 :     double nArg = 0.0;
    1263         758 :     rtl::OUString aArgStr;
    1264         758 :     bool bVal = lcl_GetCellContent( pCell, bIsStr1, nArg, aArgStr );
    1265         758 :     if (bVal)
    1266         758 :         return IsValid( nArg, rPos );
    1267             :     else
    1268           0 :         return IsValidStr( aArgStr, rPos );
    1269             : }
    1270             : 
    1271          60 : rtl::OUString ScConditionEntry::GetExpression( const ScAddress& rCursor, sal_uInt16 nIndex,
    1272             :                                         sal_uLong nNumFmt,
    1273             :                                         const FormulaGrammar::Grammar eGrammar ) const
    1274             : {
    1275          60 :     rtl::OUString aRet;
    1276             : 
    1277          60 :     if ( FormulaGrammar::isEnglish( eGrammar) && nNumFmt == 0 )
    1278          52 :         nNumFmt = mpDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US );
    1279             : 
    1280          60 :     if ( nIndex==0 )
    1281             :     {
    1282          34 :         if ( pFormula1 )
    1283             :         {
    1284          26 :             ScCompiler aComp(mpDoc, rCursor, *pFormula1);
    1285          26 :             aComp.SetGrammar(eGrammar);
    1286          26 :             rtl::OUStringBuffer aBuffer;
    1287          26 :             aComp.CreateStringFromTokenArray( aBuffer );
    1288          26 :             aRet = aBuffer.makeStringAndClear();
    1289             :         }
    1290           8 :         else if (bIsStr1)
    1291             :         {
    1292           0 :             aRet = """";
    1293           0 :             aRet += aStrVal1;
    1294           0 :             aRet += """";
    1295             :         }
    1296             :         else
    1297           8 :             mpDoc->GetFormatTable()->GetInputLineString(nVal1, nNumFmt, aRet);
    1298             :     }
    1299          26 :     else if ( nIndex==1 )
    1300             :     {
    1301          26 :         if ( pFormula2 )
    1302             :         {
    1303           8 :             ScCompiler aComp(mpDoc, rCursor, *pFormula2);
    1304           8 :             aComp.SetGrammar(eGrammar);
    1305           8 :             rtl::OUStringBuffer aBuffer;
    1306           8 :             aComp.CreateStringFromTokenArray( aBuffer );
    1307           8 :             aRet = aBuffer.makeStringAndClear();
    1308             :         }
    1309          18 :         else if (bIsStr2)
    1310             :         {
    1311           0 :             aRet = """";
    1312           0 :             aRet += aStrVal2;
    1313           0 :             aRet += """";
    1314             :         }
    1315             :         else
    1316          18 :             mpDoc->GetFormatTable()->GetInputLineString(nVal2, nNumFmt, aRet);
    1317             :     }
    1318             :     else
    1319             :     {
    1320             :         SAL_WARN("sc", "GetExpression: falscher Index");
    1321             :     }
    1322             : 
    1323          60 :     return aRet;
    1324             : }
    1325             : 
    1326          24 : ScTokenArray* ScConditionEntry::CreateTokenArry( sal_uInt16 nIndex ) const
    1327             : {
    1328          24 :     ScTokenArray* pRet = NULL;
    1329          24 :     ScAddress aAddr;
    1330             : 
    1331          24 :     if ( nIndex==0 )
    1332             :     {
    1333          24 :         if ( pFormula1 )
    1334           0 :             pRet = new ScTokenArray( *pFormula1 );
    1335             :         else
    1336             :         {
    1337          24 :             pRet = new ScTokenArray();
    1338          24 :             if (bIsStr1)
    1339           0 :                 pRet->AddString( aStrVal1 );
    1340             :             else
    1341          24 :                 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          24 :     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           8 : ScAddress ScConditionEntry::GetValidSrcPos() const
    1451             : {
    1452             :     // return a position that's adjusted to allow textual representation of expressions if possible
    1453             : 
    1454           8 :     SCTAB nMinTab = aSrcPos.Tab();
    1455           8 :     SCTAB nMaxTab = nMinTab;
    1456             : 
    1457          24 :     for (sal_uInt16 nPass = 0; nPass < 2; nPass++)
    1458             :     {
    1459          16 :         ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
    1460          16 :         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           8 :     ScAddress aValidPos = aSrcPos;
    1490           8 :     SCTAB nTabCount = mpDoc->GetTableCount();
    1491           8 :     if ( nMaxTab >= nTabCount && nMinTab > 0 )
    1492           0 :         aValidPos.SetTab( aSrcPos.Tab() - nMinTab );    // so the lowest tab ref will be on 0
    1493             : 
    1494           8 :     if ( aValidPos.Tab() >= nTabCount )
    1495           0 :         aValidPos.SetTab( nTabCount - 1 );  // ensure a valid position even if some references will be invalid
    1496             : 
    1497           8 :     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          50 : ScConditionMode ScConditionEntry::GetModeFromApi(sal_Int32 nOperation)
    1523             : {
    1524          50 :     ScConditionMode eMode = SC_COND_NONE;
    1525          50 :     switch (nOperation)
    1526             :     {
    1527             :         case com::sun::star::sheet::ConditionOperator2::EQUAL:
    1528           4 :             eMode = SC_COND_EQUAL;
    1529           4 :             break;
    1530             :         case com::sun::star::sheet::ConditionOperator2::LESS:
    1531           2 :             eMode = SC_COND_LESS;
    1532           2 :             break;
    1533             :         case com::sun::star::sheet::ConditionOperator2::GREATER:
    1534          10 :             eMode = SC_COND_GREATER;
    1535          10 :             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           4 :             eMode = SC_COND_EQGREATER;
    1541           4 :             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          22 :             eMode = SC_COND_BETWEEN;
    1547          22 :             break;
    1548             :         case com::sun::star::sheet::ConditionOperator2::NOT_BETWEEN:
    1549           4 :             eMode = SC_COND_NOTBETWEEN;
    1550           4 :             break;
    1551             :         case com::sun::star::sheet::ConditionOperator2::FORMULA:
    1552           4 :             eMode = SC_COND_DIRECT;
    1553           4 :             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          50 :     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          22 : 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          22 :     aStyleName( rStyle )
    1587             : {
    1588          22 : }
    1589             : 
    1590          94 : 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          94 :     aStyleName( rStyle )
    1596             : {
    1597          94 : }
    1598             : 
    1599           0 : ScCondFormatEntry::ScCondFormatEntry( const ScCondFormatEntry& r ) :
    1600             :     ScConditionEntry( r ),
    1601           0 :     aStyleName( r.aStyleName )
    1602             : {
    1603           0 : }
    1604             : 
    1605          22 : ScCondFormatEntry::ScCondFormatEntry( ScDocument* pDocument, const ScCondFormatEntry& r ) :
    1606             :     ScConditionEntry( pDocument, r ),
    1607          22 :     aStyleName( r.aStyleName )
    1608             : {
    1609          22 : }
    1610             : 
    1611           2 : int ScCondFormatEntry::operator== ( const ScCondFormatEntry& r ) const
    1612             : {
    1613           2 :     return ScConditionEntry::operator==( r ) &&
    1614           2 :             aStyleName == r.aStyleName;
    1615             : }
    1616             : 
    1617         212 : ScCondFormatEntry::~ScCondFormatEntry()
    1618             : {
    1619         212 : }
    1620             : 
    1621           0 : void ScCondFormatEntry::DataChanged( const ScRange* pModified ) const
    1622             : {
    1623           0 :     if ( pCondFormat )
    1624           0 :         pCondFormat->DoRepaint( pModified );
    1625           0 : }
    1626             : 
    1627          22 : ScFormatEntry* ScCondFormatEntry::Clone( ScDocument* pDoc ) const
    1628             : {
    1629          22 :     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.GetYear() == aCellDate.GetYear() && rActDate.GetMonth() == aCellDate.GetMonth() )
    1688             :             {
    1689           0 :                 if( rActDate.GetWeekOfYear( SUNDAY ) == aCellDate.GetWeekOfYear( SUNDAY ) + 1 )
    1690           0 :                     return true;
    1691             :             }
    1692           0 :             break;
    1693             :         case condformat::THISWEEK:
    1694           0 :             if( rActDate.GetYear() == aCellDate.GetYear() && rActDate.GetMonth() == aCellDate.GetMonth() )
    1695             :             {
    1696           0 :                 if( rActDate.GetWeekOfYear( SUNDAY ) == aCellDate.GetWeekOfYear( SUNDAY ) )
    1697           0 :                     return true;
    1698             :             }
    1699           0 :             break;
    1700             :         case condformat::NEXTWEEK:
    1701           0 :             if( rActDate.GetYear() == aCellDate.GetYear() && rActDate.GetMonth() == aCellDate.GetMonth() )
    1702             :             {
    1703           0 :                 if( rActDate.GetWeekOfYear( SUNDAY ) == aCellDate.GetWeekOfYear( SUNDAY ) - 1 )
    1704           0 :                     return true;
    1705             :             }
    1706           0 :             break;
    1707             :         case condformat::LASTMONTH:
    1708           0 :             if( rActDate.GetYear() == aCellDate.GetYear() )
    1709             :             {
    1710           0 :                 if( rActDate.GetMonth() == aCellDate.GetMonth() + 1)
    1711           0 :                     return true;
    1712             :             }
    1713           0 :             break;
    1714             :         case condformat::THISMONTH:
    1715           0 :             if( rActDate.GetYear() == aCellDate.GetYear() )
    1716             :             {
    1717           0 :                 if( rActDate.GetMonth() == aCellDate.GetMonth() )
    1718           0 :                     return true;
    1719             :             }
    1720           0 :             break;
    1721             :         case condformat::NEXTMONTH:
    1722           0 :             if( rActDate.GetYear() == aCellDate.GetYear() )
    1723             :             {
    1724           0 :                 if( rActDate.GetMonth() == aCellDate.GetMonth() - 1)
    1725           0 :                     return true;
    1726             :             }
    1727           0 :             break;
    1728             :         case condformat::LASTYEAR:
    1729           0 :             if( rActDate.GetYear() == aCellDate.GetYear() + 1 )
    1730           0 :                 return true;
    1731           0 :             break;
    1732             :         case condformat::THISYEAR:
    1733           0 :             if( rActDate.GetYear() == aCellDate.GetYear() )
    1734           0 :                 return true;
    1735           0 :             break;
    1736             :         case condformat::NEXTYEAR:
    1737           0 :             if( rActDate.GetYear() == aCellDate.GetYear() - 1 )
    1738           0 :                 return true;
    1739           0 :             break;
    1740             :     }
    1741             : 
    1742           0 :     return false;
    1743             : }
    1744             : 
    1745           0 : void ScCondDateFormatEntry::SetDateType( condformat::ScCondFormatDateType eType )
    1746             : {
    1747           0 :     meType = eType;
    1748           0 : }
    1749             : 
    1750           0 : condformat::ScCondFormatDateType ScCondDateFormatEntry::GetDateType() const
    1751             : {
    1752           0 :     return meType;
    1753             : }
    1754             : 
    1755           0 : const rtl::OUString& ScCondDateFormatEntry::GetStyleName() const
    1756             : {
    1757           0 :     return maStyleName;
    1758             : }
    1759             : 
    1760           0 : void ScCondDateFormatEntry::SetStyleName( const rtl::OUString& rStyleName )
    1761             : {
    1762           0 :     maStyleName = rStyleName;
    1763           0 : }
    1764             : 
    1765           0 : ScFormatEntry* ScCondDateFormatEntry::Clone( ScDocument* pDoc ) const
    1766             : {
    1767           0 :     return new ScCondDateFormatEntry( pDoc, *this );
    1768             : }
    1769             : 
    1770           0 : bool ScCondDateFormatEntry::operator==( const ScFormatEntry& r ) const
    1771             : {
    1772           0 :     if(r.GetType() != condformat::DATE)
    1773           0 :         return false;
    1774             : 
    1775           0 :     const ScCondDateFormatEntry& rEntry = static_cast<const ScCondDateFormatEntry&>(r);
    1776             : 
    1777           0 :     if(rEntry.meType != meType)
    1778           0 :         return false;
    1779             : 
    1780           0 :     return rEntry.maStyleName == maStyleName;
    1781             : }
    1782             : 
    1783           0 : void ScCondDateFormatEntry::dumpInfo( rtl::OUStringBuffer& rBuffer ) const
    1784             : {
    1785           0 :     rBuffer.append("Date Format");
    1786           0 : }
    1787             : 
    1788           0 : void ScCondDateFormatEntry::startRendering()
    1789             : {
    1790           0 :     mpCache.reset();
    1791           0 : }
    1792             : 
    1793           0 : void ScCondDateFormatEntry::endRendering()
    1794             : {
    1795           0 :     mpCache.reset();
    1796           0 : }
    1797             : 
    1798             : //------------------------------------------------------------------------
    1799             : 
    1800          74 : ScConditionalFormat::ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument) :
    1801             :     pDoc( pDocument ),
    1802          74 :     nKey( nNewKey )
    1803             : {
    1804          74 : }
    1805             : 
    1806           0 : ScConditionalFormat::ScConditionalFormat(const ScConditionalFormat& r) :
    1807             :     pDoc( r.pDoc ),
    1808             :     nKey( r.nKey ),
    1809           0 :     maRanges( r.maRanges )
    1810             : {
    1811           0 :     for (CondFormatContainer::const_iterator itr = r.maEntries.begin(); itr != r.maEntries.end(); ++itr)
    1812             :     {
    1813           0 :         ScFormatEntry* pNewEntry = itr->Clone(r.pDoc);
    1814           0 :         maEntries.push_back( pNewEntry );
    1815           0 :         pNewEntry->SetParent(this);
    1816             :     }
    1817           0 : }
    1818             : 
    1819           6 : ScConditionalFormat* ScConditionalFormat::Clone(ScDocument* pNewDoc) const
    1820             : {
    1821             :     // echte Kopie der Formeln (fuer Ref-Undo / zwischen Dokumenten)
    1822             : 
    1823           6 :     if (!pNewDoc)
    1824           6 :         pNewDoc = pDoc;
    1825             : 
    1826           6 :     ScConditionalFormat* pNew = new ScConditionalFormat(nKey, pNewDoc);
    1827             : 
    1828          28 :     for (CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1829             :     {
    1830          22 :         ScFormatEntry* pNewEntry = itr->Clone(pNewDoc);
    1831          22 :         pNew->maEntries.push_back( pNewEntry );
    1832          22 :         pNewEntry->SetParent(pNew);
    1833             :     }
    1834           6 :     pNew->AddRange( maRanges );
    1835             : 
    1836           6 :     return pNew;
    1837             : }
    1838             : 
    1839           6 : bool ScConditionalFormat::EqualEntries( const ScConditionalFormat& r ) const
    1840             : {
    1841           6 :     if( size() != r.size())
    1842           4 :         return false;
    1843             : 
    1844             :     //! auf gleiche Eintraege in anderer Reihenfolge testen ???
    1845             : 
    1846           2 :     for (sal_uInt16 i=0; i<size(); i++)
    1847           2 :         if ( ! (maEntries == r.maEntries ) )
    1848           2 :             return false;
    1849             : 
    1850             :     // right now don't check for same range
    1851             :     // we only use this method to merge same conditional formats from
    1852             :     // old ODF data structure
    1853           0 :     return true;
    1854             : }
    1855             : 
    1856          74 : void ScConditionalFormat::AddRange( const ScRangeList& rRanges )
    1857             : {
    1858          74 :     maRanges = rRanges;
    1859          74 : }
    1860             : 
    1861         116 : void ScConditionalFormat::AddEntry( ScFormatEntry* pNew )
    1862             : {
    1863         116 :     maEntries.push_back(pNew);
    1864         116 :     pNew->SetParent(this);
    1865         116 : }
    1866             : 
    1867          42 : ScConditionalFormat::~ScConditionalFormat()
    1868             : {
    1869          42 : }
    1870             : 
    1871          32 : const ScFormatEntry* ScConditionalFormat::GetEntry( sal_uInt16 nPos ) const
    1872             : {
    1873          32 :     if ( nPos < size() )
    1874          32 :         return &maEntries[nPos];
    1875             :     else
    1876           0 :         return NULL;
    1877             : }
    1878             : 
    1879         708 : const rtl::OUString& ScConditionalFormat::GetCellStyle( ScBaseCell* pCell, const ScAddress& rPos ) const
    1880             : {
    1881        1172 :     for (CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1882             :     {
    1883         758 :         if(itr->GetType() == condformat::CONDITION)
    1884             :         {
    1885         758 :             const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(*itr);
    1886         758 :             if ( rEntry.IsCellValid( pCell, rPos ) )
    1887         294 :                 return rEntry.GetStyle();
    1888             :         }
    1889           0 :         else if(itr->GetType() == condformat::DATE)
    1890             :         {
    1891           0 :             const ScCondDateFormatEntry& rEntry = static_cast<const ScCondDateFormatEntry&>(*itr);
    1892           0 :             if (rEntry.IsValid( rPos ))
    1893           0 :                 return rEntry.GetStyleName();
    1894             :         }
    1895             :     }
    1896             : 
    1897         414 :     return EMPTY_OUSTRING;
    1898             : }
    1899             : 
    1900           0 : ScCondFormatData ScConditionalFormat::GetData( ScBaseCell* pCell, const ScAddress& rPos ) const
    1901             : {
    1902           0 :     ScCondFormatData aData;
    1903           0 :     for(CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1904             :     {
    1905           0 :         if(itr->GetType() == condformat::CONDITION && aData.aStyleName.isEmpty())
    1906             :         {
    1907           0 :             const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(*itr);
    1908           0 :             if ( rEntry.IsCellValid( pCell, rPos ) )
    1909           0 :                 aData.aStyleName = rEntry.GetStyle();
    1910             :         }
    1911           0 :         else if(itr->GetType() == condformat::COLORSCALE && !aData.pColorScale)
    1912             :         {
    1913           0 :             const ScColorScaleFormat& rEntry = static_cast<const ScColorScaleFormat&>(*itr);
    1914           0 :             aData.pColorScale = rEntry.GetColor(rPos);
    1915             :         }
    1916           0 :         else if(itr->GetType() == condformat::DATABAR && !aData.pDataBar)
    1917             :         {
    1918           0 :             const ScDataBarFormat& rEntry = static_cast<const ScDataBarFormat&>(*itr);
    1919           0 :             aData.pDataBar = rEntry.GetDataBarInfo(rPos);
    1920             :         }
    1921           0 :         else if(itr->GetType() == condformat::ICONSET && !aData.pIconSet)
    1922             :         {
    1923           0 :             const ScIconSetFormat& rEntry = static_cast<const ScIconSetFormat&>(*itr);
    1924           0 :             aData.pIconSet = rEntry.GetIconSetInfo(rPos);
    1925             :         }
    1926           0 :         else if(itr->GetType() == condformat::DATE && aData.aStyleName.isEmpty())
    1927             :         {
    1928           0 :             const ScCondDateFormatEntry& rEntry = static_cast<const ScCondDateFormatEntry&>(*itr);
    1929           0 :             if ( rEntry.IsValid( rPos ) )
    1930           0 :                 aData.aStyleName = rEntry.GetStyleName();
    1931             :         }
    1932             :     }
    1933           0 :     return aData;
    1934             : }
    1935             : 
    1936             : 
    1937             : #if DUMP_FORMAT_INFO
    1938           0 : void ScConditionalFormat::dumpInfo(rtl::OUStringBuffer& rBuf) const
    1939             : {
    1940           0 :     for(CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1941             :     {
    1942           0 :         itr->dumpInfo(rBuf);
    1943             :     }
    1944           0 : }
    1945             : #endif
    1946             : 
    1947           0 : void ScConditionalFormat::DoRepaint( const ScRange* pModified )
    1948             : {
    1949           0 :     if(pModified)
    1950           0 :         pDoc->RepaintRange(*pModified);
    1951             :     else
    1952             :     {
    1953             :         // all conditional format cells
    1954           0 :         pDoc->RepaintRange( maRanges );
    1955             :     }
    1956           0 : }
    1957             : 
    1958           0 : void ScConditionalFormat::CompileAll()
    1959             : {
    1960           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1961           0 :         if(itr->GetType() == condformat::CONDITION)
    1962           0 :             static_cast<ScCondFormatEntry&>(*itr).CompileAll();
    1963           0 : }
    1964             : 
    1965           6 : void ScConditionalFormat::CompileXML()
    1966             : {
    1967          28 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1968          22 :         if(itr->GetType() == condformat::CONDITION)
    1969          22 :             static_cast<ScCondFormatEntry&>(*itr).CompileXML();
    1970           6 : }
    1971             : 
    1972           0 : void ScConditionalFormat::UpdateReference( UpdateRefMode eUpdateRefMode,
    1973             :                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    1974             : {
    1975           0 :     if( eUpdateRefMode == URM_COPY && nDz != 0 )
    1976           0 :         maRanges.UpdateReference( URM_MOVE, pDoc, rRange, nDx, nDy, nDz );
    1977             :     else
    1978           0 :         maRanges.UpdateReference( eUpdateRefMode, pDoc, rRange, nDx, nDy, nDz );
    1979             : 
    1980           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1981           0 :         itr->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz);
    1982           0 : }
    1983             : 
    1984           0 : void ScConditionalFormat::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    1985             : {
    1986           0 :     SCTAB nTab = maRanges[0]->aStart.Tab();
    1987           0 :     maRanges.DeleteArea( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
    1988           0 : }
    1989             : 
    1990           0 : void ScConditionalFormat::RenameCellStyle(const rtl::OUString& rOld, const rtl::OUString& rNew)
    1991             : {
    1992           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    1993           0 :         if(itr->GetType() == condformat::CONDITION)
    1994             :         {
    1995           0 :             ScCondFormatEntry& rFormat = static_cast<ScCondFormatEntry&>(*itr);
    1996           0 :             if(rFormat.GetStyle() == rOld)
    1997           0 :                 rFormat.UpdateStyleName( rNew );
    1998             :         }
    1999           0 : }
    2000             : 
    2001           0 : void ScConditionalFormat::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
    2002             : {
    2003           0 :     size_t n = maRanges.size();
    2004           0 :     SCTAB nMinTab = std::min<SCTAB>(nOldPos, nNewPos);
    2005           0 :     SCTAB nMaxTab = std::max<SCTAB>(nOldPos, nNewPos);
    2006           0 :     for(size_t i = 0; i < n; ++i)
    2007             :     {
    2008           0 :         ScRange* pRange = maRanges[i];
    2009           0 :         SCTAB nTab = pRange->aStart.Tab();
    2010           0 :         if(nTab < nMinTab || nTab > nMaxTab)
    2011             :         {
    2012           0 :             continue;
    2013             :         }
    2014             : 
    2015           0 :         if(nTab == nOldPos)
    2016             :         {
    2017           0 :             pRange->aStart.SetTab(nNewPos);
    2018           0 :             pRange->aEnd.SetTab(nNewPos);
    2019           0 :             continue;
    2020             :         }
    2021             : 
    2022           0 :         if(nNewPos < nOldPos)
    2023             :         {
    2024           0 :             pRange->aStart.IncTab();
    2025           0 :             pRange->aEnd.IncTab();
    2026             :         }
    2027             :         else
    2028             :         {
    2029           0 :             pRange->aStart.IncTab(-1);
    2030           0 :             pRange->aEnd.IncTab(-1);
    2031             :         }
    2032             :     }
    2033             : 
    2034           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2035           0 :         itr->UpdateMoveTab( nOldPos, nNewPos );
    2036           0 : }
    2037             : 
    2038           0 : void ScConditionalFormat::SourceChanged( const ScAddress& rAddr )
    2039             : {
    2040           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2041           0 :         if(itr->GetType() == condformat::CONDITION)
    2042             :         {
    2043           0 :             ScCondFormatEntry& rFormat = static_cast<ScCondFormatEntry&>(*itr);
    2044           0 :             rFormat.SourceChanged( rAddr );
    2045             :         }
    2046           0 : }
    2047             : 
    2048           0 : bool ScConditionalFormat::MarkUsedExternalReferences() const
    2049             : {
    2050           0 :     bool bAllMarked = false;
    2051           0 :     for(CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end() && !bAllMarked; ++itr)
    2052           0 :         if(itr->GetType() == condformat::CONDITION)
    2053             :         {
    2054           0 :             const ScCondFormatEntry& rFormat = static_cast<const ScCondFormatEntry&>(*itr);
    2055           0 :             bAllMarked = rFormat.MarkUsedExternalReferences();
    2056             :         }
    2057             : 
    2058           0 :     return bAllMarked;
    2059             : }
    2060             : 
    2061           0 : void ScConditionalFormat::startRendering()
    2062             : {
    2063           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2064             :     {
    2065           0 :         itr->startRendering();
    2066             :     }
    2067           0 : }
    2068             : 
    2069           0 : void ScConditionalFormat::endRendering()
    2070             : {
    2071           0 :     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
    2072             :     {
    2073           0 :         itr->endRendering();
    2074             :     }
    2075           0 : }
    2076             : 
    2077             : //------------------------------------------------------------------------
    2078             : 
    2079           6 : ScConditionalFormatList::ScConditionalFormatList(const ScConditionalFormatList& rList)
    2080             : {
    2081           6 :     for(const_iterator itr = rList.begin(); itr != rList.end(); ++itr)
    2082           0 :         InsertNew( itr->Clone() );
    2083           6 : }
    2084             : 
    2085          90 : ScConditionalFormatList::ScConditionalFormatList(ScDocument* pDoc, const ScConditionalFormatList& rList)
    2086             : {
    2087          90 :     for(const_iterator itr = rList.begin(); itr != rList.end(); ++itr)
    2088           0 :         InsertNew( itr->Clone(pDoc) );
    2089          90 : }
    2090             : 
    2091           0 : bool ScConditionalFormatList::operator==( const ScConditionalFormatList& r ) const
    2092             : {
    2093             :     // fuer Ref-Undo - interne Variablen werden nicht verglichen
    2094             : 
    2095           0 :     sal_uInt16 nCount = size();
    2096           0 :     bool bEqual = ( nCount == r.size() );
    2097           0 :     const_iterator locIterator = begin();
    2098           0 :     for(const_iterator itr = r.begin(); itr != r.end() && bEqual; ++itr, ++locIterator)
    2099           0 :         if ( !locIterator->EqualEntries(*itr) )         // Eintraege unterschiedlich ?
    2100           0 :             bEqual = false;
    2101             : 
    2102           0 :     return bEqual;
    2103             : }
    2104             : 
    2105         726 : ScConditionalFormat* ScConditionalFormatList::GetFormat( sal_uInt32 nKey )
    2106             : {
    2107             :     //! binaer suchen
    2108             : 
    2109        3124 :     for( iterator itr = begin(); itr != end(); ++itr)
    2110        3124 :         if (itr->GetKey() == nKey)
    2111         726 :             return &(*itr);
    2112             : 
    2113             :     SAL_WARN("sc", "ScConditionalFormatList: Eintrag nicht gefunden");
    2114           0 :     return NULL;
    2115             : }
    2116             : 
    2117           6 : void ScConditionalFormatList::CompileAll()
    2118             : {
    2119           6 :     for( iterator itr = begin(); itr != end(); ++itr)
    2120           0 :         itr->CompileAll();
    2121           6 : }
    2122             : 
    2123         158 : void ScConditionalFormatList::CompileXML()
    2124             : {
    2125         164 :     for( iterator itr = begin(); itr != end(); ++itr)
    2126           6 :         itr->CompileXML();
    2127         158 : }
    2128             : 
    2129         274 : void ScConditionalFormatList::UpdateReference( UpdateRefMode eUpdateRefMode,
    2130             :                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    2131             : {
    2132         274 :     for( iterator itr = begin(); itr != end(); ++itr)
    2133           0 :         itr->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz );
    2134             : 
    2135         274 :     if( eUpdateRefMode == URM_INSDEL )
    2136             :     {
    2137             :         // need to check which must be deleted
    2138         254 :         iterator itr = begin();
    2139         508 :         while(itr != end())
    2140             :         {
    2141           0 :             if(itr->GetRange().empty())
    2142           0 :                 maConditionalFormats.erase(itr++);
    2143             :             else
    2144           0 :                 ++itr;
    2145             :         }
    2146             :     }
    2147         274 : }
    2148             : 
    2149           0 : void ScConditionalFormatList::RenameCellStyle( const rtl::OUString& rOld, const rtl::OUString& rNew )
    2150             : {
    2151           0 :     for( iterator itr = begin(); itr != end(); ++itr)
    2152           0 :         itr->RenameCellStyle(rOld,rNew);
    2153           0 : }
    2154             : 
    2155          20 : void ScConditionalFormatList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
    2156             : {
    2157          20 :     for( iterator itr = begin(); itr != end(); ++itr)
    2158           0 :         itr->UpdateMoveTab( nOldPos, nNewPos );
    2159          20 : }
    2160             : 
    2161         198 : bool ScConditionalFormatList::CheckAllEntries()
    2162             : {
    2163         198 :     bool bValid = true;
    2164             :     //
    2165             :     // need to check which must be deleted
    2166         198 :     iterator itr = begin();
    2167         396 :     while(itr != end())
    2168             :     {
    2169           0 :         if(itr->GetRange().empty())
    2170             :         {
    2171           0 :             bValid = false;
    2172           0 :             maConditionalFormats.erase(itr++);
    2173             :         }
    2174             :         else
    2175           0 :             ++itr;
    2176             :     }
    2177             : 
    2178         198 :     return bValid;
    2179             : }
    2180             : 
    2181         198 : void ScConditionalFormatList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    2182             : {
    2183         198 :     for( iterator itr = begin(); itr != end(); ++itr)
    2184           0 :         itr->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
    2185             : 
    2186         198 :     CheckAllEntries();
    2187         198 : }
    2188             : 
    2189       13032 : void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
    2190             : {
    2191       13032 :     for( iterator itr = begin(); itr != end(); ++itr)
    2192           0 :         itr->SourceChanged( rAddr );
    2193       13032 : }
    2194             : 
    2195       15306 : ScConditionalFormatList::iterator ScConditionalFormatList::begin()
    2196             : {
    2197       15306 :     return maConditionalFormats.begin();
    2198             : }
    2199             : 
    2200          98 : ScConditionalFormatList::const_iterator ScConditionalFormatList::begin() const
    2201             : {
    2202          98 :     return maConditionalFormats.begin();
    2203             : }
    2204             : 
    2205       17918 : ScConditionalFormatList::iterator ScConditionalFormatList::end()
    2206             : {
    2207       17918 :     return maConditionalFormats.end();
    2208             : }
    2209             : 
    2210         114 : ScConditionalFormatList::const_iterator ScConditionalFormatList::end() const
    2211             : {
    2212         114 :     return maConditionalFormats.end();
    2213             : }
    2214             : 
    2215           4 : size_t ScConditionalFormatList::size() const
    2216             : {
    2217           4 :     return maConditionalFormats.size();
    2218             : }
    2219             : 
    2220           0 : void ScConditionalFormatList::erase( sal_uLong nIndex )
    2221             : {
    2222           0 :     for( iterator itr = begin(); itr != end(); ++itr )
    2223             :     {
    2224           0 :         if( itr->GetKey() == nIndex )
    2225             :         {
    2226           0 :             maConditionalFormats.erase(itr);
    2227           0 :             break;
    2228             :         }
    2229             :     }
    2230           0 : }
    2231             : 
    2232         182 : void ScConditionalFormatList::startRendering()
    2233             : {
    2234         182 :     for(iterator itr = begin(); itr != end(); ++itr)
    2235             :     {
    2236           0 :         itr->startRendering();
    2237             :     }
    2238         182 : }
    2239             : 
    2240         182 : void ScConditionalFormatList::endRendering()
    2241             : {
    2242         182 :     for(iterator itr = begin(); itr != end(); ++itr)
    2243             :     {
    2244           0 :         itr->endRendering();
    2245             :     }
    2246         182 : }
    2247             : 
    2248             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10