LCOV - code coverage report
Current view: top level - sc/source/core/data - dociter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 636 1243 51.2 %
Date: 2012-08-25 Functions: 48 84 57.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 504 1268 39.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <svl/zforlist.hxx>
      30                 :            : 
      31                 :            : #include "scitems.hxx"
      32                 :            : #include "global.hxx"
      33                 :            : #include "dociter.hxx"
      34                 :            : #include "document.hxx"
      35                 :            : #include "table.hxx"
      36                 :            : #include "column.hxx"
      37                 :            : #include "cell.hxx"
      38                 :            : #include "attarray.hxx"
      39                 :            : #include "patattr.hxx"
      40                 :            : #include "docoptio.hxx"
      41                 :            : #include "cellform.hxx"
      42                 :            : #include "segmenttree.hxx"
      43                 :            : #include "progress.hxx"
      44                 :            : #include "queryparam.hxx"
      45                 :            : #include "queryentry.hxx"
      46                 :            : #include "globstr.hrc"
      47                 :            : #include "tools/fract.hxx"
      48                 :            : 
      49                 :            : #include <vector>
      50                 :            : 
      51                 :            : using ::rtl::math::approxEqual;
      52                 :            : using ::std::vector;
      53                 :            : using ::rtl::OUString;
      54                 :            : using ::std::set;
      55                 :            : 
      56                 :            : // STATIC DATA -----------------------------------------------------------
      57                 :            : 
      58                 :            : namespace
      59                 :            : {
      60                 :          0 :     void lcl_uppercase(OUString& rStr)
      61                 :            :     {
      62         [ #  # ]:          0 :         rStr = ScGlobal::pCharClass->uppercase(rStr.trim());
      63                 :          0 :     }
      64                 :            : }
      65                 :            : 
      66                 :          0 : ScDocumentIterator::ScDocumentIterator( ScDocument* pDocument,
      67                 :            :                             SCTAB nStartTable, SCTAB nEndTable ) :
      68                 :            :     pDoc( pDocument ),
      69                 :            :     nStartTab( nStartTable ),
      70                 :          0 :     nEndTab( nEndTable )
      71                 :            : {
      72                 :          0 :     SCTAB nDocMaxTab = pDoc->GetTableCount() - 1;
      73                 :          0 :     PutInOrder( nStartTab, nEndTab );
      74 [ #  # ][ #  # ]:          0 :     if (!ValidTab(nStartTab) || nStartTab > nDocMaxTab ) nStartTab = nDocMaxTab;
                 [ #  # ]
      75 [ #  # ][ #  # ]:          0 :     if (!ValidTab(nEndTab) || nStartTab > nDocMaxTab ) nEndTab = nDocMaxTab;
                 [ #  # ]
      76                 :            : 
      77                 :          0 :     pDefPattern = pDoc->GetDefPattern();
      78                 :            : 
      79                 :          0 :     nCol = 0;
      80                 :          0 :     nRow = 0;
      81                 :          0 :     nTab = nStartTab;
      82                 :            : 
      83                 :          0 :     nColPos = 0;
      84                 :          0 :     nAttrPos = 0;
      85                 :          0 : }
      86                 :            : 
      87                 :          0 : ScDocumentIterator::~ScDocumentIterator()
      88                 :            : {
      89                 :          0 : }
      90                 :            : 
      91                 :          0 : bool ScDocumentIterator::GetThisCol()
      92                 :            : {
      93                 :          0 :     ScTable*        pTab = NULL;
      94 [ #  # ][ #  # ]:          0 :     while ( nTab < pDoc->GetTableCount() && (pTab = pDoc->maTabs[nTab]) == NULL )
                 [ #  # ]
      95                 :            :     {
      96         [ #  # ]:          0 :         if ( nTab == nEndTab )
      97                 :            :         {
      98                 :          0 :             nCol = MAXCOL;
      99                 :          0 :             nRow = MAXROW;
     100                 :          0 :             return false;
     101                 :            :         }
     102                 :          0 :         ++nTab;
     103                 :            :     }
     104         [ #  # ]:          0 :     if (pTab == NULL)
     105                 :            :     {
     106                 :            :         OSL_FAIL("no table in document?");
     107                 :          0 :         return false;
     108                 :            :     }
     109                 :          0 :     ScColumn*       pCol = &pTab->aCol[nCol];
     110                 :          0 :     ScAttrArray*    pAtt = pCol->pAttrArray;
     111                 :            : 
     112                 :          0 :     bool bFound = false;
     113 [ #  # ][ #  # ]:          0 :     do
                 [ #  # ]
     114                 :            :     {
     115                 :            :         SCROW nColRow;
     116                 :            :         SCROW nAttrEnd;
     117                 :            : 
     118         [ #  # ]:          0 :         do
     119                 :            :         {
     120                 :          0 :             nAttrEnd = pAtt->pData[nAttrPos].nRow;
     121         [ #  # ]:          0 :             if (nAttrEnd < nRow)
     122                 :          0 :                 ++nAttrPos;
     123                 :            :         }
     124                 :            :         while (nAttrEnd < nRow);
     125                 :            : 
     126         [ #  # ]:          0 :         do
     127                 :            :         {
     128         [ #  # ]:          0 :             nColRow = (nColPos < pCol->maItems.size()) ? pCol->maItems[nColPos].nRow : MAXROW+1;
     129         [ #  # ]:          0 :             if (nColRow < nRow)
     130                 :          0 :                 ++nColPos;
     131                 :            :         }
     132                 :            :         while (nColRow < nRow);
     133                 :            : 
     134         [ #  # ]:          0 :         if (nColRow == nRow)
     135                 :            :         {
     136                 :          0 :             bFound   = true;
     137                 :          0 :             pCell    = pCol->maItems[nColPos].pCell;
     138                 :          0 :             pPattern = pAtt->pData[nAttrPos].pPattern;
     139                 :            :         }
     140         [ #  # ]:          0 :         else if ( pAtt->pData[nAttrPos].pPattern != pDefPattern )
     141                 :            :         {
     142                 :          0 :             bFound = true;
     143                 :          0 :             pCell = NULL;
     144                 :          0 :             pPattern = pAtt->pData[nAttrPos].pPattern;
     145                 :            :         }
     146                 :            :         else
     147                 :            :         {
     148                 :          0 :             nRow = Min( (SCROW)nColRow, (SCROW)(nAttrEnd+1) );
     149                 :            :         }
     150                 :            :     }
     151                 :          0 :     while (!bFound && nRow <= MAXROW);
     152                 :            : 
     153                 :          0 :     return bFound;
     154                 :            : }
     155                 :            : 
     156                 :          0 : bool ScDocumentIterator::GetThis()
     157                 :            : {
     158                 :          0 :     bool bEnd = false;
     159                 :          0 :     bool bSuccess = false;
     160                 :            : 
     161 [ #  # ][ #  # ]:          0 :     while ( !bSuccess && !bEnd )
                 [ #  # ]
     162                 :            :     {
     163         [ #  # ]:          0 :         if ( nRow > MAXROW )
     164                 :          0 :             bSuccess = false;
     165                 :            :         else
     166                 :          0 :             bSuccess = GetThisCol();
     167                 :            : 
     168         [ #  # ]:          0 :         if ( !bSuccess )
     169                 :            :         {
     170                 :          0 :             ++nCol;
     171         [ #  # ]:          0 :             if (nCol > MAXCOL)
     172                 :            :             {
     173                 :          0 :                 nCol = 0;
     174                 :          0 :                 ++nTab;
     175         [ #  # ]:          0 :                 if (nTab > nEndTab)
     176                 :          0 :                     bEnd = true;
     177                 :            :             }
     178                 :          0 :             nRow = 0;
     179                 :          0 :             nColPos = 0;
     180                 :          0 :             nAttrPos = 0;
     181                 :            :         }
     182                 :            :     }
     183                 :            : 
     184                 :          0 :     return !bEnd;
     185                 :            : }
     186                 :            : 
     187                 :          0 : bool ScDocumentIterator::GetFirst()
     188                 :            : {
     189                 :          0 :     nCol = 0;
     190                 :          0 :     nTab = nStartTab;
     191                 :            : 
     192                 :          0 :     nRow = 0;
     193                 :          0 :     nColPos = 0;
     194                 :          0 :     nAttrPos = 0;
     195                 :            : 
     196                 :          0 :     return GetThis();
     197                 :            : }
     198                 :            : 
     199                 :          0 : bool ScDocumentIterator::GetNext()
     200                 :            : {
     201                 :          0 :     ++nRow;
     202                 :            : 
     203                 :          0 :     return GetThis();
     204                 :            : }
     205                 :            : 
     206                 :            : //------------------------------------------------------------------------
     207                 :            : 
     208                 :          0 : ScBaseCell* ScDocumentIterator::GetCell()
     209                 :            : {
     210                 :          0 :     return pCell;
     211                 :            : }
     212                 :            : 
     213                 :          0 : const ScPatternAttr* ScDocumentIterator::GetPattern()
     214                 :            : {
     215                 :          0 :     return pPattern;
     216                 :            : }
     217                 :            : 
     218                 :          0 : void ScDocumentIterator::GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
     219                 :            : {
     220                 :          0 :     rCol = nCol;
     221                 :          0 :     rRow = nRow;
     222                 :          0 :     rTab = nTab;
     223                 :          0 : }
     224                 :            : 
     225                 :            : 
     226                 :            : //------------------------------------------------------------------------
     227                 :            : //------------------------------------------------------------------------
     228                 :          0 : void lcl_IterGetNumberFormat( sal_uLong& nFormat, const ScAttrArray*& rpArr,
     229                 :            :         SCROW& nAttrEndRow, const ScAttrArray* pNewArr, SCROW nRow,
     230                 :            :         ScDocument* pDoc )
     231                 :            : {
     232 [ #  # ][ #  # ]:          0 :     if ( rpArr != pNewArr || nAttrEndRow < nRow )
     233                 :            :     {
     234                 :            :         SCSIZE nPos;
     235         [ #  # ]:          0 :         pNewArr->Search( nRow, nPos );  // nPos 0 gueltig wenn nicht gefunden
     236                 :          0 :         const ScPatternAttr* pPattern = pNewArr->pData[nPos].pPattern;
     237 [ #  # ][ #  # ]:          0 :         nFormat = pPattern->GetNumberFormat( pDoc->GetFormatTable() );
     238                 :          0 :         rpArr = pNewArr;
     239                 :          0 :         nAttrEndRow = pNewArr->pData[nPos].nRow;
     240                 :            :     }
     241                 :          0 : }
     242                 :            : 
     243                 :        126 : ScValueIterator::ScValueIterator( ScDocument* pDocument, const ScRange& rRange,
     244                 :            :             bool bSTotal, bool bTextZero ) :
     245                 :            :     pDoc( pDocument ),
     246                 :            :     nNumFmtIndex(0),
     247                 :        126 :     nStartCol( rRange.aStart.Col() ),
     248                 :        126 :     nStartRow( rRange.aStart.Row() ),
     249                 :        126 :     nStartTab( rRange.aStart.Tab() ),
     250                 :        126 :     nEndCol( rRange.aEnd.Col() ),
     251                 :        126 :     nEndRow( rRange.aEnd.Row() ),
     252                 :        126 :     nEndTab( rRange.aEnd.Tab() ),
     253                 :            :     nNumFmtType( NUMBERFORMAT_UNDEFINED ),
     254                 :            :     bNumValid( false ),
     255                 :            :     bSubTotal(bSTotal),
     256                 :            :     bNextValid( false ),
     257                 :        126 :     bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
     258                 :       1008 :     bTextAsZero( bTextZero )
     259                 :            : {
     260                 :        126 :     SCTAB nDocMaxTab = pDocument->GetTableCount() - 1;
     261                 :            : 
     262                 :        126 :     PutInOrder( nStartCol, nEndCol);
     263                 :        126 :     PutInOrder( nStartRow, nEndRow);
     264                 :        126 :     PutInOrder( nStartTab, nEndTab );
     265                 :            : 
     266         [ -  + ]:        126 :     if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
     267         [ -  + ]:        126 :     if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
     268         [ -  + ]:        126 :     if (!ValidRow(nStartRow)) nStartRow = MAXROW;
     269         [ -  + ]:        126 :     if (!ValidRow(nEndRow)) nEndRow = MAXROW;
     270 [ +  - ][ -  + ]:        126 :     if (!ValidTab(nStartTab) || nStartTab > nDocMaxTab) nStartTab = nDocMaxTab;
                 [ -  + ]
     271 [ +  - ][ -  + ]:        126 :     if (!ValidTab(nEndTab) || nEndTab > nDocMaxTab) nEndTab = nDocMaxTab;
                 [ -  + ]
     272                 :            : 
     273                 :        126 :     nCol = nStartCol;
     274                 :        126 :     nRow = nStartRow;
     275                 :        126 :     nTab = nStartTab;
     276                 :            : 
     277                 :        126 :     nColRow = 0;                    // wird bei GetFirst initialisiert
     278                 :            : 
     279                 :        126 :     nNumFormat = 0;                 // werden bei GetNumberFormat initialisiert
     280                 :        126 :     pAttrArray = 0;
     281                 :        126 :     nAttrEndRow = 0;
     282                 :        126 : }
     283                 :            : 
     284                 :       3592 : bool ScValueIterator::GetThis(double& rValue, sal_uInt16& rErr)
     285                 :            : {
     286                 :       3592 :     if (nTab >= pDoc->GetTableCount())
     287                 :            :     {
     288                 :            :         OSL_FAIL("try to access out of index, FIX IT");
     289                 :            :     }
     290                 :       3592 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
     291                 :       3642 :     for (;;)
     292                 :            :     {
     293         [ +  + ]:       3642 :         if ( nRow > nEndRow )
     294                 :            :         {
     295                 :        414 :             nRow = nStartRow;
     296         [ +  + ]:        300 :             do
     297                 :            :             {
     298                 :        426 :                 nCol++;
     299         [ +  + ]:        426 :                 if ( nCol > nEndCol )
     300                 :            :                 {
     301                 :        126 :                     nCol = nStartCol;
     302                 :        126 :                     nTab++;
     303         [ +  - ]:        126 :                     if ( nTab > nEndTab )
     304                 :            :                     {
     305                 :            :                         // rValue = 0.0;    //! do not change caller's value!
     306                 :        126 :                         rErr = 0;
     307                 :        126 :                         return false;               // Ende und Aus
     308                 :            :                     }
     309                 :            :                 }
     310                 :        300 :                 pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
     311                 :        300 :             } while ( pCol->maItems.empty() );
     312                 :        288 :             pCol->Search( nRow, nColRow );
     313                 :            :         }
     314                 :            : 
     315 [ +  + ][ -  + ]:       3516 :         while (( nColRow < pCol->maItems.size() ) && ( pCol->maItems[nColRow].nRow < nRow ))
                 [ -  + ]
     316                 :          0 :             nColRow++;
     317                 :            : 
     318 [ +  + ][ +  + ]:       3516 :         if ( nColRow < pCol->maItems.size() && pCol->maItems[nColRow].nRow <= nEndRow )
                 [ +  + ]
     319                 :            :         {
     320                 :       3486 :             nRow = pCol->maItems[nColRow].nRow + 1;
     321 [ +  - ][ +  - ]:       3486 :             if ( !bSubTotal || !pDoc->maTabs[nTab]->RowFiltered( nRow-1 ) )
                 [ +  + ]
     322                 :            :             {
     323                 :       3486 :                 ScBaseCell* pCell = pCol->maItems[nColRow].pCell;
     324                 :       3486 :                 ++nColRow;
     325   [ +  +  +  - ]:       3486 :                 switch (pCell->GetCellType())
     326                 :            :                 {
     327                 :            :                     case CELLTYPE_VALUE:
     328                 :            :                     {
     329                 :       3448 :                         bNumValid = false;
     330                 :       3448 :                         rValue = ((ScValueCell*)pCell)->GetValue();
     331                 :       3448 :                         rErr = 0;
     332                 :       3448 :                         --nRow;
     333         [ -  + ]:       3448 :                         if ( bCalcAsShown )
     334                 :            :                         {
     335                 :            :                             lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
     336                 :          0 :                                 nAttrEndRow, pCol->pAttrArray, nRow, pDoc );
     337                 :          0 :                             rValue = pDoc->RoundValueAsShown( rValue, nNumFormat );
     338                 :            :                         }
     339                 :            :                         //
     340                 :            :                         //  wenn in der selben Spalte gleich noch eine Value-Cell folgt, die
     341                 :            :                         //  auch noch im Block liegt, den Wert jetzt schon holen
     342                 :            :                         //
     343   [ +  +  +  +  :       9906 :                         if ( nColRow < pCol->maItems.size() &&
           +  + ][ +  + ]
                 [ +  + ]
     344                 :       3333 :                              pCol->maItems[nColRow].nRow <= nEndRow &&
     345                 :       3125 :                              pCol->maItems[nColRow].pCell->GetCellType() == CELLTYPE_VALUE &&
     346                 :       3122 :                              !bSubTotal )
     347                 :            :                         {
     348                 :       3117 :                             fNextValue = ((ScValueCell*)pCol->maItems[nColRow].pCell)->GetValue();
     349                 :       3117 :                             nNextRow = pCol->maItems[nColRow].nRow;
     350                 :       3117 :                             bNextValid = true;
     351         [ -  + ]:       3117 :                             if ( bCalcAsShown )
     352                 :            :                             {
     353                 :            :                                 lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
     354                 :          0 :                                     nAttrEndRow, pCol->pAttrArray, nNextRow, pDoc );
     355                 :          0 :                                 fNextValue = pDoc->RoundValueAsShown( fNextValue, nNumFormat );
     356                 :            :                             }
     357                 :            :                         }
     358                 :            : 
     359                 :       3448 :                         return true;                                    // gefunden
     360                 :            :                     }
     361                 :            : //                    break;
     362                 :            :                     case CELLTYPE_FORMULA:
     363                 :            :                     {
     364 [ +  + ][ +  - ]:         22 :                         if (!bSubTotal || !((ScFormulaCell*)pCell)->IsSubTotal())
         [ -  + ][ +  + ]
     365                 :            :                         {
     366         [ +  - ]:         18 :                             rErr = ((ScFormulaCell*)pCell)->GetErrCode();
     367 [ +  - ][ +  - ]:         18 :                             if ( rErr || ((ScFormulaCell*)pCell)->IsValue() )
         [ +  - ][ +  + ]
     368                 :            :                             {
     369         [ +  - ]:         18 :                                 rValue = ((ScFormulaCell*)pCell)->GetValue();
     370                 :         18 :                                 nRow--;
     371                 :         18 :                                 bNumValid = false;
     372                 :         18 :                                 return true;                            // gefunden
     373                 :            :                             }
     374         [ #  # ]:          0 :                             else if ( bTextAsZero )
     375                 :            :                             {
     376                 :          0 :                                 rValue = 0.0;
     377                 :          0 :                                 nRow--;
     378                 :          0 :                                 bNumValid = false;
     379                 :          0 :                                 return true;
     380                 :            :                             }
     381                 :            :                         }
     382                 :            :                     }
     383                 :          4 :                     break;
     384                 :            :                     case CELLTYPE_STRING :
     385                 :            :                     case CELLTYPE_EDIT :
     386                 :            :                     {
     387         [ -  + ]:         16 :                         if ( bTextAsZero )
     388                 :            :                         {
     389                 :          0 :                             rErr = 0;
     390                 :          0 :                             rValue = 0.0;
     391                 :          0 :                             nNumFmtType = NUMBERFORMAT_NUMBER;
     392                 :          0 :                             nNumFmtIndex = 0;
     393                 :          0 :                             bNumValid = true;
     394                 :          0 :                             --nRow;
     395                 :          0 :                             return true;
     396                 :            :                         }
     397                 :            :                     }
     398                 :         20 :                     break;
     399                 :            :                     default:
     400                 :            :                     {
     401                 :            :                         // added to avoid warnings
     402                 :            :                     }
     403                 :            :                 }
     404                 :            :             }
     405                 :            :         }
     406                 :            :         else
     407                 :         30 :             nRow = nEndRow + 1;         // naechste Spalte
     408                 :            :     }
     409                 :            : }
     410                 :            : 
     411                 :         81 : void ScValueIterator::GetCurNumFmtInfo( short& nType, sal_uLong& nIndex )
     412                 :            : {
     413 [ +  - ][ +  - ]:         81 :     if (!bNumValid && nTab < pDoc->GetTableCount())
                 [ +  - ]
     414                 :            :     {
     415                 :         81 :         const ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
     416                 :         81 :         nNumFmtIndex = pCol->GetNumberFormat( nRow );
     417         [ +  - ]:         81 :         if ( (nNumFmtIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
     418                 :            :         {
     419                 :            :             const ScBaseCell* pCell;
     420                 :         81 :             SCSIZE nIdx = nColRow - 1;
     421                 :            :             // there might be rearranged something, so be on the safe side
     422 [ +  - ][ +  - ]:         81 :             if ( nIdx < pCol->maItems.size() && pCol->maItems[nIdx].nRow == nRow )
                 [ +  - ]
     423                 :         81 :                 pCell = pCol->maItems[nIdx].pCell;
     424                 :            :             else
     425                 :            :             {
     426 [ #  # ][ #  # ]:          0 :                 if ( pCol->Search( nRow, nIdx ) )
     427                 :          0 :                     pCell = pCol->maItems[nIdx].pCell;
     428                 :            :                 else
     429                 :          0 :                     pCell = NULL;
     430                 :            :             }
     431 [ +  - ][ +  + ]:         81 :             if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
                 [ +  + ]
     432         [ +  - ]:          3 :                 ((const ScFormulaCell*)pCell)->GetFormatInfo( nNumFmtType, nNumFmtIndex );
     433                 :            :             else
     434 [ +  - ][ +  - ]:         81 :                 nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
     435                 :            :         }
     436                 :            :         else
     437                 :          0 :             nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
     438                 :         81 :         bNumValid = true;
     439                 :            :     }
     440                 :         81 :     nType = nNumFmtType;
     441                 :         81 :     nIndex = nNumFmtIndex;
     442                 :         81 : }
     443                 :            : 
     444                 :        126 : bool ScValueIterator::GetFirst(double& rValue, sal_uInt16& rErr)
     445                 :            : {
     446                 :        126 :     nCol = nStartCol;
     447                 :        126 :     nRow = nStartRow;
     448                 :        126 :     nTab = nStartTab;
     449                 :            : 
     450                 :        126 :     if (nTab >= pDoc->GetTableCount())
     451                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
     452                 :        126 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
     453                 :        126 :     pCol->Search( nRow, nColRow );
     454                 :            : 
     455                 :        126 :     nNumFormat = 0;                 // werden bei GetNumberFormat initialisiert
     456                 :        126 :     pAttrArray = 0;
     457                 :        126 :     nAttrEndRow = 0;
     458                 :            : 
     459                 :        126 :     return GetThis(rValue, rErr);
     460                 :            : }
     461                 :            : 
     462                 :            : // ============================================================================
     463                 :            : 
     464                 :         12 : ScDBQueryDataIterator::DataAccess::DataAccess(const ScDBQueryDataIterator* pParent) :
     465                 :         12 :     mpParent(pParent)
     466                 :            : {
     467                 :         12 : }
     468                 :            : 
     469                 :         12 : ScDBQueryDataIterator::DataAccess::~DataAccess()
     470                 :            : {
     471         [ -  + ]:         12 : }
     472                 :            : 
     473                 :        132 : SCROW ScDBQueryDataIterator::GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow)
     474                 :            : {
     475                 :        132 :     if (nTab >= rDoc.GetTableCount())
     476                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
     477                 :        132 :     ScColumn* pCol = &rDoc.maTabs[nTab]->aCol[nCol];
     478                 :        132 :     return pCol->maItems[nColRow].nRow;
     479                 :            : }
     480                 :            : 
     481                 :         72 : ScBaseCell* ScDBQueryDataIterator::GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow)
     482                 :            : {
     483                 :         72 :     if (nTab >= rDoc.GetTableCount())
     484                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
     485                 :         72 :     ScColumn* pCol = &rDoc.maTabs[nTab]->aCol[nCol];
     486                 :         72 :     return pCol->maItems[nColRow].pCell;
     487                 :            : }
     488                 :            : 
     489                 :          0 : ScAttrArray* ScDBQueryDataIterator::GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol)
     490                 :            : {
     491                 :          0 :     if (nTab >= rDoc.GetTableCount())
     492                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
     493                 :          0 :     ScColumn* pCol = &rDoc.maTabs[nTab]->aCol[nCol];
     494                 :          0 :     return pCol->pAttrArray;
     495                 :            : }
     496                 :            : 
     497                 :         72 : bool ScDBQueryDataIterator::IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell)
     498                 :            : {
     499                 :         72 :     if (nTab >= rDoc.GetTableCount())
     500                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
     501                 :         72 :     return rDoc.maTabs[nTab]->ValidQuery(nRow, rParam, pCell);
     502                 :            : }
     503                 :            : 
     504                 :         12 : SCSIZE ScDBQueryDataIterator::SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol)
     505                 :            : {
     506         [ +  - ]:         12 :     if (nTab >= rDoc.GetTableCount())
     507                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
     508                 :         12 :     ScColumn* pCol = &rDoc.maTabs[nTab]->aCol[nCol];
     509                 :            :     SCSIZE nColRow;
     510         [ +  - ]:         12 :     pCol->Search(nRow, nColRow);
     511                 :         12 :     return nColRow;
     512                 :            : }
     513                 :            : 
     514                 :            : // ----------------------------------------------------------------------------
     515                 :            : 
     516                 :         12 : ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc) :
     517                 :            :     DataAccess(pParent),
     518                 :            :     mpParam(pParam),
     519                 :            :     mpDoc(pDoc),
     520         [ +  - ]:         12 :     bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() )
     521                 :            : {
     522                 :         12 :     nCol = mpParam->mnField;
     523                 :         12 :     nRow = mpParam->nRow1;
     524                 :         12 :     nTab = mpParam->nTab;
     525                 :            : 
     526                 :         12 :     nColRow = 0;                    // wird bei GetFirst initialisiert
     527                 :            :     SCSIZE i;
     528         [ +  - ]:         12 :     SCSIZE nCount = mpParam->GetEntryCount();
     529 [ +  - ][ +  - ]:         24 :     for (i=0; (i<nCount) && (mpParam->GetEntry(i).bDoQuery); i++)
         [ +  + ][ +  + ]
     530                 :            :     {
     531         [ +  - ]:         12 :         ScQueryEntry& rEntry = mpParam->GetEntry(i);
     532         [ +  - ]:         12 :         ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
     533         [ +  - ]:         12 :         rItems.resize(1);
     534         [ +  - ]:         12 :         ScQueryEntry::Item& rItem = rItems.front();
     535                 :         12 :         sal_uInt32 nIndex = 0;
     536                 :            :         bool bNumber = mpDoc->GetFormatTable()->IsNumberFormat(
     537 [ +  - ][ +  - ]:         12 :             rItem.maString, nIndex, rItem.mfVal);
         [ +  - ][ +  - ]
     538         [ +  - ]:         12 :         rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
     539                 :            :     }
     540                 :         12 :     nNumFormat = 0;                 // werden bei GetNumberFormat initialisiert
     541                 :         12 :     pAttrArray = 0;
     542                 :         12 :     nAttrEndRow = 0;
     543                 :         12 : }
     544                 :            : 
     545                 :         12 : ScDBQueryDataIterator::DataAccessInternal::~DataAccessInternal()
     546                 :            : {
     547         [ -  + ]:         24 : }
     548                 :            : 
     549                 :         60 : bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue)
     550                 :            : {
     551                 :         60 :     SCCOLROW nFirstQueryField = mpParam->GetEntry(0).nField;
     552                 :         84 :     for ( ;; )
     553                 :            :     {
     554         [ +  + ]:         84 :         if (nRow > mpParam->nRow2)
     555                 :            :         {
     556                 :            :             // Bottom of the range reached.  Bail out.
     557                 :         12 :             rValue.mnError = 0;
     558                 :         12 :             return false;
     559                 :            :         }
     560                 :            : 
     561                 :         72 :         SCSIZE nCellCount = mpDoc->GetCellCount(nTab, nCol);
     562         [ -  + ]:         72 :         if (!nCellCount)
     563                 :            :             // No cells found in this column.  Bail out.
     564                 :          0 :             return false;
     565                 :            : 
     566                 :         72 :         SCROW nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
     567 [ +  - ][ +  + ]:        132 :         while ( (nColRow < nCellCount) && (nThisRow < nRow) )
                 [ +  + ]
     568                 :         60 :             nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, ++nColRow);
     569                 :            : 
     570 [ +  - ][ +  - ]:         72 :         if ( nColRow < nCellCount && nThisRow <= mpParam->nRow2 )
     571                 :            :         {
     572                 :         72 :             nRow = nThisRow;
     573                 :         72 :             ScBaseCell* pCell = NULL;
     574         [ +  - ]:         72 :             if (nCol == static_cast<SCCOL>(nFirstQueryField))
     575                 :         72 :                 pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
     576                 :            : 
     577 [ +  - ][ +  + ]:         72 :             if (ScDBQueryDataIterator::IsQueryValid(*mpDoc, *mpParam, nTab, nRow, pCell))
     578                 :            :             {
     579                 :            :                 // #i109812# get cell here if it wasn't done above
     580         [ -  + ]:         48 :                 if (nCol != static_cast<SCCOL>(nFirstQueryField))
     581                 :          0 :                     pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
     582                 :            : 
     583         [ +  - ]:         48 :                 switch (pCell ? pCell->GetCellType() : CELLTYPE_NONE)
           [ +  -  -  - ]
     584                 :            :                 {
     585                 :            :                     case CELLTYPE_VALUE:
     586                 :            :                         {
     587                 :         48 :                             rValue.mfValue = ((ScValueCell*)pCell)->GetValue();
     588                 :         48 :                             rValue.mbIsNumber = true;
     589         [ -  + ]:         48 :                             if ( bCalcAsShown )
     590                 :            :                             {
     591                 :            :                                 const ScAttrArray* pNewAttrArray =
     592                 :          0 :                                     ScDBQueryDataIterator::GetAttrArrayByCol(*mpDoc, nTab, nCol);
     593                 :            :                                 lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
     594                 :          0 :                                     nAttrEndRow, pNewAttrArray, nRow, mpDoc );
     595                 :          0 :                                 rValue.mfValue = mpDoc->RoundValueAsShown( rValue.mfValue, nNumFormat );
     596                 :            :                             }
     597                 :         48 :                             nNumFmtType = NUMBERFORMAT_NUMBER;
     598                 :         48 :                             nNumFmtIndex = 0;
     599                 :         48 :                             rValue.mnError = 0;
     600                 :         48 :                             return true;        // gefunden
     601                 :            :                         }
     602                 :            : //                        break;
     603                 :            :                     case CELLTYPE_FORMULA:
     604                 :            :                         {
     605 [ #  # ][ #  # ]:          0 :                             if (((ScFormulaCell*)pCell)->IsValue())
     606                 :            :                             {
     607         [ #  # ]:          0 :                                 rValue.mfValue = ((ScFormulaCell*)pCell)->GetValue();
     608                 :          0 :                                 rValue.mbIsNumber = true;
     609                 :            :                                 mpDoc->GetNumberFormatInfo( nNumFmtType,
     610                 :            :                                     nNumFmtIndex, ScAddress( nCol, nRow, nTab ),
     611         [ #  # ]:          0 :                                     pCell );
     612         [ #  # ]:          0 :                                 rValue.mnError = ((ScFormulaCell*)pCell)->GetErrCode();
     613                 :          0 :                                 return true;    // gefunden
     614                 :            :                             }
     615         [ #  # ]:          0 :                             else if(mpParam->mbSkipString)
     616                 :          0 :                                 nRow++;
     617                 :            :                             else
     618                 :            :                             {
     619         [ #  # ]:          0 :                                 rValue.maString = static_cast<ScFormulaCell*>(pCell)->GetString();
     620                 :          0 :                                 rValue.mfValue = 0.0;
     621         [ #  # ]:          0 :                                 rValue.mnError = static_cast<ScFormulaCell*>(pCell)->GetErrCode();
     622                 :          0 :                                 rValue.mbIsNumber = false;
     623                 :          0 :                                 return true;
     624                 :            :                             }
     625                 :            :                         }
     626                 :          0 :                         break;
     627                 :            :                     case CELLTYPE_STRING:
     628                 :            :                     case CELLTYPE_EDIT:
     629         [ #  # ]:          0 :                         if (mpParam->mbSkipString)
     630                 :          0 :                             ++nRow;
     631                 :            :                         else
     632                 :            :                         {
     633                 :          0 :                             rValue.maString = pCell->GetStringData();
     634                 :          0 :                             rValue.mfValue = 0.0;
     635                 :          0 :                             rValue.mnError = 0;
     636                 :          0 :                             rValue.mbIsNumber = false;
     637                 :          0 :                             return true;
     638                 :            :                         }
     639                 :          0 :                         break;
     640                 :            :                     default:
     641                 :          0 :                         nRow++;
     642                 :          0 :                         break;
     643                 :            :                 }
     644                 :            :             }
     645                 :            :             else
     646                 :         24 :                 nRow++;
     647                 :            :         }
     648                 :            :         else
     649                 :          0 :             nRow = mpParam->nRow2 + 1; // Naechste Spalte
     650                 :            :     }
     651                 :            : // statement unreachable
     652                 :            : }
     653                 :            : 
     654                 :         12 : bool ScDBQueryDataIterator::DataAccessInternal::getFirst(Value& rValue)
     655                 :            : {
     656         [ +  - ]:         12 :     if (mpParam->bHasHeader)
     657                 :         12 :         nRow++;
     658                 :            : 
     659                 :         12 :     nColRow = ScDBQueryDataIterator::SearchColEntryIndex(*mpDoc, nTab, nRow, nCol);
     660                 :         12 :     return getCurrent(rValue);
     661                 :            : }
     662                 :            : 
     663                 :         48 : bool ScDBQueryDataIterator::DataAccessInternal::getNext(Value& rValue)
     664                 :            : {
     665                 :         48 :     ++nRow;
     666                 :         48 :     return getCurrent(rValue);
     667                 :            : }
     668                 :            : 
     669                 :            : // ----------------------------------------------------------------------------
     670                 :            : 
     671                 :          0 : ScDBQueryDataIterator::DataAccessMatrix::DataAccessMatrix(const ScDBQueryDataIterator* pParent, ScDBQueryParamMatrix* pParam) :
     672                 :            :     DataAccess(pParent),
     673                 :          0 :     mpParam(pParam)
     674                 :            : {
     675                 :            :     SCSIZE nC, nR;
     676         [ #  # ]:          0 :     mpParam->mpMatrix->GetDimensions(nC, nR);
     677                 :          0 :     mnRows = static_cast<SCROW>(nR);
     678                 :          0 :     mnCols = static_cast<SCCOL>(nC);
     679                 :          0 : }
     680                 :            : 
     681                 :          0 : ScDBQueryDataIterator::DataAccessMatrix::~DataAccessMatrix()
     682                 :            : {
     683         [ #  # ]:          0 : }
     684                 :            : 
     685                 :          0 : bool ScDBQueryDataIterator::DataAccessMatrix::getCurrent(Value& rValue)
     686                 :            : {
     687                 :            :     // Starting from row == mnCurRow, get the first row that satisfies all the
     688                 :            :     // query parameters.
     689         [ #  # ]:          0 :     for ( ;mnCurRow < mnRows; ++mnCurRow)
     690                 :            :     {
     691                 :          0 :         const ScMatrix& rMat = *mpParam->mpMatrix;
     692         [ #  # ]:          0 :         if (rMat.IsEmpty(mpParam->mnField, mnCurRow))
     693                 :            :             // Don't take empty values into account.
     694                 :          0 :             continue;
     695                 :            : 
     696                 :          0 :         bool bIsStrVal = rMat.IsString(mpParam->mnField, mnCurRow);
     697 [ #  # ][ #  # ]:          0 :         if (bIsStrVal && mpParam->mbSkipString)
     698                 :          0 :             continue;
     699                 :            : 
     700         [ #  # ]:          0 :         if (isValidQuery(mnCurRow, rMat))
     701                 :            :         {
     702                 :          0 :             rValue.maString = rMat.GetString(mpParam->mnField, mnCurRow);
     703                 :          0 :             rValue.mfValue = rMat.GetDouble(mpParam->mnField, mnCurRow);
     704                 :          0 :             rValue.mbIsNumber = !bIsStrVal;
     705                 :          0 :             rValue.mnError = 0;
     706                 :          0 :             return true;
     707                 :            :         }
     708                 :            :     }
     709                 :          0 :     return false;
     710                 :            : }
     711                 :            : 
     712                 :          0 : bool ScDBQueryDataIterator::DataAccessMatrix::getFirst(Value& rValue)
     713                 :            : {
     714         [ #  # ]:          0 :     mnCurRow = mpParam->bHasHeader ? 1 : 0;
     715                 :          0 :     return getCurrent(rValue);
     716                 :            : }
     717                 :            : 
     718                 :          0 : bool ScDBQueryDataIterator::DataAccessMatrix::getNext(Value& rValue)
     719                 :            : {
     720                 :          0 :     ++mnCurRow;
     721                 :          0 :     return getCurrent(rValue);
     722                 :            : }
     723                 :            : 
     724                 :            : namespace {
     725                 :            : 
     726                 :          0 : bool isQueryByValue(const ScQueryEntry::Item& rItem, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
     727                 :            : {
     728         [ #  # ]:          0 :     if (rItem.meType == ScQueryEntry::ByString)
     729                 :          0 :         return false;
     730                 :            : 
     731         [ #  # ]:          0 :     if (!rMat.IsValueOrEmpty(nCol, nRow))
     732                 :          0 :         return false;
     733                 :            : 
     734                 :          0 :     return true;
     735                 :            : }
     736                 :            : 
     737                 :          0 : bool isQueryByString(const ScQueryEntry& rEntry, const ScQueryEntry::Item& rItem, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
     738                 :            : {
     739         [ #  # ]:          0 :     switch (rEntry.eOp)
     740                 :            :     {
     741                 :            :         case SC_EQUAL:
     742                 :            :         case SC_NOT_EQUAL:
     743                 :            :         case SC_CONTAINS:
     744                 :            :         case SC_DOES_NOT_CONTAIN:
     745                 :            :         case SC_BEGINS_WITH:
     746                 :            :         case SC_ENDS_WITH:
     747                 :            :         case SC_DOES_NOT_BEGIN_WITH:
     748                 :            :         case SC_DOES_NOT_END_WITH:
     749                 :          0 :             return true;
     750                 :            :         default:
     751                 :            :             ;
     752                 :            :     }
     753                 :            : 
     754 [ #  # ][ #  # ]:          0 :     if (rItem.meType == ScQueryEntry::ByString && rMat.IsString(nCol, nRow))
                 [ #  # ]
     755                 :          0 :         return true;
     756                 :            : 
     757                 :          0 :     return false;
     758                 :            : }
     759                 :            : 
     760                 :            : }
     761                 :            : 
     762                 :          0 : bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScMatrix& rMat) const
     763                 :            : {
     764         [ #  # ]:          0 :     SCSIZE nEntryCount = mpParam->GetEntryCount();
     765         [ #  # ]:          0 :     vector<bool> aResults;
     766         [ #  # ]:          0 :     aResults.reserve(nEntryCount);
     767                 :            : 
     768                 :            :     const CollatorWrapper& rCollator =
     769 [ #  # ][ #  # ]:          0 :         mpParam->bCaseSens ? *ScGlobal::GetCaseCollator() : *ScGlobal::GetCollator();
                 [ #  # ]
     770                 :            : 
     771         [ #  # ]:          0 :     for (SCSIZE i = 0; i < nEntryCount; ++i)
     772                 :            :     {
     773         [ #  # ]:          0 :         const ScQueryEntry& rEntry = mpParam->GetEntry(i);
     774         [ #  # ]:          0 :         const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
     775         [ #  # ]:          0 :         if (!rEntry.bDoQuery)
     776                 :          0 :             continue;
     777                 :            : 
     778         [ #  # ]:          0 :         switch (rEntry.eOp)
     779                 :            :         {
     780                 :            :             case SC_EQUAL:
     781                 :            :             case SC_LESS:
     782                 :            :             case SC_GREATER:
     783                 :            :             case SC_LESS_EQUAL:
     784                 :            :             case SC_GREATER_EQUAL:
     785                 :            :             case SC_NOT_EQUAL:
     786                 :          0 :                 break;
     787                 :            :             default:
     788                 :            :                 // Only the above operators are supported.
     789                 :          0 :                 continue;
     790                 :            :         }
     791                 :            : 
     792                 :          0 :         bool bValid = false;
     793                 :            : 
     794                 :          0 :         SCSIZE nField = static_cast<SCSIZE>(rEntry.nField);
     795 [ #  # ][ #  # ]:          0 :         if (isQueryByValue(rItem, rMat, nField, nRow))
     796                 :            :         {
     797                 :            :             // By value
     798         [ #  # ]:          0 :             double fMatVal = rMat.GetDouble(nField, nRow);
     799                 :          0 :             bool bEqual = approxEqual(fMatVal, rItem.mfVal);
     800   [ #  #  #  #  :          0 :             switch (rEntry.eOp)
                #  #  # ]
     801                 :            :             {
     802                 :            :                 case SC_EQUAL:
     803                 :          0 :                     bValid = bEqual;
     804                 :          0 :                 break;
     805                 :            :                 case SC_LESS:
     806 [ #  # ][ #  # ]:          0 :                     bValid = (fMatVal < rItem.mfVal) && !bEqual;
     807                 :          0 :                 break;
     808                 :            :                 case SC_GREATER:
     809 [ #  # ][ #  # ]:          0 :                     bValid = (fMatVal > rItem.mfVal) && !bEqual;
     810                 :          0 :                 break;
     811                 :            :                 case SC_LESS_EQUAL:
     812 [ #  # ][ #  # ]:          0 :                     bValid = (fMatVal < rItem.mfVal) || bEqual;
     813                 :          0 :                 break;
     814                 :            :                 case SC_GREATER_EQUAL:
     815 [ #  # ][ #  # ]:          0 :                     bValid = (fMatVal > rItem.mfVal) || bEqual;
     816                 :          0 :                 break;
     817                 :            :                 case SC_NOT_EQUAL:
     818                 :          0 :                     bValid = !bEqual;
     819                 :          0 :                 break;
     820                 :            :                 default:
     821                 :            :                     ;
     822                 :            :             }
     823                 :            :         }
     824 [ #  # ][ #  # ]:          0 :         else if (isQueryByString(rEntry, rItem, rMat, nField, nRow))
     825                 :            :         {
     826                 :            :             // By string
     827                 :            :             do
     828                 :            :             {
     829                 :            :                 // Equality check first.
     830                 :            : 
     831         [ #  # ]:          0 :                 OUString aMatStr = rMat.GetString(nField, nRow);
     832         [ #  # ]:          0 :                 lcl_uppercase(aMatStr);
     833         [ #  # ]:          0 :                 OUString aQueryStr = rEntry.GetQueryItem().maString;
     834         [ #  # ]:          0 :                 lcl_uppercase(aQueryStr);
     835                 :          0 :                 bool bDone = false;
     836      [ #  #  # ]:          0 :                 switch (rEntry.eOp)
     837                 :            :                 {
     838                 :            :                     case SC_EQUAL:
     839                 :          0 :                         bValid = aMatStr.equals(aQueryStr);
     840                 :          0 :                         bDone = true;
     841                 :          0 :                     break;
     842                 :            :                     case SC_NOT_EQUAL:
     843                 :          0 :                         bValid = !aMatStr.equals(aQueryStr);
     844                 :          0 :                         bDone = true;
     845                 :          0 :                     break;
     846                 :            :                     default:
     847                 :            :                         ;
     848                 :            :                 }
     849                 :            : 
     850         [ #  # ]:          0 :                 if (bDone)
     851                 :            :                     break;
     852                 :            : 
     853                 :            :                 // Unequality check using collator.
     854                 :            : 
     855         [ #  # ]:          0 :                 sal_Int32 nCompare = rCollator.compareString(aMatStr, aQueryStr);
     856   [ #  #  #  #  :          0 :                 switch (rEntry.eOp)
                      # ]
     857                 :            :                 {
     858                 :            :                     case SC_LESS :
     859                 :          0 :                         bValid = (nCompare < 0);
     860                 :          0 :                     break;
     861                 :            :                     case SC_GREATER :
     862                 :          0 :                         bValid = (nCompare > 0);
     863                 :          0 :                     break;
     864                 :            :                     case SC_LESS_EQUAL :
     865                 :          0 :                         bValid = (nCompare <= 0);
     866                 :          0 :                     break;
     867                 :            :                     case SC_GREATER_EQUAL :
     868                 :          0 :                         bValid = (nCompare >= 0);
     869                 :          0 :                     break;
     870                 :            :                     default:
     871                 :            :                         ;
     872 [ #  # ][ #  # ]:          0 :                 }
     873                 :            :             }
     874                 :            :             while (false);
     875                 :            :         }
     876                 :            : 
     877         [ #  # ]:          0 :         if (aResults.empty())
     878                 :            :             // First query entry.
     879         [ #  # ]:          0 :             aResults.push_back(bValid);
     880         [ #  # ]:          0 :         else if (rEntry.eConnect == SC_AND)
     881                 :            :         {
     882                 :            :             // For AND op, tuck the result into the last result value.
     883                 :          0 :             size_t n = aResults.size();
     884 [ #  # ][ #  # ]:          0 :             aResults[n-1] = aResults[n-1] && bValid;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     885                 :            :         }
     886                 :            :         else
     887                 :            :             // For OR op, store its own result.
     888         [ #  # ]:          0 :             aResults.push_back(bValid);
     889                 :            :     }
     890                 :            : 
     891                 :            :     // Row is valid as long as there is at least one result being true.
     892                 :          0 :     vector<bool>::const_iterator itr = aResults.begin(), itrEnd = aResults.end();
     893         [ #  # ]:          0 :     for (; itr != itrEnd; ++itr)
     894         [ #  # ]:          0 :         if (*itr)
     895                 :          0 :             return true;
     896                 :            : 
     897                 :          0 :     return false;
     898                 :            : }
     899                 :            : 
     900                 :            : // ----------------------------------------------------------------------------
     901                 :            : 
     902                 :         12 : ScDBQueryDataIterator::Value::Value() :
     903                 :         12 :     mnError(0), mbIsNumber(true)
     904                 :            : {
     905                 :         12 :     ::rtl::math::setNan(&mfValue);
     906                 :         12 : }
     907                 :            : 
     908                 :            : // ----------------------------------------------------------------------------
     909                 :            : 
     910                 :         12 : ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam) :
     911                 :         12 :     mpParam (pParam)
     912                 :            : {
     913      [ +  -  - ]:         12 :     switch (mpParam->GetType())
                 [ +  - ]
     914                 :            :     {
     915                 :            :         case ScDBQueryParamBase::INTERNAL:
     916                 :            :         {
     917                 :         12 :             ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pParam);
     918 [ +  - ][ +  - ]:         12 :             mpData.reset(new DataAccessInternal(this, p, pDocument));
     919                 :            :         }
     920                 :         12 :         break;
     921                 :            :         case ScDBQueryParamBase::MATRIX:
     922                 :            :         {
     923                 :          0 :             ScDBQueryParamMatrix* p = static_cast<ScDBQueryParamMatrix*>(pParam);
     924 [ #  # ][ #  # ]:          0 :             mpData.reset(new DataAccessMatrix(this, p));
     925                 :            :         }
     926                 :            :     }
     927                 :         12 : }
     928                 :            : 
     929                 :         12 : bool ScDBQueryDataIterator::GetFirst(Value& rValue)
     930                 :            : {
     931                 :         12 :     return mpData->getFirst(rValue);
     932                 :            : }
     933                 :            : 
     934                 :         48 : bool ScDBQueryDataIterator::GetNext(Value& rValue)
     935                 :            : {
     936                 :         48 :     return mpData->getNext(rValue);
     937                 :            : }
     938                 :            : 
     939                 :            : // ============================================================================
     940                 :            : 
     941                 :       1320 : ScCellIterator::ScCellIterator( ScDocument* pDocument,
     942                 :            :                                 SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
     943                 :            :                                 SCCOL nECol, SCROW nERow, SCTAB nETab, bool bSTotal ) :
     944                 :            :     pDoc( pDocument ),
     945                 :            :     nStartCol( nSCol),
     946                 :            :     nStartRow( nSRow),
     947                 :            :     nStartTab( nSTab ),
     948                 :            :     nEndCol( nECol ),
     949                 :            :     nEndRow( nERow),
     950                 :            :     nEndTab( nETab ),
     951                 :       1320 :     bSubTotal(bSTotal)
     952                 :            : 
     953                 :            : {
     954                 :       1320 :     SCTAB nDocMaxTab = pDocument->GetTableCount() - 1;
     955                 :            : 
     956                 :       1320 :     PutInOrder( nStartCol, nEndCol);
     957                 :       1320 :     PutInOrder( nStartRow, nEndRow);
     958                 :       1320 :     PutInOrder( nStartTab, nEndTab );
     959                 :            : 
     960         [ -  + ]:       1320 :     if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
     961         [ -  + ]:       1320 :     if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
     962         [ -  + ]:       1320 :     if (!ValidRow(nStartRow)) nStartRow = MAXROW;
     963         [ -  + ]:       1320 :     if (!ValidRow(nEndRow)) nEndRow = MAXROW;
     964 [ +  - ][ -  + ]:       1320 :     if (!ValidTab(nStartTab) || nStartTab > nDocMaxTab) nStartTab = nDocMaxTab;
                 [ -  + ]
     965 [ +  - ][ -  + ]:       1320 :     if (!ValidTab(nEndTab) || nEndTab > nDocMaxTab) nEndTab = nDocMaxTab;
                 [ -  + ]
     966                 :            : 
     967 [ +  + ][ -  + ]:       1320 :     while (nEndTab>0 && !pDoc->maTabs[nEndTab])
                 [ -  + ]
     968                 :          0 :         --nEndTab;                                      // nur benutzte Tabellen
     969         [ -  + ]:       1320 :     if (nStartTab>nEndTab)
     970                 :          0 :         nStartTab = nEndTab;
     971                 :            : 
     972                 :       1320 :     nCol = nStartCol;
     973                 :       1320 :     nRow = nStartRow;
     974                 :       1320 :     nTab = nStartTab;
     975                 :       1320 :     nColRow = 0;                    // wird bei GetFirst initialisiert
     976                 :            : 
     977         [ -  + ]:       1320 :     if (!pDoc->maTabs[nTab])
     978                 :            :     {
     979                 :            :         OSL_FAIL("Tabelle nicht gefunden");
     980                 :          0 :         nStartCol = nCol = MAXCOL+1;
     981                 :          0 :         nStartRow = nRow = MAXROW+1;
     982                 :          0 :         nStartTab = nTab = MAXTAB+1;    // -> Abbruch bei GetFirst
     983                 :            :     }
     984                 :       1320 : }
     985                 :            : 
     986                 :        131 : ScCellIterator::ScCellIterator
     987                 :            :     ( ScDocument* pDocument, const ScRange& rRange, bool bSTotal ) :
     988                 :            :     pDoc( pDocument ),
     989                 :        131 :     nStartCol( rRange.aStart.Col() ),
     990                 :        131 :     nStartRow( rRange.aStart.Row() ),
     991                 :        131 :     nStartTab( rRange.aStart.Tab() ),
     992                 :        131 :     nEndCol( rRange.aEnd.Col() ),
     993                 :        131 :     nEndRow( rRange.aEnd.Row() ),
     994                 :        131 :     nEndTab( rRange.aEnd.Tab() ),
     995                 :        917 :     bSubTotal(bSTotal)
     996                 :            : 
     997                 :            : {
     998                 :        131 :     PutInOrder( nStartCol, nEndCol);
     999                 :        131 :     PutInOrder( nStartRow, nEndRow);
    1000                 :        131 :     PutInOrder( nStartTab, nEndTab );
    1001                 :            : 
    1002         [ -  + ]:        131 :     if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
    1003         [ -  + ]:        131 :     if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
    1004         [ -  + ]:        131 :     if (!ValidRow(nStartRow)) nStartRow = MAXROW;
    1005         [ -  + ]:        131 :     if (!ValidRow(nEndRow)) nEndRow = MAXROW;
    1006         [ +  + ]:        131 :     if (!ValidTab(nStartTab)) nStartTab = pDoc->GetTableCount()-1;
    1007         [ +  + ]:        131 :     if (!ValidTab(nEndTab)) nEndTab = pDoc->GetTableCount()-1;
    1008                 :            : 
    1009 [ +  + ][ -  + ]:        131 :     while (nEndTab>0 && !pDoc->maTabs[nEndTab])
                 [ -  + ]
    1010                 :          0 :         --nEndTab;                                      // nur benutzte Tabellen
    1011         [ -  + ]:        131 :     if (nStartTab>nEndTab)
    1012                 :          0 :         nStartTab = nEndTab;
    1013                 :            : 
    1014                 :        131 :     nCol = nStartCol;
    1015                 :        131 :     nRow = nStartRow;
    1016                 :        131 :     nTab = nStartTab;
    1017                 :        131 :     nColRow = 0;                    // wird bei GetFirst initialisiert
    1018                 :            : 
    1019         [ -  + ]:        131 :     if (!pDoc->maTabs[nTab])
    1020                 :            :     {
    1021                 :            :         OSL_FAIL("Tabelle nicht gefunden");
    1022                 :          0 :         nStartCol = nCol = MAXCOL+1;
    1023                 :          0 :         nStartRow = nRow = MAXROW+1;
    1024                 :          0 :         nStartTab = nTab = MAXTAB+1;    // -> Abbruch bei GetFirst
    1025                 :            :     }
    1026                 :        131 : }
    1027                 :            : 
    1028                 :      12238 : ScBaseCell* ScCellIterator::GetThis()
    1029                 :            : {
    1030                 :            : 
    1031                 :      12238 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1032                 :      14524 :     for ( ;; )
    1033                 :            :     {
    1034         [ +  + ]:      14524 :         if ( nRow > nEndRow )
    1035                 :            :         {
    1036                 :       2574 :             nRow = nStartRow;
    1037         [ +  + ]:      44274 :             do
    1038                 :            :             {
    1039                 :      45725 :                 nCol++;
    1040         [ +  + ]:      45725 :                 if ( nCol > nEndCol )
    1041                 :            :                 {
    1042                 :       1451 :                     nCol = nStartCol;
    1043                 :       1451 :                     nTab++;
    1044         [ +  - ]:       1451 :                     if ( nTab > nEndTab )
    1045                 :       1451 :                         return NULL;                // Ende und Aus
    1046                 :            :                 }
    1047                 :      44274 :                 pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1048                 :      44274 :             } while ( pCol->maItems.empty() );
    1049                 :       1123 :             pCol->Search( nRow, nColRow );
    1050                 :            :         }
    1051                 :            : 
    1052 [ +  + ][ +  + ]:      23572 :         while ( (nColRow < pCol->maItems.size()) && (pCol->maItems[nColRow].nRow < nRow) )
                 [ +  + ]
    1053                 :      10499 :             nColRow++;
    1054                 :            : 
    1055 [ +  + ][ +  + ]:      13073 :         if ( nColRow < pCol->maItems.size() && pCol->maItems[nColRow].nRow <= nEndRow )
                 [ +  + ]
    1056                 :            :         {
    1057                 :      10787 :             nRow = pCol->maItems[nColRow].nRow;
    1058 [ #  # ][ +  - ]:      10787 :             if ( !bSubTotal || !pDoc->maTabs[nTab]->RowFiltered( nRow ) )
                 [ -  + ]
    1059                 :            :             {
    1060                 :      10787 :                 ScBaseCell* pCell = pCol->maItems[nColRow].pCell;
    1061                 :            : 
    1062   [ #  #  #  # ]:      10787 :                 if ( bSubTotal && pCell->GetCellType() == CELLTYPE_FORMULA
         [ -  + ][ -  + ]
    1063         [ #  # ]:          0 :                                 && ((ScFormulaCell*)pCell)->IsSubTotal() )
    1064                 :          0 :                     nRow++;             // Sub-Total-Zeilen nicht
    1065                 :            :                 else
    1066                 :      10787 :                     return pCell;       // gefunden
    1067                 :            :             }
    1068                 :            :             else
    1069                 :          0 :                 nRow++;
    1070                 :            :         }
    1071                 :            :         else
    1072                 :       2286 :             nRow = nEndRow + 1; // Naechste Spalte
    1073                 :            :     }
    1074                 :            : }
    1075                 :            : 
    1076                 :       1451 : ScBaseCell* ScCellIterator::GetFirst()
    1077                 :            : {
    1078         [ -  + ]:       1451 :     if ( !ValidTab(nTab) )
    1079                 :          0 :         return NULL;
    1080                 :       1451 :     nCol = nStartCol;
    1081                 :       1451 :     nRow = nStartRow;
    1082                 :       1451 :     nTab = nStartTab;
    1083                 :       1451 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1084                 :       1451 :     pCol->Search( nRow, nColRow );
    1085                 :       1451 :     return GetThis();
    1086                 :            : }
    1087                 :            : 
    1088                 :      10787 : ScBaseCell* ScCellIterator::GetNext()
    1089                 :            : {
    1090                 :      10787 :     ++nRow;
    1091                 :      10787 :     return GetThis();
    1092                 :            : }
    1093                 :            : 
    1094                 :            : //-------------------------------------------------------------------------------
    1095                 :            : 
    1096                 :        225 : ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
    1097                 :            :              const ScQueryParam& rParam, bool bMod ) :
    1098         [ +  - ]:        225 :     mpParam(new ScQueryParam(rParam)),
    1099                 :            :     pDoc( pDocument ),
    1100                 :            :     nTab( nTable),
    1101                 :            :     nStopOnMismatch( nStopOnMismatchDisabled ),
    1102                 :            :     nTestEqualCondition( nTestEqualConditionDisabled ),
    1103                 :            :     bAdvanceQuery( false ),
    1104                 :        450 :     bIgnoreMismatchOnLeadingStrings( false )
    1105                 :            : {
    1106                 :        225 :     nCol = mpParam->nCol1;
    1107                 :        225 :     nRow = mpParam->nRow1;
    1108                 :        225 :     nColRow = 0;                    // wird bei GetFirst initialisiert
    1109                 :            :     SCSIZE i;
    1110         [ +  + ]:        225 :     if (bMod)                               // sonst schon eingetragen
    1111                 :            :     {
    1112         [ +  - ]:         12 :         SCSIZE nCount = mpParam->GetEntryCount();
    1113 [ +  - ][ +  - ]:         36 :         for (i = 0; (i < nCount) && (mpParam->GetEntry(i).bDoQuery); ++i)
         [ +  + ][ +  + ]
    1114                 :            :         {
    1115         [ +  - ]:         24 :             ScQueryEntry& rEntry = mpParam->GetEntry(i);
    1116         [ +  - ]:         24 :             ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    1117                 :         24 :             sal_uInt32 nIndex = 0;
    1118                 :            :             bool bNumber = pDoc->GetFormatTable()->IsNumberFormat(
    1119 [ +  - ][ +  - ]:         24 :                 rItem.maString, nIndex, rItem.mfVal);
         [ +  - ][ +  - ]
    1120         [ +  - ]:         24 :             rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
    1121                 :            :         }
    1122                 :            :     }
    1123                 :        225 :     nNumFormat = 0;                 // werden bei GetNumberFormat initialisiert
    1124                 :        225 :     pAttrArray = 0;
    1125                 :        225 :     nAttrEndRow = 0;
    1126                 :        225 : }
    1127                 :            : 
    1128                 :        585 : ScBaseCell* ScQueryCellIterator::GetThis()
    1129                 :            : {
    1130                 :        585 :     if (nTab >= pDoc->GetTableCount())
    1131                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
    1132                 :        585 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1133                 :        585 :     const ScQueryEntry& rEntry = mpParam->GetEntry(0);
    1134                 :        585 :     const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    1135                 :            : 
    1136                 :        585 :     SCCOLROW nFirstQueryField = rEntry.nField;
    1137                 :            :     bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings &&
    1138 [ +  + ][ +  + ]:        585 :         rItem.meType != ScQueryEntry::ByString;
    1139                 :            :     bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
    1140                 :        276 :         !mpParam->bHasHeader && rItem.meType == ScQueryEntry::ByString &&
    1141                 :        168 :         ((mpParam->bByRow && nRow == mpParam->nRow1) ||
    1142   [ +  +  +  - ]:       1029 :          (!mpParam->bByRow && nCol == mpParam->nCol1));
           [ +  +  +  -  
           +  + ][ -  + ]
                 [ #  # ]
    1143                 :       1173 :     for ( ;; )
    1144                 :            :     {
    1145         [ +  + ]:       1173 :         if ( nRow > mpParam->nRow2 )
    1146                 :            :         {
    1147                 :        120 :             nRow = mpParam->nRow1;
    1148 [ +  - ][ +  + ]:        120 :             if (mpParam->bHasHeader && mpParam->bByRow)
                 [ +  + ]
    1149                 :         12 :                 nRow++;
    1150         [ #  # ]:          0 :             do
    1151                 :            :             {
    1152         [ +  - ]:        120 :                 if ( ++nCol > mpParam->nCol2 )
    1153                 :        120 :                     return NULL;                // Ende und Aus
    1154         [ #  # ]:          0 :                 if ( bAdvanceQuery )
    1155                 :            :                 {
    1156                 :          0 :                     AdvanceQueryParamEntryField();
    1157                 :          0 :                     nFirstQueryField = rEntry.nField;
    1158                 :            :                 }
    1159                 :          0 :                 pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1160                 :          0 :             } while ( pCol->maItems.empty() );
    1161                 :          0 :             pCol->Search( nRow, nColRow );
    1162                 :            :             bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
    1163                 :          0 :                 !mpParam->bHasHeader && rItem.meType == ScQueryEntry::ByString &&
    1164 [ #  # ][ #  # ]:          0 :                 mpParam->bByRow;
           [ #  #  #  # ]
    1165                 :            :         }
    1166                 :            : 
    1167 [ +  - ][ +  + ]:       1881 :         while ( nColRow < pCol->maItems.size() && pCol->maItems[nColRow].nRow < nRow )
                 [ +  + ]
    1168                 :        828 :             nColRow++;
    1169                 :            : 
    1170   [ +  -  +  + ]:       2106 :         if ( nColRow < pCol->maItems.size() &&
                 [ +  + ]
    1171                 :       1053 :                 (nRow = pCol->maItems[nColRow].nRow) <= mpParam->nRow2 )
    1172                 :            :         {
    1173                 :        987 :             ScBaseCell* pCell = pCol->maItems[nColRow].pCell;
    1174         [ -  + ]:        987 :             if ( pCell->GetCellType() == CELLTYPE_NOTE )
    1175                 :          0 :                 ++nRow;
    1176 [ +  + ][ +  + ]:        987 :             else if (bAllStringIgnore && pCell->HasStringData())
                 [ +  + ]
    1177                 :         81 :                 ++nRow;
    1178                 :            :             else
    1179                 :            :             {
    1180                 :            :                 bool bTestEqualCondition;
    1181 [ +  - ][ +  + ]:        906 :                 if ( (pDoc->maTabs[nTab])->ValidQuery( nRow, *mpParam,
    1182                 :            :                         (nCol == static_cast<SCCOL>(nFirstQueryField) ? pCell : NULL),
    1183 [ +  + ][ +  - ]:        906 :                         (nTestEqualCondition ? &bTestEqualCondition : NULL) ) )
    1184                 :            :                 {
    1185 [ +  + ][ -  + ]:        360 :                     if ( nTestEqualCondition && bTestEqualCondition )
    1186                 :          0 :                         nTestEqualCondition |= nTestEqualConditionMatched;
    1187                 :        360 :                     return pCell;     // found
    1188                 :            :                 }
    1189         [ +  + ]:        546 :                 else if ( nStopOnMismatch )
    1190                 :            :                 {
    1191                 :            :                     // Yes, even a mismatch may have a fulfilled equal
    1192                 :            :                     // condition if regular expressions were involved and
    1193                 :            :                     // SC_LESS_EQUAL or SC_GREATER_EQUAL were queried.
    1194 [ +  - ][ -  + ]:        105 :                     if ( nTestEqualCondition && bTestEqualCondition )
    1195                 :            :                     {
    1196                 :          0 :                         nTestEqualCondition |= nTestEqualConditionMatched;
    1197                 :          0 :                         nStopOnMismatch |= nStopOnMismatchOccurred;
    1198                 :          0 :                         return NULL;
    1199                 :            :                     }
    1200                 :            :                     bool bStop;
    1201         [ -  + ]:        105 :                     if (bFirstStringIgnore)
    1202                 :            :                     {
    1203 [ #  # ][ #  # ]:          0 :                         if (pCell->HasStringData())
    1204                 :            :                         {
    1205                 :          0 :                             ++nRow;
    1206                 :          0 :                             bStop = false;
    1207                 :            :                         }
    1208                 :            :                         else
    1209                 :          0 :                             bStop = true;
    1210                 :            :                     }
    1211                 :            :                     else
    1212                 :        105 :                         bStop = true;
    1213         [ +  - ]:        105 :                     if (bStop)
    1214                 :            :                     {
    1215                 :        105 :                         nStopOnMismatch |= nStopOnMismatchOccurred;
    1216                 :        105 :                         return NULL;
    1217                 :            :                     }
    1218                 :            :                 }
    1219                 :            :                 else
    1220                 :        906 :                     nRow++;
    1221                 :            :             }
    1222                 :            :         }
    1223                 :            :         else
    1224                 :         66 :             nRow = mpParam->nRow2 + 1; // Naechste Spalte
    1225                 :        588 :         bFirstStringIgnore = false;
    1226                 :            :     }
    1227                 :            : }
    1228                 :            : 
    1229                 :         81 : ScBaseCell* ScQueryCellIterator::GetFirst()
    1230                 :            : {
    1231                 :         81 :     if (nTab >= pDoc->GetTableCount())
    1232                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
    1233                 :         81 :     nCol = mpParam->nCol1;
    1234                 :         81 :     nRow = mpParam->nRow1;
    1235         [ +  + ]:         81 :     if (mpParam->bHasHeader)
    1236                 :         12 :         nRow++;
    1237                 :         81 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1238                 :         81 :     pCol->Search( nRow, nColRow );
    1239                 :         81 :     return GetThis();
    1240                 :            : }
    1241                 :            : 
    1242                 :        360 : ScBaseCell* ScQueryCellIterator::GetNext()
    1243                 :            : {
    1244                 :        360 :     ++nRow;
    1245         [ +  + ]:        360 :     if ( nStopOnMismatch )
    1246                 :        132 :         nStopOnMismatch = nStopOnMismatchEnabled;
    1247         [ +  + ]:        360 :     if ( nTestEqualCondition )
    1248                 :        132 :         nTestEqualCondition = nTestEqualConditionEnabled;
    1249                 :        360 :     return GetThis();
    1250                 :            : }
    1251                 :            : 
    1252                 :          0 : void ScQueryCellIterator::AdvanceQueryParamEntryField()
    1253                 :            : {
    1254                 :          0 :     SCSIZE nEntries = mpParam->GetEntryCount();
    1255         [ #  # ]:          0 :     for ( SCSIZE j = 0; j < nEntries; j++  )
    1256                 :            :     {
    1257                 :          0 :         ScQueryEntry& rEntry = mpParam->GetEntry( j );
    1258         [ #  # ]:          0 :         if ( rEntry.bDoQuery )
    1259                 :            :         {
    1260         [ #  # ]:          0 :             if ( rEntry.nField < MAXCOL )
    1261                 :          0 :                 rEntry.nField++;
    1262                 :            :             else
    1263                 :            :             {
    1264                 :            :                 OSL_FAIL( "AdvanceQueryParamEntryField: ++rEntry.nField > MAXCOL" );
    1265                 :            :             }
    1266                 :            :         }
    1267                 :            :         else
    1268                 :          0 :             break;  // for
    1269                 :            :     }
    1270                 :          0 : }
    1271                 :            : 
    1272                 :            : 
    1273                 :        144 : bool ScQueryCellIterator::FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
    1274                 :            :         SCROW& nFoundRow, bool bSearchForEqualAfterMismatch,
    1275                 :            :         bool bIgnoreMismatchOnLeadingStringsP )
    1276                 :            : {
    1277                 :        144 :     nFoundCol = MAXCOL+1;
    1278                 :        144 :     nFoundRow = MAXROW+1;
    1279                 :        144 :     SetStopOnMismatch( true );      // assume sorted keys
    1280                 :        144 :     SetTestEqualCondition( true );
    1281                 :        144 :     bIgnoreMismatchOnLeadingStrings = bIgnoreMismatchOnLeadingStringsP;
    1282 [ #  # ][ -  + ]:        144 :     bool bRegExp = mpParam->bRegExp && mpParam->GetEntry(0).GetQueryItem().meType == ScQueryEntry::ByString;
    1283                 :        288 :     bool bBinary = !bRegExp && mpParam->bByRow && (mpParam->GetEntry(0).eOp ==
    1284   [ +  -  +  -  :        432 :             SC_LESS_EQUAL || mpParam->GetEntry(0).eOp == SC_GREATER_EQUAL);
           +  + ][ +  - ]
    1285 [ +  - ][ +  - ]:        144 :     if (bBinary ? (BinarySearch() ? GetThis() : 0) : GetFirst())
         [ +  + ][ +  + ]
    1286                 :            :     {
    1287                 :            :         // First equal entry or last smaller than (greater than) entry.
    1288                 :            :         SCSIZE nColRowSave;
    1289                 :        129 :         ScBaseCell* pNext = 0;
    1290 [ +  + ][ +  + ]:        132 :         do
                 [ +  - ]
    1291                 :            :         {
    1292                 :        132 :             nFoundCol = GetCol();
    1293                 :        132 :             nFoundRow = GetRow();
    1294                 :        132 :             nColRowSave = nColRow;
    1295                 :        132 :         } while ( !IsEqualConditionFulfilled() && (pNext = GetNext()) != NULL );
    1296                 :            :         // There may be no pNext but equal condition fulfilled if regular
    1297                 :            :         // expressions are involved. Keep the found entry and proceed.
    1298 [ +  - ][ +  - ]:        129 :         if (!pNext && !IsEqualConditionFulfilled())
                 [ +  - ]
    1299                 :            :         {
    1300                 :            :             // Step back to last in range and adjust position markers for
    1301                 :            :             // GetNumberFormat() or similar.
    1302                 :        129 :             nCol = nFoundCol;
    1303                 :        129 :             nRow = nFoundRow;
    1304                 :        129 :             nColRow = nColRowSave;
    1305                 :            :         }
    1306                 :            :     }
    1307         [ -  + ]:        144 :     if ( IsEqualConditionFulfilled() )
    1308                 :            :     {
    1309                 :            :         // Position on last equal entry.
    1310                 :          0 :         SCSIZE nEntries = mpParam->GetEntryCount();
    1311         [ #  # ]:          0 :         for ( SCSIZE j = 0; j < nEntries; j++  )
    1312                 :            :         {
    1313                 :          0 :             ScQueryEntry& rEntry = mpParam->GetEntry( j );
    1314         [ #  # ]:          0 :             if ( rEntry.bDoQuery )
    1315                 :            :             {
    1316         [ #  # ]:          0 :                 switch ( rEntry.eOp )
    1317                 :            :                 {
    1318                 :            :                     case SC_LESS_EQUAL :
    1319                 :            :                     case SC_GREATER_EQUAL :
    1320                 :          0 :                         rEntry.eOp = SC_EQUAL;
    1321                 :          0 :                     break;
    1322                 :            :                     default:
    1323                 :            :                     {
    1324                 :            :                         // added to avoid warnings
    1325                 :            :                     }
    1326                 :            :                 }
    1327                 :            :             }
    1328                 :            :             else
    1329                 :          0 :                 break;  // for
    1330                 :            :         }
    1331                 :            :         SCSIZE nColRowSave;
    1332                 :          0 :         bIgnoreMismatchOnLeadingStrings = false;
    1333                 :          0 :         SetTestEqualCondition( false );
    1334         [ #  # ]:          0 :         do
    1335                 :            :         {
    1336                 :          0 :             nFoundCol = GetCol();
    1337                 :          0 :             nFoundRow = GetRow();
    1338                 :          0 :             nColRowSave = nColRow;
    1339                 :          0 :         } while (GetNext());
    1340                 :            :         // Step back conditions same as above
    1341                 :          0 :         nCol = nFoundCol;
    1342                 :          0 :         nRow = nFoundRow;
    1343                 :          0 :         nColRow = nColRowSave;
    1344                 :          0 :         return true;
    1345                 :            :     }
    1346         [ +  - ]:        144 :     if ( (bSearchForEqualAfterMismatch || mpParam->bRegExp) &&
           [ -  +  #  # ]
                 [ -  + ]
    1347                 :          0 :             StoppedOnMismatch() )
    1348                 :            :     {
    1349                 :            :         // Assume found entry to be the last value less than respectively
    1350                 :            :         // greater than the query. But keep on searching for an equal match.
    1351                 :          0 :         SCSIZE nEntries = mpParam->GetEntryCount();
    1352         [ #  # ]:          0 :         for ( SCSIZE j = 0; j < nEntries; j++  )
    1353                 :            :         {
    1354                 :          0 :             ScQueryEntry& rEntry = mpParam->GetEntry( j );
    1355         [ #  # ]:          0 :             if ( rEntry.bDoQuery )
    1356                 :            :             {
    1357         [ #  # ]:          0 :                 switch ( rEntry.eOp )
    1358                 :            :                 {
    1359                 :            :                     case SC_LESS_EQUAL :
    1360                 :            :                     case SC_GREATER_EQUAL :
    1361                 :          0 :                         rEntry.eOp = SC_EQUAL;
    1362                 :          0 :                     break;
    1363                 :            :                     default:
    1364                 :            :                     {
    1365                 :            :                         // added to avoid warnings
    1366                 :            :                     }
    1367                 :            :                 }
    1368                 :            :             }
    1369                 :            :             else
    1370                 :          0 :                 break;  // for
    1371                 :            :         }
    1372                 :          0 :         SetStopOnMismatch( false );
    1373                 :          0 :         SetTestEqualCondition( false );
    1374         [ #  # ]:          0 :         if (GetNext())
    1375                 :            :         {
    1376                 :            :             // Last of a consecutive area, avoid searching the entire parameter
    1377                 :            :             // range as it is a real performance bottleneck in case of regular
    1378                 :            :             // expressions.
    1379                 :            :             SCSIZE nColRowSave;
    1380         [ #  # ]:          0 :             do
    1381                 :            :             {
    1382                 :          0 :                 nFoundCol = GetCol();
    1383                 :          0 :                 nFoundRow = GetRow();
    1384                 :          0 :                 nColRowSave = nColRow;
    1385                 :          0 :                 SetStopOnMismatch( true );
    1386                 :          0 :             } while (GetNext());
    1387                 :          0 :             nCol = nFoundCol;
    1388                 :          0 :             nRow = nFoundRow;
    1389                 :          0 :             nColRow = nColRowSave;
    1390                 :            :         }
    1391                 :            :     }
    1392 [ +  + ][ +  - ]:        144 :     return (nFoundCol <= MAXCOL) && (nFoundRow <= MAXROW);
    1393                 :            : }
    1394                 :            : 
    1395                 :            : 
    1396                 :        144 : ScBaseCell* ScQueryCellIterator::BinarySearch()
    1397                 :            : {
    1398         [ +  - ]:        144 :     if (nTab >= pDoc->GetTableCount())
    1399                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
    1400                 :        144 :     nCol = mpParam->nCol1;
    1401                 :        144 :     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
    1402         [ -  + ]:        144 :     if (!pCol->maItems.size())
    1403                 :          0 :         return 0;
    1404                 :            : 
    1405                 :            :     ScBaseCell* pCell;
    1406                 :            :     SCSIZE nHi, nLo;
    1407                 :        144 :     CollatorWrapper* pCollator = (mpParam->bCaseSens ? ScGlobal::GetCaseCollator() :
    1408 [ #  # ][ +  - ]:        144 :         ScGlobal::GetCollator());
                 [ -  + ]
    1409         [ +  - ]:        144 :     SvNumberFormatter& rFormatter = *(pDoc->GetFormatTable());
    1410         [ +  - ]:        144 :     const ScQueryEntry& rEntry = mpParam->GetEntry(0);
    1411         [ +  - ]:        144 :     const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    1412                 :        144 :     bool bLessEqual = rEntry.eOp == SC_LESS_EQUAL;
    1413                 :        144 :     bool bByString = rItem.meType == ScQueryEntry::ByString;
    1414 [ +  - ][ +  + ]:        144 :     bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings && !bByString;
    1415                 :            :     bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
    1416 [ +  - ][ +  - ]:        144 :         !mpParam->bHasHeader && bByString;
                 [ +  + ]
    1417                 :            : 
    1418                 :        144 :     nRow = mpParam->nRow1;
    1419         [ -  + ]:        144 :     if (mpParam->bHasHeader)
    1420                 :          0 :         nRow++;
    1421 [ +  - ][ +  - ]:        189 :     if (pCol->Search( nRow, nLo ) && bFirstStringIgnore &&
         [ +  + ][ +  + ]
                 [ +  + ]
    1422         [ +  - ]:         45 :             pCol->maItems[nLo].pCell->HasStringData())
    1423                 :            :     {
    1424                 :         12 :         rtl::OUString aCellStr;
    1425         [ +  - ]:         12 :         sal_uLong nFormat = pCol->GetNumberFormat( pCol->maItems[nLo].nRow);
    1426                 :         12 :         ScCellFormat::GetInputString( pCol->maItems[nLo].pCell, nFormat, aCellStr,
    1427         [ +  - ]:         12 :                 rFormatter);
    1428 [ +  - ][ +  - ]:         12 :         sal_Int32 nTmp = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString);
    1429 [ -  + ][ #  # ]:         12 :         if ((rEntry.eOp == SC_LESS_EQUAL && nTmp > 0) ||
         [ +  - ][ +  + ]
         [ -  + ][ #  # ]
    1430                 :            :                 (rEntry.eOp == SC_GREATER_EQUAL && nTmp < 0) ||
    1431                 :            :                 (rEntry.eOp == SC_EQUAL && nTmp != 0))
    1432                 :         12 :             ++nLo;
    1433                 :            :     }
    1434 [ +  - ][ -  + ]:        144 :     if (!pCol->Search( mpParam->nRow2, nHi ) && nHi>0)
         [ #  # ][ -  + ]
    1435                 :          0 :         --nHi;
    1436 [ +  + ][ +  - ]:        459 :     while (bAllStringIgnore && nLo <= nHi && nLo < pCol->maItems.size() &&
         [ +  - ][ +  + ]
                 [ +  + ]
    1437         [ +  - ]:        207 :             pCol->maItems[nLo].pCell->HasStringData())
    1438                 :        108 :         ++nLo;
    1439                 :            : 
    1440                 :            :     // Bookkeeping values for breaking up the binary search in case the data
    1441                 :            :     // range isn't strictly sorted.
    1442                 :        144 :     SCSIZE nLastInRange = nLo;
    1443                 :        144 :     SCSIZE nFirstLastInRange = nLastInRange;
    1444                 :            :     double fLastInRangeValue = bLessEqual ?
    1445                 :         96 :         -(::std::numeric_limits<double>::max()) :
    1446         [ +  + ]:        240 :             ::std::numeric_limits<double>::max();
    1447         [ +  - ]:        144 :     String aLastInRangeString;
    1448         [ +  + ]:        144 :     if (!bLessEqual)
    1449         [ +  - ]:         48 :         aLastInRangeString.Assign( sal_Unicode(0xFFFF));
    1450         [ +  - ]:        144 :     if (nLastInRange < pCol->maItems.size())
    1451                 :            :     {
    1452                 :        144 :         pCell = pCol->maItems[nLastInRange].pCell;
    1453 [ +  + ][ +  - ]:        144 :         if (pCell->HasStringData())
    1454                 :            :         {
    1455         [ +  - ]:         12 :             sal_uLong nFormat = pCol->GetNumberFormat( pCol->maItems[nLastInRange].nRow);
    1456                 :         12 :             rtl::OUString aStr;
    1457                 :            :             ScCellFormat::GetInputString( pCell, nFormat, aStr,
    1458         [ +  - ]:         12 :                     rFormatter);
    1459         [ +  - ]:         12 :             aLastInRangeString = aStr;
    1460                 :            :         }
    1461                 :            :         else
    1462                 :            :         {
    1463      [ +  -  - ]:        132 :             switch ( pCell->GetCellType() )
    1464                 :            :             {
    1465                 :            :                 case CELLTYPE_VALUE :
    1466                 :            :                     fLastInRangeValue =
    1467                 :        132 :                         static_cast<ScValueCell*>(pCell)->GetValue();
    1468                 :        132 :                     break;
    1469                 :            :                 case CELLTYPE_FORMULA :
    1470                 :            :                     fLastInRangeValue =
    1471 [ #  # ][ #  # ]:          0 :                         static_cast<ScFormulaCell*>(pCell)->GetValue();
    1472                 :        144 :                     break;
    1473                 :            :                 default:
    1474                 :            :                 {
    1475                 :            :                     // added to avoid warnings
    1476                 :            :                 }
    1477                 :            :             }
    1478                 :            :         }
    1479                 :            :     }
    1480                 :            : 
    1481                 :        144 :     sal_Int32 nRes = 0;
    1482                 :        144 :     bool bFound = false;
    1483                 :        144 :     bool bDone = false;
    1484 [ +  + ][ +  + ]:        675 :     while (nLo <= nHi && !bDone)
                 [ +  + ]
    1485                 :            :     {
    1486                 :        531 :         SCSIZE nMid = (nLo+nHi)/2;
    1487                 :        531 :         SCSIZE i = nMid;
    1488 [ +  - ][ -  + ]:        531 :         while (i <= nHi && pCol->maItems[i].pCell->GetCellType() == CELLTYPE_NOTE)
                 [ -  + ]
    1489                 :          0 :             ++i;
    1490         [ -  + ]:        531 :         if (i > nHi)
    1491                 :            :         {
    1492         [ #  # ]:          0 :             if (nMid > 0)
    1493                 :          0 :                 nHi = nMid - 1;
    1494                 :            :             else
    1495                 :          0 :                 bDone = true;
    1496                 :          0 :             continue;   // while
    1497                 :            :         }
    1498         [ +  - ]:        531 :         bool bStr = pCol->maItems[i].pCell->HasStringData();
    1499                 :        531 :         nRes = 0;
    1500                 :            :         // compares are content<query:-1, content>query:1
    1501                 :            :         // Cell value comparison similar to ScTable::ValidQuery()
    1502 [ +  + ][ +  + ]:        531 :         if (!bStr && !bByString)
    1503                 :            :         {
    1504                 :            :             double nCellVal;
    1505                 :        324 :             pCell = pCol->maItems[i].pCell;
    1506      [ +  -  - ]:        324 :             switch ( pCell->GetCellType() )
    1507                 :            :             {
    1508                 :            :                 case CELLTYPE_VALUE :
    1509                 :        324 :                     nCellVal = static_cast<ScValueCell*>(pCell)->GetValue();
    1510                 :        324 :                     break;
    1511                 :            :                 case CELLTYPE_FORMULA :
    1512 [ #  # ][ #  # ]:          0 :                     nCellVal = static_cast<ScFormulaCell*>(pCell)->GetValue();
    1513                 :          0 :                     break;
    1514                 :            :                 default:
    1515                 :          0 :                     nCellVal = 0.0;
    1516                 :            :             }
    1517   [ +  +  +  - ]:        474 :             if ((nCellVal < rItem.mfVal) && !::rtl::math::approxEqual(
                 [ +  + ]
    1518                 :        150 :                         nCellVal, rItem.mfVal))
    1519                 :            :             {
    1520                 :        150 :                 nRes = -1;
    1521         [ +  + ]:        150 :                 if (bLessEqual)
    1522                 :            :                 {
    1523         [ +  + ]:        105 :                     if (fLastInRangeValue < nCellVal)
    1524                 :            :                     {
    1525                 :         93 :                         fLastInRangeValue = nCellVal;
    1526                 :         93 :                         nLastInRange = i;
    1527                 :            :                     }
    1528         [ -  + ]:         12 :                     else if (fLastInRangeValue > nCellVal)
    1529                 :            :                     {
    1530                 :            :                         // not strictly sorted, continue with GetThis()
    1531                 :          0 :                         nLastInRange = nFirstLastInRange;
    1532                 :          0 :                         bDone = true;
    1533                 :            :                     }
    1534                 :            :                 }
    1535                 :            :             }
    1536   [ +  -  +  - ]:        348 :             else if ((nCellVal > rItem.mfVal) && !::rtl::math::approxEqual(
                 [ +  - ]
    1537                 :        174 :                         nCellVal, rItem.mfVal))
    1538                 :            :             {
    1539                 :        174 :                 nRes = 1;
    1540         [ +  + ]:        174 :                 if (!bLessEqual)
    1541                 :            :                 {
    1542         [ +  + ]:         81 :                     if (fLastInRangeValue > nCellVal)
    1543                 :            :                     {
    1544                 :         78 :                         fLastInRangeValue = nCellVal;
    1545                 :         78 :                         nLastInRange = i;
    1546                 :            :                     }
    1547         [ -  + ]:          3 :                     else if (fLastInRangeValue < nCellVal)
    1548                 :            :                     {
    1549                 :            :                         // not strictly sorted, continue with GetThis()
    1550                 :          0 :                         nLastInRange = nFirstLastInRange;
    1551                 :          0 :                         bDone = true;
    1552                 :            :                     }
    1553                 :            :                 }
    1554                 :        324 :             }
    1555                 :            :         }
    1556 [ +  + ][ +  + ]:        207 :         else if (bStr && bByString)
    1557                 :            :         {
    1558                 :        111 :             rtl::OUString aCellStr;
    1559         [ +  - ]:        111 :             sal_uLong nFormat = pCol->GetNumberFormat( pCol->maItems[i].nRow);
    1560                 :        111 :             ScCellFormat::GetInputString( pCol->maItems[i].pCell, nFormat, aCellStr,
    1561         [ +  - ]:        111 :                     rFormatter);
    1562 [ +  - ][ +  - ]:        111 :             nRes = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString);
    1563 [ +  + ][ +  + ]:        111 :             if (nRes < 0 && bLessEqual)
    1564                 :            :             {
    1565                 :            :                 sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
    1566 [ +  - ][ +  - ]:         57 :                         aCellStr);
    1567         [ +  + ]:         57 :                 if (nTmp < 0)
    1568                 :            :                 {
    1569         [ +  - ]:         54 :                     aLastInRangeString = aCellStr;
    1570                 :         54 :                     nLastInRange = i;
    1571                 :            :                 }
    1572         [ -  + ]:          3 :                 else if (nTmp > 0)
    1573                 :            :                 {
    1574                 :            :                     // not strictly sorted, continue with GetThis()
    1575                 :          0 :                     nLastInRange = nFirstLastInRange;
    1576                 :          0 :                     bDone = true;
    1577                 :         57 :                 }
    1578                 :            :             }
    1579 [ +  + ][ +  + ]:         54 :             else if (nRes > 0 && !bLessEqual)
    1580                 :            :             {
    1581                 :            :                 sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
    1582 [ +  - ][ +  - ]:         12 :                         aCellStr);
    1583         [ +  + ]:         12 :                 if (nTmp > 0)
    1584                 :            :                 {
    1585         [ +  - ]:          6 :                     aLastInRangeString = aCellStr;
    1586                 :          6 :                     nLastInRange = i;
    1587                 :            :                 }
    1588         [ -  + ]:          6 :                 else if (nTmp < 0)
    1589                 :            :                 {
    1590                 :            :                     // not strictly sorted, continue with GetThis()
    1591                 :          0 :                     nLastInRange = nFirstLastInRange;
    1592                 :          0 :                     bDone = true;
    1593                 :            :                 }
    1594                 :        111 :             }
    1595                 :            :         }
    1596 [ +  + ][ +  - ]:         96 :         else if (!bStr && bByString)
    1597                 :            :         {
    1598                 :         60 :             nRes = -1;  // numeric < string
    1599         [ +  + ]:        102 :             if (bLessEqual)
    1600                 :         42 :                 nLastInRange = i;
    1601                 :            :         }
    1602                 :            :         else // if (bStr && !bByString)
    1603                 :            :         {
    1604                 :         36 :             nRes = 1;   // string > numeric
    1605         [ -  + ]:         36 :             if (!bLessEqual)
    1606                 :          0 :                 nLastInRange = i;
    1607                 :            :         }
    1608         [ +  + ]:        531 :         if (nRes < 0)
    1609                 :            :         {
    1610         [ +  + ]:        279 :             if (bLessEqual)
    1611                 :        204 :                 nLo = nMid + 1;
    1612                 :            :             else    // assumed to be SC_GREATER_EQUAL
    1613                 :            :             {
    1614         [ +  - ]:         75 :                 if (nMid > 0)
    1615                 :         75 :                     nHi = nMid - 1;
    1616                 :            :                 else
    1617                 :          0 :                     bDone = true;
    1618                 :            :             }
    1619                 :            :         }
    1620         [ +  - ]:        252 :         else if (nRes > 0)
    1621                 :            :         {
    1622         [ +  + ]:        252 :             if (bLessEqual)
    1623                 :            :             {
    1624         [ +  + ]:        159 :                 if (nMid > 0)
    1625                 :        156 :                     nHi = nMid - 1;
    1626                 :            :                 else
    1627                 :          3 :                     bDone = true;
    1628                 :            :             }
    1629                 :            :             else    // assumed to be SC_GREATER_EQUAL
    1630                 :         93 :                 nLo = nMid + 1;
    1631                 :            :         }
    1632                 :            :         else
    1633                 :            :         {
    1634                 :          0 :             nLo = i;
    1635                 :          0 :             bDone = bFound = true;
    1636                 :            :         }
    1637                 :            :     }
    1638         [ +  - ]:        144 :     if (!bFound)
    1639                 :            :     {
    1640                 :            :         // If all hits didn't result in a moving limit there's something
    1641                 :            :         // strange, e.g. data range not properly sorted, or only identical
    1642                 :            :         // values encountered, which doesn't mean there aren't any others in
    1643                 :            :         // between.. leave it to GetThis(). The condition for this would be
    1644                 :            :         // if (nLastInRange == nFirstLastInRange) nLo = nFirstLastInRange;
    1645                 :            :         // Else, in case no exact match was found, we step back for a
    1646                 :            :         // subsequent GetThis() to find the last in range. Effectively this is
    1647                 :            :         // --nLo with nLastInRange == nLo-1. Both conditions combined yield:
    1648                 :        144 :         nLo = nLastInRange;
    1649                 :            :     }
    1650 [ +  - ][ +  - ]:        144 :     if (nLo < pCol->maItems.size() && pCol->maItems[nLo].nRow <= mpParam->nRow2)
                 [ +  - ]
    1651                 :            :     {
    1652                 :        144 :         nRow = pCol->maItems[nLo].nRow;
    1653                 :        144 :         pCell = pCol->maItems[nLo].pCell;
    1654                 :        144 :         nColRow = nLo;
    1655                 :            :     }
    1656                 :            :     else
    1657                 :            :     {
    1658                 :          0 :         nRow = mpParam->nRow2 + 1;
    1659                 :          0 :         pCell = 0;
    1660                 :          0 :         nColRow = pCol->maItems.size() - 1;
    1661                 :            :     }
    1662         [ +  - ]:        144 :     return pCell;
    1663                 :            : }
    1664                 :            : 
    1665                 :            : 
    1666                 :            : //-------------------------------------------------------------------------------
    1667                 :            : 
    1668                 :       4202 : ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
    1669                 :            :                                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
    1670                 :            :     pDoc( pDocument ),
    1671                 :            :     nTab( nTable ),
    1672                 :            :     nStartCol( nCol1 ),
    1673                 :            :     nEndCol( nCol2 ),
    1674                 :            :     nStartRow( nRow1 ),
    1675                 :            :     nEndRow( nRow2 ),
    1676                 :            :     nCol( nCol1 ),
    1677                 :            :     nRow( nRow1 ),
    1678                 :       4202 :     bMore( true )
    1679                 :            : {
    1680                 :       4202 :     if (nTab >= pDoc->GetTableCount())
    1681                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
    1682                 :            : 
    1683                 :       4202 :     pNextRows = new SCROW[ nCol2-nCol1+1 ];
    1684                 :       4202 :     pNextIndices = new SCSIZE[ nCol2-nCol1+1 ];
    1685                 :            : 
    1686                 :       4202 :     SetTab( nTab );
    1687                 :       4202 : }
    1688                 :            : 
    1689                 :       4202 : ScHorizontalCellIterator::~ScHorizontalCellIterator()
    1690                 :            : {
    1691         [ +  - ]:       4202 :     delete [] pNextRows;
    1692         [ +  - ]:       4202 :     delete [] pNextIndices;
    1693                 :       4202 : }
    1694                 :            : 
    1695                 :       4202 : void ScHorizontalCellIterator::SetTab( SCTAB nTabP )
    1696                 :            : {
    1697                 :       4202 :     nTab = nTabP;
    1698                 :       4202 :     nRow = nStartRow;
    1699                 :       4202 :     nCol = nStartCol;
    1700                 :       4202 :     bMore = true;
    1701                 :            : 
    1702         [ +  + ]:    1945000 :     for (SCCOL i=nStartCol; i<=nEndCol; i++)
    1703                 :            :     {
    1704                 :    1940798 :         ScColumn* pCol = &pDoc->maTabs[nTab]->aCol[i];
    1705                 :            : 
    1706                 :            :         SCSIZE nIndex;
    1707         [ +  - ]:    1940798 :         pCol->Search( nStartRow, nIndex );
    1708         [ +  + ]:    1940798 :         if ( nIndex < pCol->maItems.size() )
    1709                 :            :         {
    1710                 :      10306 :             pNextRows[i-nStartCol] = pCol->maItems[nIndex].nRow;
    1711                 :      10306 :             pNextIndices[i-nStartCol] = nIndex;
    1712                 :            :         }
    1713                 :            :         else
    1714                 :            :         {
    1715                 :    1930492 :             pNextRows[i-nStartCol] = MAXROWCOUNT;       // nichts gefunden
    1716                 :    1930492 :             pNextIndices[i-nStartCol] = MAXROWCOUNT;
    1717                 :            :         }
    1718                 :            :     }
    1719                 :            : 
    1720         [ +  + ]:       4202 :    if (pNextRows[0] != nStartRow)
    1721                 :       2587 :         Advance();
    1722                 :       4202 : }
    1723                 :            : 
    1724                 :      18641 : ScBaseCell* ScHorizontalCellIterator::GetNext( SCCOL& rCol, SCROW& rRow )
    1725                 :            : {
    1726         [ +  + ]:      18641 :     if ( bMore )
    1727                 :            :     {
    1728                 :      15759 :         rCol = nCol;
    1729                 :      15759 :         rRow = nRow;
    1730                 :            : 
    1731                 :      15759 :         ScColumn* pCol = &pDoc->maTabs[nTab]->aCol[nCol];
    1732                 :      15759 :         SCSIZE nIndex = pNextIndices[nCol-nStartCol];
    1733                 :            :         OSL_ENSURE( nIndex < pCol->maItems.size(), "ScHorizontalCellIterator::GetNext: nIndex out of range" );
    1734                 :      15759 :         ScBaseCell* pCell = pCol->maItems[nIndex].pCell;
    1735         [ +  + ]:      15759 :         if ( ++nIndex < pCol->maItems.size() )
    1736                 :            :         {
    1737                 :      12367 :             pNextRows[nCol-nStartCol] = pCol->maItems[nIndex].nRow;
    1738                 :      12367 :             pNextIndices[nCol-nStartCol] = nIndex;
    1739                 :            :         }
    1740                 :            :         else
    1741                 :            :         {
    1742                 :       3392 :             pNextRows[nCol-nStartCol] = MAXROWCOUNT;        // nichts gefunden
    1743                 :       3392 :             pNextIndices[nCol-nStartCol] = MAXROWCOUNT;
    1744                 :            :         }
    1745                 :            : 
    1746                 :      15759 :         Advance();
    1747                 :      15759 :         return pCell;
    1748                 :            :     }
    1749                 :            :     else
    1750                 :      18641 :         return NULL;
    1751                 :            : }
    1752                 :            : 
    1753                 :          4 : bool ScHorizontalCellIterator::ReturnNext( SCCOL& rCol, SCROW& rRow )
    1754                 :            : {
    1755                 :          4 :     rCol = nCol;
    1756                 :          4 :     rRow = nRow;
    1757                 :          4 :     return bMore;
    1758                 :            : }
    1759                 :            : 
    1760                 :      18346 : void ScHorizontalCellIterator::Advance()
    1761                 :            : {
    1762                 :      18346 :     bool bFound = false;
    1763                 :            :     SCCOL i;
    1764                 :            : 
    1765 [ +  + ][ +  + ]:    2899097 :     for (i=nCol+1; i<=nEndCol && !bFound; i++)
                 [ +  + ]
    1766         [ +  + ]:    2880751 :         if (pNextRows[i-nStartCol] == nRow)
    1767                 :            :         {
    1768                 :      12492 :             nCol = i;
    1769                 :      12492 :             bFound = true;
    1770                 :            :         }
    1771                 :            : 
    1772         [ +  + ]:      18346 :     if (!bFound)
    1773                 :            :     {
    1774                 :       5854 :         SCROW nMinRow = MAXROW+1;
    1775         [ +  + ]:    2892677 :         for (i=nStartCol; i<=nEndCol; i++)
    1776         [ +  + ]:    2886823 :             if (pNextRows[i-nStartCol] < nMinRow)
    1777                 :            :             {
    1778                 :       2730 :                 nCol = i;
    1779                 :       2730 :                 nMinRow = pNextRows[i-nStartCol];
    1780                 :            :             }
    1781                 :            : 
    1782         [ +  + ]:       5854 :         if (nMinRow <= nEndRow)
    1783                 :            :         {
    1784                 :       2575 :             nRow = nMinRow;
    1785                 :       2575 :             bFound = true;
    1786                 :            :         }
    1787                 :            :     }
    1788                 :            : 
    1789         [ +  + ]:      18346 :     if ( !bFound )
    1790                 :       3279 :         bMore = false;
    1791                 :      18346 : }
    1792                 :            : 
    1793                 :            : //------------------------------------------------------------------------
    1794                 :            : 
    1795                 :          0 : ScHorizontalValueIterator::ScHorizontalValueIterator( ScDocument* pDocument,
    1796                 :            :         const ScRange& rRange, bool bSTotal, bool bTextZero ) :
    1797                 :            :     pDoc( pDocument ),
    1798                 :            :     nNumFmtIndex(0),
    1799                 :          0 :     nEndTab( rRange.aEnd.Tab() ),
    1800                 :            :     nNumFmtType( NUMBERFORMAT_UNDEFINED ),
    1801                 :            :     bNumValid( false ),
    1802                 :            :     bSubTotal( bSTotal ),
    1803                 :          0 :     bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
    1804                 :          0 :     bTextAsZero( bTextZero )
    1805                 :            : {
    1806                 :          0 :     SCCOL nStartCol = rRange.aStart.Col();
    1807                 :          0 :     SCROW nStartRow = rRange.aStart.Row();
    1808                 :          0 :     SCTAB nStartTab = rRange.aStart.Tab();
    1809                 :          0 :     SCCOL nEndCol = rRange.aEnd.Col();
    1810                 :          0 :     SCROW nEndRow = rRange.aEnd.Row();
    1811                 :          0 :     PutInOrder( nStartCol, nEndCol);
    1812                 :          0 :     PutInOrder( nStartRow, nEndRow);
    1813                 :          0 :     PutInOrder( nStartTab, nEndTab );
    1814                 :            : 
    1815         [ #  # ]:          0 :     if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
    1816         [ #  # ]:          0 :     if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
    1817         [ #  # ]:          0 :     if (!ValidRow(nStartRow)) nStartRow = MAXROW;
    1818         [ #  # ]:          0 :     if (!ValidRow(nEndRow)) nEndRow = MAXROW;
    1819         [ #  # ]:          0 :     if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
    1820         [ #  # ]:          0 :     if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
    1821                 :            : 
    1822                 :          0 :     nCurCol = nStartCol;
    1823                 :          0 :     nCurRow = nStartRow;
    1824                 :          0 :     nCurTab = nStartTab;
    1825                 :            : 
    1826                 :          0 :     nNumFormat = 0;                 // will be initialized in GetNumberFormat()
    1827                 :          0 :     pAttrArray = 0;
    1828                 :          0 :     nAttrEndRow = 0;
    1829                 :            : 
    1830                 :            :     pCellIter = new ScHorizontalCellIterator( pDoc, nStartTab, nStartCol,
    1831 [ #  # ][ #  # ]:          0 :             nStartRow, nEndCol, nEndRow );
    1832                 :          0 : }
    1833                 :            : 
    1834                 :          0 : ScHorizontalValueIterator::~ScHorizontalValueIterator()
    1835                 :            : {
    1836         [ #  # ]:          0 :     delete pCellIter;
    1837                 :          0 : }
    1838                 :            : 
    1839                 :          0 : bool ScHorizontalValueIterator::GetNext( double& rValue, sal_uInt16& rErr )
    1840                 :            : {
    1841                 :          0 :     bool bFound = false;
    1842         [ #  # ]:          0 :     while ( !bFound )
    1843                 :            :     {
    1844                 :          0 :         ScBaseCell* pCell = pCellIter->GetNext( nCurCol, nCurRow );
    1845         [ #  # ]:          0 :         while ( !pCell )
    1846                 :            :         {
    1847         [ #  # ]:          0 :             if ( nCurTab < nEndTab )
    1848                 :            :             {
    1849                 :          0 :                 pCellIter->SetTab( ++nCurTab);
    1850                 :          0 :                 pCell = pCellIter->GetNext( nCurCol, nCurRow );
    1851                 :            :             }
    1852                 :            :             else
    1853                 :          0 :                 return false;
    1854                 :            :         }
    1855 [ #  # ][ #  # ]:          0 :         if ( !bSubTotal || !pDoc->maTabs[nCurTab]->RowFiltered( nCurRow ) )
                 [ #  # ]
    1856                 :            :         {
    1857   [ #  #  #  # ]:          0 :             switch (pCell->GetCellType())
    1858                 :            :             {
    1859                 :            :                 case CELLTYPE_VALUE:
    1860                 :            :                     {
    1861                 :          0 :                         bNumValid = false;
    1862                 :          0 :                         rValue = ((ScValueCell*)pCell)->GetValue();
    1863                 :          0 :                         rErr = 0;
    1864         [ #  # ]:          0 :                         if ( bCalcAsShown )
    1865                 :            :                         {
    1866                 :          0 :                             ScColumn* pCol = &pDoc->maTabs[nCurTab]->aCol[nCurCol];
    1867                 :            :                             lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
    1868                 :          0 :                                     nAttrEndRow, pCol->pAttrArray, nCurRow, pDoc );
    1869                 :          0 :                             rValue = pDoc->RoundValueAsShown( rValue, nNumFormat );
    1870                 :            :                         }
    1871                 :          0 :                         bFound = true;
    1872                 :            :                     }
    1873                 :          0 :                     break;
    1874                 :            :                 case CELLTYPE_FORMULA:
    1875                 :            :                     {
    1876 [ #  # ][ #  # ]:          0 :                         if (!bSubTotal || !((ScFormulaCell*)pCell)->IsSubTotal())
         [ #  # ][ #  # ]
    1877                 :            :                         {
    1878         [ #  # ]:          0 :                             rErr = ((ScFormulaCell*)pCell)->GetErrCode();
    1879 [ #  # ][ #  # ]:          0 :                             if ( rErr || ((ScFormulaCell*)pCell)->IsValue() )
         [ #  # ][ #  # ]
    1880                 :            :                             {
    1881         [ #  # ]:          0 :                                 rValue = ((ScFormulaCell*)pCell)->GetValue();
    1882                 :          0 :                                 bNumValid = false;
    1883                 :          0 :                                 bFound = true;
    1884                 :            :                             }
    1885         [ #  # ]:          0 :                             else if ( bTextAsZero )
    1886                 :            :                             {
    1887                 :          0 :                                 rValue = 0.0;
    1888                 :          0 :                                 bNumValid = false;
    1889                 :          0 :                                 bFound = true;
    1890                 :            :                             }
    1891                 :            :                         }
    1892                 :            :                     }
    1893                 :          0 :                     break;
    1894                 :            :                 case CELLTYPE_STRING :
    1895                 :            :                 case CELLTYPE_EDIT :
    1896                 :            :                     {
    1897         [ #  # ]:          0 :                         if ( bTextAsZero )
    1898                 :            :                         {
    1899                 :          0 :                             rErr = 0;
    1900                 :          0 :                             rValue = 0.0;
    1901                 :          0 :                             nNumFmtType = NUMBERFORMAT_NUMBER;
    1902                 :          0 :                             nNumFmtIndex = 0;
    1903                 :          0 :                             bNumValid = true;
    1904                 :          0 :                             bFound = true;
    1905                 :            :                         }
    1906                 :            :                     }
    1907                 :          0 :                     break;
    1908                 :            :                 default:
    1909                 :            :                     ;   // nothing
    1910                 :            :             }
    1911                 :            :         }
    1912                 :            :     }
    1913                 :          0 :     return bFound;
    1914                 :            : }
    1915                 :            : 
    1916                 :            : //-------------------------------------------------------------------------------
    1917                 :            : 
    1918                 :          0 : ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
    1919                 :            :                             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
    1920                 :            :     pDoc( pDocument ),
    1921                 :            :     nTab( nTable ),
    1922                 :            :     nStartCol( nCol1 ),
    1923                 :            :     nStartRow( nRow1 ),
    1924                 :            :     nEndCol( nCol2 ),
    1925                 :          0 :     nEndRow( nRow2 )
    1926                 :            : {
    1927                 :          0 :     if (nTab >= pDoc->GetTableCount())
    1928                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
    1929                 :            :     OSL_ENSURE( pDoc->maTabs[nTab], "Tabelle nicht da" );
    1930                 :            : 
    1931                 :            :     SCCOL i;
    1932                 :            : 
    1933                 :          0 :     nRow = nStartRow;
    1934                 :          0 :     nCol = nStartCol;
    1935                 :          0 :     bRowEmpty = false;
    1936                 :            : 
    1937                 :          0 :     pIndices    = new SCSIZE[nEndCol-nStartCol+1];
    1938                 :          0 :     pNextEnd    = new SCROW[nEndCol-nStartCol+1];
    1939                 :          0 :     ppPatterns  = new const ScPatternAttr*[nEndCol-nStartCol+1];
    1940                 :            : 
    1941                 :          0 :     SCROW nSkipTo = MAXROW;
    1942                 :          0 :     bool bEmpty = true;
    1943         [ #  # ]:          0 :     for (i=nStartCol; i<=nEndCol; i++)
    1944                 :            :     {
    1945                 :          0 :         SCCOL nPos = i - nStartCol;
    1946                 :          0 :         ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray;
    1947                 :            :         OSL_ENSURE( pArray, "pArray == 0" );
    1948                 :            : 
    1949                 :            :         SCSIZE nIndex;
    1950         [ #  # ]:          0 :         pArray->Search( nStartRow, nIndex );
    1951                 :            : 
    1952                 :          0 :         const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
    1953                 :          0 :         SCROW nThisEnd = pArray->pData[nIndex].nRow;
    1954         [ #  # ]:          0 :         if ( IsDefaultItem( pPattern ) )
    1955                 :            :         {
    1956                 :          0 :             pPattern = NULL;
    1957         [ #  # ]:          0 :             if ( nThisEnd < nSkipTo )
    1958                 :          0 :                 nSkipTo = nThisEnd;         // nSkipTo kann gleich hier gesetzt werden
    1959                 :            :         }
    1960                 :            :         else
    1961                 :          0 :             bEmpty = false;                 // Attribute gefunden
    1962                 :            : 
    1963                 :          0 :         pIndices[nPos] = nIndex;
    1964                 :          0 :         pNextEnd[nPos] = nThisEnd;
    1965                 :          0 :         ppPatterns[nPos] = pPattern;
    1966                 :            :     }
    1967                 :            : 
    1968         [ #  # ]:          0 :     if (bEmpty)
    1969                 :          0 :         nRow = nSkipTo;                     // bis zum naechsten Bereichsende ueberspringen
    1970                 :          0 :     bRowEmpty = bEmpty;
    1971                 :          0 : }
    1972                 :            : 
    1973                 :          0 : ScHorizontalAttrIterator::~ScHorizontalAttrIterator()
    1974                 :            : {
    1975         [ #  # ]:          0 :     delete[] (ScPatternAttr**)ppPatterns;
    1976         [ #  # ]:          0 :     delete[] pNextEnd;
    1977         [ #  # ]:          0 :     delete[] pIndices;
    1978                 :          0 : }
    1979                 :            : 
    1980                 :          0 : const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow )
    1981                 :            : {
    1982                 :          0 :     if (nTab >= pDoc->GetTableCount())
    1983                 :            :         OSL_FAIL("try to access index out of bounds, FIX IT");
    1984                 :          0 :     for (;;)
    1985                 :            :     {
    1986         [ #  # ]:          0 :         if (!bRowEmpty)
    1987                 :            :         {
    1988                 :            :             // in dieser Zeile suchen
    1989                 :            : 
    1990 [ #  # ][ #  # ]:          0 :             while ( nCol <= nEndCol && !ppPatterns[nCol-nStartCol] )
                 [ #  # ]
    1991                 :          0 :                 ++nCol;
    1992                 :            : 
    1993         [ #  # ]:          0 :             if ( nCol <= nEndCol )
    1994                 :            :             {
    1995                 :          0 :                 const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
    1996                 :          0 :                 rRow = nRow;
    1997                 :          0 :                 rCol1 = nCol;
    1998 [ #  # ][ #  # ]:          0 :                 while ( nCol < nEndCol && ppPatterns[nCol+1-nStartCol] == pPat )
                 [ #  # ]
    1999                 :          0 :                     ++nCol;
    2000                 :          0 :                 rCol2 = nCol;
    2001                 :          0 :                 ++nCol;                 // hochzaehlen fuer naechsten Aufruf
    2002                 :          0 :                 return pPat;            // gefunden
    2003                 :            :             }
    2004                 :            :         }
    2005                 :            : 
    2006                 :            :         // naechste Zeile
    2007                 :            : 
    2008                 :          0 :         ++nRow;
    2009         [ #  # ]:          0 :         if ( nRow > nEndRow )       // schon am Ende?
    2010                 :          0 :             return NULL;            // nichts gefunden
    2011                 :            : 
    2012                 :          0 :         bool bEmpty = true;
    2013                 :            :         SCCOL i;
    2014                 :            : 
    2015         [ #  # ]:          0 :         for ( i = nStartCol; i <= nEndCol; i++)
    2016                 :            :         {
    2017                 :          0 :             SCCOL nPos = i-nStartCol;
    2018         [ #  # ]:          0 :             if ( pNextEnd[nPos] < nRow )
    2019                 :            :             {
    2020                 :          0 :                 ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray;
    2021                 :            : 
    2022                 :          0 :                 SCSIZE nIndex = ++pIndices[nPos];
    2023         [ #  # ]:          0 :                 if ( nIndex < pArray->nCount )
    2024                 :            :                 {
    2025                 :          0 :                     const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
    2026                 :          0 :                     SCROW nThisEnd = pArray->pData[nIndex].nRow;
    2027         [ #  # ]:          0 :                     if ( IsDefaultItem( pPattern ) )
    2028                 :          0 :                         pPattern = NULL;
    2029                 :            :                     else
    2030                 :          0 :                         bEmpty = false;                 // Attribute gefunden
    2031                 :            : 
    2032                 :          0 :                     pNextEnd[nPos] = nThisEnd;
    2033                 :          0 :                     ppPatterns[nPos] = pPattern;
    2034                 :            : 
    2035                 :            :                     OSL_ENSURE( pNextEnd[nPos] >= nRow, "Reihenfolge durcheinander" );
    2036                 :            :                 }
    2037                 :            :                 else
    2038                 :            :                 {
    2039                 :            :                     OSL_FAIL("AttrArray reicht nicht bis MAXROW");
    2040                 :          0 :                     pNextEnd[nPos] = MAXROW;
    2041                 :          0 :                     ppPatterns[nPos] = NULL;
    2042                 :            :                 }
    2043                 :            :             }
    2044         [ #  # ]:          0 :             else if ( ppPatterns[nPos] )
    2045                 :          0 :                 bEmpty = false;                         // Bereich noch nicht zuende
    2046                 :            :         }
    2047                 :            : 
    2048         [ #  # ]:          0 :         if (bEmpty)
    2049                 :            :         {
    2050                 :          0 :             SCCOL nCount = nEndCol-nStartCol+1;
    2051                 :          0 :             SCROW nSkipTo = pNextEnd[0];                // naechstes Bereichsende suchen
    2052         [ #  # ]:          0 :             for (i=1; i<nCount; i++)
    2053         [ #  # ]:          0 :                 if ( pNextEnd[i] < nSkipTo )
    2054                 :          0 :                     nSkipTo = pNextEnd[i];
    2055                 :          0 :             nRow = nSkipTo;                             // leere Zeilen ueberspringen
    2056                 :            :         }
    2057                 :          0 :         bRowEmpty = bEmpty;
    2058                 :          0 :         nCol = nStartCol;           // wieder links anfangen
    2059                 :            :     }
    2060                 :            : }
    2061                 :            : 
    2062                 :            : //-------------------------------------------------------------------------------
    2063                 :            : 
    2064                 :          0 : inline bool IsGreater( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    2065                 :            : {
    2066 [ #  # ][ #  # ]:          0 :     return ( nRow1 > nRow2 ) || ( nRow1 == nRow2 && nCol1 > nCol2 );
                 [ #  # ]
    2067                 :            : }
    2068                 :            : 
    2069                 :          0 : ScUsedAreaIterator::ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
    2070                 :            :                             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
    2071                 :            :     aCellIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
    2072                 :            :     aAttrIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
    2073                 :            :     nNextCol( nCol1 ),
    2074         [ #  # ]:          0 :     nNextRow( nRow1 )
    2075                 :            : {
    2076         [ #  # ]:          0 :     pCell    = aCellIter.GetNext( nCellCol, nCellRow );
    2077         [ #  # ]:          0 :     pPattern = aAttrIter.GetNext( nAttrCol1, nAttrCol2, nAttrRow );
    2078                 :          0 : }
    2079                 :            : 
    2080                 :          0 : ScUsedAreaIterator::~ScUsedAreaIterator()
    2081                 :            : {
    2082                 :          0 : }
    2083                 :            : 
    2084                 :          0 : bool ScUsedAreaIterator::GetNext()
    2085                 :            : {
    2086                 :            :     //  Iteratoren weiterzaehlen
    2087                 :            : 
    2088 [ #  # ][ #  # ]:          0 :     if ( pCell && IsGreater( nNextCol, nNextRow, nCellCol, nCellRow ) )
                 [ #  # ]
    2089                 :          0 :         pCell = aCellIter.GetNext( nCellCol, nCellRow );
    2090                 :            : 
    2091 [ #  # ][ #  # ]:          0 :     while ( pCell && pCell->IsBlank() )
                 [ #  # ]
    2092                 :          0 :         pCell = aCellIter.GetNext( nCellCol, nCellRow );
    2093                 :            : 
    2094 [ #  # ][ #  # ]:          0 :     if ( pPattern && IsGreater( nNextCol, nNextRow, nAttrCol2, nAttrRow ) )
                 [ #  # ]
    2095                 :          0 :         pPattern = aAttrIter.GetNext( nAttrCol1, nAttrCol2, nAttrRow );
    2096                 :            : 
    2097 [ #  # ][ #  # ]:          0 :     if ( pPattern && nAttrRow == nNextRow && nAttrCol1 < nNextCol )
                 [ #  # ]
    2098                 :          0 :         nAttrCol1 = nNextCol;
    2099                 :            : 
    2100                 :            :     //  naechsten Abschnitt heraussuchen
    2101                 :            : 
    2102                 :          0 :     bool bFound = true;
    2103                 :          0 :     bool bUseCell = false;
    2104                 :            : 
    2105 [ #  # ][ #  # ]:          0 :     if ( pCell && pPattern )
    2106                 :            :     {
    2107         [ #  # ]:          0 :         if ( IsGreater( nCellCol, nCellRow, nAttrCol1, nAttrRow ) )     // vorne nur Attribute ?
    2108                 :            :         {
    2109                 :          0 :             pFoundCell = NULL;
    2110                 :          0 :             pFoundPattern = pPattern;
    2111                 :          0 :             nFoundRow = nAttrRow;
    2112                 :          0 :             nFoundStartCol = nAttrCol1;
    2113 [ #  # ][ #  # ]:          0 :             if ( nCellRow == nAttrRow && nCellCol <= nAttrCol2 )        // auch Zelle im Bereich ?
    2114                 :          0 :                 nFoundEndCol = nCellCol - 1;                            // nur bis vor der Zelle
    2115                 :            :             else
    2116                 :          0 :                 nFoundEndCol = nAttrCol2;                               // alles
    2117                 :            :         }
    2118                 :            :         else
    2119                 :            :         {
    2120                 :          0 :             bUseCell = true;
    2121 [ #  # ][ #  # ]:          0 :             if ( nAttrRow == nCellRow && nAttrCol1 == nCellCol )        // Attribute auf der Zelle ?
    2122                 :          0 :                 pFoundPattern = pPattern;
    2123                 :            :             else
    2124                 :          0 :                 pFoundPattern = NULL;
    2125                 :            :         }
    2126                 :            :     }
    2127         [ #  # ]:          0 :     else if ( pCell )                   // nur Zelle -> direkt uebernehmen
    2128                 :            :     {
    2129                 :          0 :         pFoundPattern = NULL;
    2130                 :          0 :         bUseCell = true;                // Position von Zelle
    2131                 :            :     }
    2132         [ #  # ]:          0 :     else if ( pPattern )                // nur Attribute -> direkt uebernehmen
    2133                 :            :     {
    2134                 :          0 :         pFoundCell = NULL;
    2135                 :          0 :         pFoundPattern = pPattern;
    2136                 :          0 :         nFoundRow = nAttrRow;
    2137                 :          0 :         nFoundStartCol = nAttrCol1;
    2138                 :          0 :         nFoundEndCol = nAttrCol2;
    2139                 :            :     }
    2140                 :            :     else                                // gar nichts
    2141                 :          0 :         bFound = false;
    2142                 :            : 
    2143         [ #  # ]:          0 :     if ( bUseCell )                     // Position von Zelle
    2144                 :            :     {
    2145                 :          0 :         pFoundCell = pCell;
    2146                 :          0 :         nFoundRow = nCellRow;
    2147                 :          0 :         nFoundStartCol = nFoundEndCol = nCellCol;
    2148                 :            :     }
    2149                 :            : 
    2150         [ #  # ]:          0 :     if (bFound)
    2151                 :            :     {
    2152                 :          0 :         nNextRow = nFoundRow;
    2153                 :          0 :         nNextCol = nFoundEndCol + 1;
    2154                 :            :     }
    2155                 :            : 
    2156                 :          0 :     return bFound;
    2157                 :            : }
    2158                 :            : 
    2159                 :            : //-------------------------------------------------------------------------------
    2160                 :            : 
    2161                 :     544775 : ScDocAttrIterator::ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
    2162                 :            :                                     SCCOL nCol1, SCROW nRow1,
    2163                 :            :                                     SCCOL nCol2, SCROW nRow2) :
    2164                 :            :     pDoc( pDocument ),
    2165                 :            :     nTab( nTable ),
    2166                 :            :     nEndCol( nCol2 ),
    2167                 :            :     nStartRow( nRow1 ),
    2168                 :            :     nEndRow( nRow2 ),
    2169                 :     544775 :     nCol( nCol1 )
    2170                 :            : {
    2171 [ +  - ][ +  - ]:     544775 :     if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] )
         [ +  - ][ +  - ]
    2172                 :     544775 :         pColIter = pDoc->maTabs[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
    2173                 :            :     else
    2174                 :          0 :         pColIter = NULL;
    2175                 :     544775 : }
    2176                 :            : 
    2177                 :     544775 : ScDocAttrIterator::~ScDocAttrIterator()
    2178                 :            : {
    2179                 :     544775 :     delete pColIter;
    2180                 :     544775 : }
    2181                 :            : 
    2182                 :    1093865 : const ScPatternAttr* ScDocAttrIterator::GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 )
    2183                 :            : {
    2184         [ +  + ]:    1641705 :     while ( pColIter )
    2185                 :            :     {
    2186                 :    1096934 :         const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
    2187         [ +  + ]:    1096934 :         if ( pPattern )
    2188                 :            :         {
    2189                 :     549094 :             rCol = nCol;
    2190                 :     549094 :             return pPattern;
    2191                 :            :         }
    2192                 :            : 
    2193                 :     547840 :         delete pColIter;
    2194                 :     547840 :         ++nCol;
    2195         [ +  + ]:     547840 :         if ( nCol <= nEndCol )
    2196                 :       3069 :             pColIter = pDoc->maTabs[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
    2197                 :            :         else
    2198                 :     544771 :             pColIter = NULL;
    2199                 :            :     }
    2200                 :    1093865 :     return NULL;        // is nix mehr
    2201                 :            : }
    2202                 :            : 
    2203                 :            : // ============================================================================
    2204                 :            : 
    2205                 :          0 : ScDocRowHeightUpdater::TabRanges::TabRanges(SCTAB nTab) :
    2206         [ #  # ]:          0 :     mnTab(nTab), mpRanges(new ScFlatBoolRowSegments)
    2207                 :            : {
    2208                 :          0 : }
    2209                 :            : 
    2210                 :         18 : ScDocRowHeightUpdater::ScDocRowHeightUpdater(ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, const vector<TabRanges>* pTabRangesArray) :
    2211                 :         18 :     mrDoc(rDoc), mpOutDev(pOutDev), mfPPTX(fPPTX), mfPPTY(fPPTY), mpTabRangesArray(pTabRangesArray)
    2212                 :            : {
    2213                 :         18 : }
    2214                 :            : 
    2215                 :         18 : void ScDocRowHeightUpdater::update()
    2216                 :            : {
    2217 [ -  + ][ #  # ]:         18 :     if (!mpTabRangesArray || mpTabRangesArray->empty())
                 [ +  - ]
    2218                 :            :     {
    2219                 :            :         // No ranges defined.  Update all rows in all tables.
    2220         [ +  - ]:         18 :         updateAll();
    2221                 :         18 :         return;
    2222                 :            :     }
    2223                 :            : 
    2224                 :          0 :     sal_uInt32 nCellCount = 0;
    2225                 :          0 :     vector<TabRanges>::const_iterator itr = mpTabRangesArray->begin(), itrEnd = mpTabRangesArray->end();
    2226 [ #  # ][ #  # ]:          0 :     for (; itr != itrEnd; ++itr)
    2227                 :            :     {
    2228                 :            :         ScFlatBoolRowSegments::RangeData aData;
    2229         [ #  # ]:          0 :         ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
    2230 [ #  # ][ #  # ]:          0 :         for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
                 [ #  # ]
    2231                 :            :         {
    2232         [ #  # ]:          0 :             if (!aData.mbValue)
    2233                 :          0 :                 continue;
    2234                 :            : 
    2235                 :          0 :             nCellCount += aData.mnRow2 - aData.mnRow1 + 1;
    2236                 :            :         }
    2237                 :            :     }
    2238                 :            : 
    2239 [ #  # ][ #  # ]:          0 :     ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
    2240                 :            : 
    2241         [ #  # ]:          0 :     Fraction aZoom(1, 1);
    2242                 :          0 :     itr = mpTabRangesArray->begin();
    2243                 :          0 :     sal_uInt32 nProgressStart = 0;
    2244 [ #  # ][ #  # ]:          0 :     for (; itr != itrEnd; ++itr)
    2245                 :            :     {
    2246                 :          0 :         SCTAB nTab = itr->mnTab;
    2247 [ #  # ][ #  # ]:          0 :         if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || !mrDoc.maTabs[nTab])
         [ #  # ][ #  # ]
                 [ #  # ]
    2248                 :          0 :             continue;
    2249                 :            : 
    2250                 :            :         ScFlatBoolRowSegments::RangeData aData;
    2251         [ #  # ]:          0 :         ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
    2252 [ #  # ][ #  # ]:          0 :         for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
                 [ #  # ]
    2253                 :            :         {
    2254         [ #  # ]:          0 :             if (!aData.mbValue)
    2255                 :          0 :                 continue;
    2256                 :            : 
    2257                 :          0 :             mrDoc.maTabs[nTab]->SetOptimalHeight(
    2258         [ #  # ]:          0 :                 aData.mnRow1, aData.mnRow2, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
    2259                 :            : 
    2260                 :          0 :             nProgressStart += aData.mnRow2 - aData.mnRow1 + 1;
    2261                 :            :         }
    2262         [ #  # ]:         18 :     }
    2263                 :            : }
    2264                 :            : 
    2265                 :         18 : void ScDocRowHeightUpdater::updateAll()
    2266                 :            : {
    2267                 :         18 :     sal_uInt32 nCellCount = 0;
    2268 [ +  - ][ +  + ]:         36 :     for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
    2269                 :            :     {
    2270 [ +  - ][ -  + ]:         18 :         if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
                 [ -  + ]
    2271                 :          0 :             continue;
    2272                 :            : 
    2273         [ +  - ]:         18 :         nCellCount += mrDoc.maTabs[nTab]->GetWeightedCount();
    2274                 :            :     }
    2275                 :            : 
    2276 [ +  - ][ +  - ]:         18 :     ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
    2277                 :            : 
    2278         [ +  - ]:         18 :     Fraction aZoom(1, 1);
    2279                 :         18 :     sal_uLong nProgressStart = 0;
    2280 [ +  - ][ +  + ]:         36 :     for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
    2281                 :            :     {
    2282 [ +  - ][ -  + ]:         18 :         if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
                 [ -  + ]
    2283                 :          0 :             continue;
    2284                 :            : 
    2285                 :         18 :         mrDoc.maTabs[nTab]->SetOptimalHeight(
    2286         [ +  - ]:         18 :             0, MAXROW, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
    2287                 :            : 
    2288         [ +  - ]:         18 :         nProgressStart += mrDoc.maTabs[nTab]->GetWeightedCount();
    2289         [ +  - ]:         18 :     }
    2290                 :         18 : }
    2291                 :            : 
    2292                 :            : //-------------------------------------------------------------------------------
    2293                 :            : 
    2294                 :         20 : ScAttrRectIterator::ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
    2295                 :            :                                     SCCOL nCol1, SCROW nRow1,
    2296                 :            :                                     SCCOL nCol2, SCROW nRow2) :
    2297                 :            :     pDoc( pDocument ),
    2298                 :            :     nTab( nTable ),
    2299                 :            :     nEndCol( nCol2 ),
    2300                 :            :     nStartRow( nRow1 ),
    2301                 :            :     nEndRow( nRow2 ),
    2302                 :            :     nIterStartCol( nCol1 ),
    2303                 :         20 :     nIterEndCol( nCol1 )
    2304                 :            : {
    2305 [ +  - ][ +  - ]:         20 :     if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] )
         [ +  - ][ +  - ]
    2306                 :            :     {
    2307                 :         20 :         pColIter = pDoc->maTabs[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
    2308   [ +  +  +  + ]:      24610 :         while ( nIterEndCol < nEndCol &&
                 [ +  + ]
    2309                 :      12296 :                 pDoc->maTabs[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
    2310                 :      24592 :                     pDoc->maTabs[nTab]->aCol[nIterEndCol+1], nStartRow, nEndRow ) )
    2311                 :      12294 :             ++nIterEndCol;
    2312                 :            :     }
    2313                 :            :     else
    2314                 :          0 :         pColIter = NULL;
    2315                 :         20 : }
    2316                 :            : 
    2317                 :         20 : ScAttrRectIterator::~ScAttrRectIterator()
    2318                 :            : {
    2319                 :         20 :     delete pColIter;
    2320                 :         20 : }
    2321                 :            : 
    2322                 :          0 : void ScAttrRectIterator::DataChanged()
    2323                 :            : {
    2324         [ #  # ]:          0 :     if (pColIter)
    2325                 :            :     {
    2326                 :          0 :         SCROW nNextRow = pColIter->GetNextRow();
    2327                 :          0 :         delete pColIter;
    2328                 :          0 :         pColIter = pDoc->maTabs[nTab]->aCol[nIterStartCol].CreateAttrIterator( nNextRow, nEndRow );
    2329                 :            :     }
    2330                 :          0 : }
    2331                 :            : 
    2332                 :         61 : const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
    2333                 :            :                                                     SCROW& rRow1, SCROW& rRow2 )
    2334                 :            : {
    2335         [ +  + ]:         88 :     while ( pColIter )
    2336                 :            :     {
    2337                 :         69 :         const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
    2338         [ +  + ]:         69 :         if ( pPattern )
    2339                 :            :         {
    2340                 :         42 :             rCol1 = nIterStartCol;
    2341                 :         42 :             rCol2 = nIterEndCol;
    2342                 :         42 :             return pPattern;
    2343                 :            :         }
    2344                 :            : 
    2345                 :         27 :         delete pColIter;
    2346                 :         27 :         nIterStartCol = nIterEndCol+1;
    2347         [ +  + ]:         27 :         if ( nIterStartCol <= nEndCol )
    2348                 :            :         {
    2349                 :          8 :             nIterEndCol = nIterStartCol;
    2350                 :          8 :             pColIter = pDoc->maTabs[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
    2351   [ +  +  +  + ]:       4090 :             while ( nIterEndCol < nEndCol &&
                 [ +  + ]
    2352                 :       2044 :                     pDoc->maTabs[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
    2353                 :       4088 :                         pDoc->maTabs[nTab]->aCol[nIterEndCol+1], nStartRow, nEndRow ) )
    2354                 :       2038 :                 ++nIterEndCol;
    2355                 :            :         }
    2356                 :            :         else
    2357                 :         19 :             pColIter = NULL;
    2358                 :            :     }
    2359                 :         61 :     return NULL;        // is nix mehr
    2360                 :            : }
    2361                 :            : 
    2362                 :            : // ============================================================================
    2363                 :            : 
    2364                 :            : SCROW ScRowBreakIterator::NOT_FOUND = -1;
    2365                 :            : 
    2366                 :        182 : ScRowBreakIterator::ScRowBreakIterator(set<SCROW>& rBreaks) :
    2367                 :            :     mrBreaks(rBreaks),
    2368                 :        182 :     maItr(rBreaks.begin()), maEnd(rBreaks.end())
    2369                 :            : {
    2370                 :        182 : }
    2371                 :            : 
    2372                 :        182 : SCROW ScRowBreakIterator::first()
    2373                 :            : {
    2374                 :        182 :     maItr = mrBreaks.begin();
    2375         [ -  + ]:        182 :     return maItr == maEnd ? NOT_FOUND : *maItr;
    2376                 :            : }
    2377                 :            : 
    2378                 :          0 : SCROW ScRowBreakIterator::next()
    2379                 :            : {
    2380                 :          0 :     ++maItr;
    2381         [ #  # ]:          0 :     return maItr == maEnd ? NOT_FOUND : *maItr;
    2382                 :            : }
    2383                 :            : 
    2384                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10