LCOV - code coverage report
Current view: top level - libreoffice/sc/source/core/data - markarr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 125 190 65.8 %
Date: 2012-12-27 Functions: 9 14 64.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "markarr.hxx"
      21             : #include "global.hxx"
      22             : #include "address.hxx"
      23             : 
      24             : // STATIC DATA -----------------------------------------------------------
      25             : 
      26             : //------------------------------------------------------------------------
      27             : 
      28       79872 : ScMarkArray::ScMarkArray() :
      29             :     nCount( 0 ),
      30             :     nLimit( 0 ),
      31       79872 :     pData( NULL )
      32             : {
      33             :     // special case "no marks" with pData = NULL
      34       79872 : }
      35             : 
      36             : //------------------------------------------------------------------------
      37             : 
      38       79872 : ScMarkArray::~ScMarkArray()
      39             : {
      40       79872 :     delete[] pData;
      41       79872 : }
      42             : 
      43             : //------------------------------------------------------------------------
      44             : 
      45         418 : void ScMarkArray::Reset( sal_Bool bMarked )
      46             : {
      47             :     // always create pData here
      48             :     // (or have separate method to ensure pData)
      49             : 
      50         418 :     delete[] pData;
      51             : 
      52         418 :     nCount = nLimit = 1;
      53         418 :     pData = new ScMarkEntry[1];
      54         418 :     pData[0].nRow = MAXROW;
      55         418 :     pData[0].bMarked = bMarked;
      56         418 : }
      57             : 
      58             : //------------------------------------------------------------------------
      59             : 
      60        1060 : sal_Bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
      61             : {
      62        1060 :     long    nHi         = static_cast<long>(nCount) - 1;
      63        1060 :     long    i           = 0;
      64        1060 :     sal_Bool    bFound      = (nCount == 1);
      65        1060 :     if (pData)
      66             :     {
      67        1060 :         long    nLo         = 0;
      68        1060 :         long    nStartRow   = 0;
      69        4174 :         while ( !bFound && nLo <= nHi )
      70             :         {
      71        2054 :             i = (nLo + nHi) / 2;
      72        2054 :             if (i > 0)
      73        1460 :                 nStartRow = (long) pData[i - 1].nRow;
      74             :             else
      75         594 :                 nStartRow = -1;
      76        2054 :             long nEndRow = (long) pData[i].nRow;
      77        2054 :             if (nEndRow < (long) nRow)
      78        1123 :                 nLo = ++i;
      79             :             else
      80         931 :                 if (nStartRow >= (long) nRow)
      81           0 :                     nHi = --i;
      82             :                 else
      83         931 :                     bFound = sal_True;
      84             :         }
      85             :     }
      86             :     else
      87           0 :         bFound = false;
      88             : 
      89        1060 :     if (bFound)
      90        1060 :         nIndex=(SCSIZE)i;
      91             :     else
      92           0 :         nIndex=0;
      93        1060 :     return bFound;
      94             : }
      95             : 
      96           0 : sal_Bool ScMarkArray::GetMark( SCROW nRow ) const
      97             : {
      98             :     SCSIZE i;
      99           0 :     if (Search( nRow, i ))
     100           0 :         return pData[i].bMarked;
     101             :     else
     102           0 :         return false;
     103             : 
     104             : }
     105             : 
     106             : //------------------------------------------------------------------------
     107             : 
     108        1429 : void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, sal_Bool bMarked )
     109             : {
     110        1429 :     if (ValidRow(nStartRow) && ValidRow(nEndRow))
     111             :     {
     112        1429 :         if ((nStartRow == 0) && (nEndRow == MAXROW))
     113             :         {
     114           0 :             Reset(bMarked);
     115             :         }
     116             :         else
     117             :         {
     118        1429 :             if (!pData)
     119         418 :                 Reset(false);   // create pData for further processing - could use special case handling!
     120             : 
     121        1429 :             SCSIZE nNeeded = nCount + 2;
     122        1429 :             if ( nLimit < nNeeded )
     123             :             {
     124         494 :                 nLimit += SC_MARKARRAY_DELTA;
     125         494 :                 if ( nLimit < nNeeded )
     126           0 :                     nLimit = nNeeded;
     127         494 :                 ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
     128         494 :                 memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
     129         494 :                 delete[] pData;
     130         494 :                 pData = pNewData;
     131             :             }
     132             : 
     133             :             SCSIZE ni;          // number of entries in beginning
     134             :             SCSIZE nInsert;     // insert position (MAXROW+1 := no insert)
     135        1429 :             sal_Bool bCombined = false;
     136        1429 :             sal_Bool bSplit = false;
     137        1429 :             if ( nStartRow > 0 )
     138             :             {
     139             :                 // skip beginning
     140             :                 SCSIZE nIndex;
     141        1060 :                 Search( nStartRow, nIndex );
     142        1060 :                 ni = nIndex;
     143             : 
     144        1060 :                 nInsert = MAXROWCOUNT;
     145        1060 :                 if ( pData[ni].bMarked != bMarked )
     146             :                 {
     147        1054 :                     if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
     148             :                     {   // may be a split or a simple insert or just a shrink,
     149             :                         // row adjustment is done further down
     150         289 :                         if ( pData[ni].nRow > nEndRow )
     151         286 :                             bSplit = sal_True;
     152         289 :                         ni++;
     153         289 :                         nInsert = ni;
     154             :                     }
     155         765 :                     else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
     156         765 :                         nInsert = ni;
     157             :                 }
     158        1060 :                 if ( ni > 0 && pData[ni-1].bMarked == bMarked )
     159             :                 {   // combine
     160         765 :                     pData[ni-1].nRow = nEndRow;
     161         765 :                     nInsert = MAXROWCOUNT;
     162         765 :                     bCombined = sal_True;
     163             :                 }
     164             :             }
     165             :             else
     166             :         {
     167         369 :                 nInsert = 0;
     168         369 :                 ni = 0;
     169             :         }
     170             : 
     171        1429 :             SCSIZE nj = ni;     // stop position of range to replace
     172        2982 :             while ( nj < nCount && pData[nj].nRow <= nEndRow )
     173         124 :                 nj++;
     174        1429 :             if ( !bSplit )
     175             :             {
     176        1143 :                 if ( nj < nCount && pData[nj].bMarked == bMarked )
     177             :                 {   // combine
     178           0 :                     if ( ni > 0 )
     179             :                     {
     180           0 :                         if ( pData[ni-1].bMarked == bMarked )
     181             :                         {   // adjacent entries
     182           0 :                             pData[ni-1].nRow = pData[nj].nRow;
     183           0 :                             nj++;
     184             :                         }
     185           0 :                         else if ( ni == nInsert )
     186           0 :                             pData[ni-1].nRow = nStartRow - 1;   // shrink
     187             :                     }
     188           0 :                     nInsert = MAXROWCOUNT;
     189           0 :                     bCombined = sal_True;
     190             :                 }
     191        1143 :                 else if ( ni > 0 && ni == nInsert )
     192           3 :                     pData[ni-1].nRow = nStartRow - 1;   // shrink
     193             :             }
     194        1429 :             if ( ni < nj )
     195             :             {   // remove middle entries
     196         124 :                 if ( !bCombined )
     197             :                 {   // replace one entry
     198          86 :                     pData[ni].nRow = nEndRow;
     199          86 :                     pData[ni].bMarked = bMarked;
     200          86 :                     ni++;
     201          86 :                     nInsert = MAXROWCOUNT;
     202             :                 }
     203         124 :                 if ( ni < nj )
     204             :                 {   // remove entries
     205          38 :                     memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
     206          38 :                     nCount -= nj - ni;
     207             :                 }
     208             :             }
     209             : 
     210        1429 :             if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
     211             :             {   // insert or append new entry
     212         578 :                 if ( nInsert <= nCount )
     213             :                 {
     214         578 :                     if ( !bSplit )
     215         292 :                         memmove( pData + nInsert + 1, pData + nInsert,
     216         584 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     217             :                     else
     218             :                     {
     219         286 :                         memmove( pData + nInsert + 2, pData + nInsert,
     220         572 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     221         286 :                         pData[nInsert+1] = pData[nInsert-1];
     222         286 :                         nCount++;
     223             :                     }
     224             :                 }
     225         578 :                 if ( nInsert )
     226         289 :                     pData[nInsert-1].nRow = nStartRow - 1;
     227         578 :                 pData[nInsert].nRow = nEndRow;
     228         578 :                 pData[nInsert].bMarked = bMarked;
     229         578 :                 nCount++;
     230             :             }
     231             :         }
     232             :     }
     233        1429 : }
     234             : 
     235           0 : sal_Bool ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
     236             : {
     237             :     SCSIZE nStartIndex;
     238             :     SCSIZE nEndIndex;
     239             : 
     240           0 :     if (Search( nStartRow, nStartIndex ))
     241           0 :         if (pData[nStartIndex].bMarked)
     242           0 :             if (Search( nEndRow, nEndIndex ))
     243           0 :                 if (nEndIndex==nStartIndex)
     244           0 :                     return sal_True;
     245             : 
     246           0 :     return false;
     247             : }
     248             : 
     249           6 : sal_Bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
     250             : {
     251           6 :     sal_Bool bRet = false;
     252           6 :     if ( nCount == 1 )
     253             :     {
     254           0 :         if ( pData[0].bMarked )
     255             :         {
     256           0 :             rStartRow = 0;
     257           0 :             rEndRow = MAXROW;
     258           0 :             bRet = sal_True;
     259             :         }
     260             :     }
     261           6 :     else if ( nCount == 2 )
     262             :     {
     263           0 :         if ( pData[0].bMarked )
     264             :         {
     265           0 :             rStartRow = 0;
     266           0 :             rEndRow = pData[0].nRow;
     267             :         }
     268             :         else
     269             :         {
     270           0 :             rStartRow = pData[0].nRow + 1;
     271           0 :             rEndRow = MAXROW;
     272             :         }
     273           0 :         bRet = sal_True;
     274             :     }
     275           6 :     else if ( nCount == 3 )
     276             :     {
     277           6 :         if ( pData[1].bMarked )
     278             :         {
     279           6 :             rStartRow = pData[0].nRow + 1;
     280           6 :             rEndRow = pData[1].nRow;
     281           6 :             bRet = sal_True;
     282             :         }
     283             :     }
     284           6 :     return bRet;
     285             : }
     286             : 
     287           0 : void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
     288             : {
     289           0 :     delete[] rDestMarkArray.pData;
     290             : 
     291           0 :     if (pData)
     292             :     {
     293           0 :         rDestMarkArray.pData = new ScMarkEntry[nCount];
     294           0 :         memcpy( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
     295             :     }
     296             :     else
     297           0 :         rDestMarkArray.pData = NULL;
     298             : 
     299           0 :     rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
     300           0 : }
     301             : 
     302           0 : SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, sal_Bool bUp ) const
     303             : {
     304           0 :     if (!pData)
     305           0 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     306             : 
     307           0 :     SCsROW nRet = nRow;
     308           0 :     if (VALIDROW(nRow))
     309             :     {
     310             :         SCSIZE nIndex;
     311           0 :         Search(nRow, nIndex);
     312           0 :         if (!pData[nIndex].bMarked)
     313             :         {
     314           0 :             if (bUp)
     315             :             {
     316           0 :                 if (nIndex>0)
     317           0 :                     nRet = pData[nIndex-1].nRow;
     318             :                 else
     319           0 :                     nRet = -1;
     320             :             }
     321             :             else
     322           0 :                 nRet = pData[nIndex].nRow + 1;
     323             :         }
     324             :     }
     325           0 :     return nRet;
     326             : }
     327             : 
     328           0 : SCROW ScMarkArray::GetMarkEnd( SCROW nRow, sal_Bool bUp ) const
     329             : {
     330           0 :     if (!pData)
     331           0 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     332             : 
     333             :     SCROW nRet;
     334             :     SCSIZE nIndex;
     335           0 :     Search(nRow, nIndex);
     336             :     OSL_ENSURE( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
     337           0 :     if (bUp)
     338             :     {
     339           0 :         if (nIndex>0)
     340           0 :             nRet = pData[nIndex-1].nRow + 1;
     341             :         else
     342           0 :             nRet = 0;
     343             :     }
     344             :     else
     345           0 :         nRet = pData[nIndex].nRow;
     346             : 
     347           0 :     return nRet;
     348             : }
     349             : 
     350             : //
     351             : //  -------------- Iterator ----------------------------------------------
     352             : //
     353             : 
     354       92327 : ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
     355             :     pArray( pNewArray ),
     356       92327 :     nPos( 0 )
     357             : {
     358       92327 : }
     359             : 
     360       92327 : ScMarkArrayIter::~ScMarkArrayIter()
     361             : {
     362       92327 : }
     363             : 
     364       93067 : sal_Bool ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
     365             : {
     366       93067 :     if ( nPos >= pArray->nCount )
     367       91785 :         return false;
     368        3017 :     while (!pArray->pData[nPos].bMarked)
     369             :     {
     370         928 :         ++nPos;
     371         928 :         if ( nPos >= pArray->nCount )
     372         475 :             return false;
     373             :     }
     374         807 :     rBottom = pArray->pData[nPos].nRow;
     375         807 :     if (nPos==0)
     376         354 :         rTop = 0;
     377             :     else
     378         453 :         rTop = pArray->pData[nPos-1].nRow + 1;
     379         807 :     ++nPos;
     380         807 :     return sal_True;
     381             : }
     382             : 
     383             : 
     384             : 
     385             : 
     386             : 
     387             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10