LCOV - code coverage report
Current view: top level - sc/source/core/data - olinetab.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 297 474 62.7 %
Date: 2014-11-03 Functions: 41 57 71.9 %
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 <limits.h>
      21             : 
      22             : #include "olinetab.hxx"
      23             : #include "global.hxx"
      24             : #include "rechead.hxx"
      25             : #include "address.hxx"
      26             : #include "table.hxx"
      27             : 
      28          64 : ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
      29             :     nStart  ( nNewStart ),
      30             :     nSize   ( nNewSize ),
      31             :     bHidden ( bNewHidden ),
      32          64 :     bVisible( true )
      33             : {
      34          64 : }
      35             : 
      36         546 : ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
      37             :     nStart  ( rEntry.nStart ),
      38             :     nSize   ( rEntry.nSize ),
      39             :     bHidden ( rEntry.bHidden ),
      40         546 :     bVisible( rEntry.bVisible )
      41             : {
      42         546 : }
      43             : 
      44        1069 : SCCOLROW ScOutlineEntry::GetEnd() const
      45             : {
      46        1069 :     return nStart+nSize-1;
      47             : }
      48             : 
      49           0 : void ScOutlineEntry::Move( SCsCOLROW nDelta )
      50             : {
      51           0 :     SCCOLROW nNewPos = nStart + nDelta;
      52           0 :     if (nNewPos<0)
      53             :     {
      54             :         OSL_FAIL("OutlineEntry < 0");
      55           0 :         nNewPos = 0;
      56             :     }
      57           0 :     nStart = nNewPos;
      58           0 : }
      59             : 
      60           0 : void ScOutlineEntry::SetSize( SCSIZE nNewSize )
      61             : {
      62           0 :     if (nNewSize>0)
      63           0 :         nSize = nNewSize;
      64             :     else
      65             :     {
      66             :         OSL_FAIL("ScOutlineEntry Size == 0");
      67             :     }
      68           0 : }
      69             : 
      70           0 : void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
      71             : {
      72           0 :     nStart = nNewPos;
      73           0 :     SetSize( nNewSize );
      74           0 : }
      75             : 
      76         118 : void ScOutlineEntry::SetHidden( bool bNewHidden )
      77             : {
      78         118 :     bHidden = bNewHidden;
      79         118 : }
      80             : 
      81         200 : void ScOutlineEntry::SetVisible( bool bNewVisible )
      82             : {
      83         200 :     bVisible = bNewVisible;
      84         200 : }
      85             : 
      86        8960 : ScOutlineCollection::ScOutlineCollection() {}
      87             : 
      88         719 : size_t ScOutlineCollection::size() const
      89             : {
      90         719 :     return maEntries.size();
      91             : }
      92             : 
      93           4 : void ScOutlineCollection::clear()
      94             : {
      95           4 :     maEntries.clear();
      96           4 : }
      97             : 
      98         610 : void ScOutlineCollection::insert(ScOutlineEntry* pEntry)
      99             : {
     100         610 :     SCCOLROW nStart = pEntry->GetStart();
     101         610 :     maEntries.insert(nStart, pEntry);
     102         610 : }
     103             : 
     104         856 : ScOutlineCollection::iterator ScOutlineCollection::begin()
     105             : {
     106         856 :     return maEntries.begin();
     107             : }
     108             : 
     109         434 : ScOutlineCollection::iterator ScOutlineCollection::end()
     110             : {
     111         434 :     return maEntries.end();
     112             : }
     113             : 
     114         770 : ScOutlineCollection::const_iterator ScOutlineCollection::begin() const
     115             : {
     116         770 :     return maEntries.begin();
     117             : }
     118             : 
     119         700 : ScOutlineCollection::const_iterator ScOutlineCollection::end() const
     120             : {
     121         700 :     return maEntries.end();
     122             : }
     123             : 
     124          64 : void ScOutlineCollection::erase(iterator pos)
     125             : {
     126          64 :     maEntries.erase(pos);
     127          64 : }
     128             : 
     129         110 : bool ScOutlineCollection::empty() const
     130             : {
     131         110 :     return maEntries.empty();
     132             : }
     133             : 
     134           8 : ScOutlineCollection::iterator ScOutlineCollection::FindStart(SCCOLROW nMinStart)
     135             : {
     136           8 :     return maEntries.lower_bound(nMinStart);
     137             : }
     138             : 
     139         848 : ScOutlineArray::ScOutlineArray() :
     140         848 :     nDepth(0) {}
     141             : 
     142         432 : ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
     143         432 :     nDepth( rArray.nDepth )
     144             : {
     145         898 :     for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
     146             :     {
     147         466 :         const ScOutlineCollection& rColl = rArray.aCollections[nLevel];
     148         466 :         ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
     149         956 :         for (; it != itEnd; ++it)
     150             :         {
     151         490 :             const ScOutlineEntry* pEntry = it->second;
     152         490 :             aCollections[nLevel].insert(new ScOutlineEntry(*pEntry));
     153             :         }
     154             :     }
     155         432 : }
     156             : 
     157         134 : void ScOutlineArray::FindEntry(
     158             :     SCCOLROW nSearchPos, size_t& rFindLevel, size_t& rFindIndex,
     159             :     size_t nMaxLevel )
     160             : {
     161         134 :     rFindLevel = rFindIndex = 0;
     162             : 
     163         134 :     if (nMaxLevel > nDepth)
     164         128 :         nMaxLevel = nDepth;
     165             : 
     166         318 :     for (size_t nLevel = 0; nLevel < nMaxLevel; ++nLevel) //TODO: Search backwards?
     167             :     {
     168         184 :         ScOutlineCollection* pCollect = &aCollections[nLevel];
     169         184 :         ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
     170         372 :         for (; it != itEnd; ++it)
     171             :         {
     172         188 :             ScOutlineEntry* pEntry = it->second;
     173         188 :             if (pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos)
     174             :             {
     175          14 :                 rFindLevel = nLevel + 1; // Next Level (for insertion)
     176          14 :                 rFindIndex = std::distance(pCollect->begin(), it);
     177             :             }
     178             :         }
     179             :     }
     180         134 : }
     181             : 
     182          64 : bool ScOutlineArray::Insert(
     183             :     SCCOLROW nStartCol, SCCOLROW nEndCol, bool& rSizeChanged, bool bHidden, bool bVisible )
     184             : {
     185          64 :     rSizeChanged = false;
     186             : 
     187             :     size_t nStartLevel, nEndLevel, nStartIndex, nEndIndex;
     188          64 :     bool bFound = false;
     189             : 
     190             :     bool bCont;
     191             :     sal_uInt16 nFindMax;
     192          64 :     FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = new Level (old+1)
     193          64 :     FindEntry( nEndCol, nEndLevel, nEndIndex );
     194          64 :     nFindMax = std::max(nStartLevel,nEndLevel);
     195          70 :     do
     196             :     {
     197          70 :         bCont = false;
     198             : 
     199          70 :         if (nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH)
     200          64 :             bFound = true;
     201             : 
     202          70 :         if (!bFound)
     203             :         {
     204           6 :             if (nFindMax>0)
     205             :             {
     206           6 :                 --nFindMax;
     207           6 :                 if (nStartLevel)
     208             :                 {
     209           6 :                     ScOutlineCollection::const_iterator it = aCollections[nStartLevel-1].begin();
     210           6 :                     std::advance(it, nStartIndex);
     211           6 :                     if (it->second->GetStart() == nStartCol)
     212           6 :                         FindEntry(nStartCol, nStartLevel, nStartIndex, nFindMax);
     213             :                 }
     214             : 
     215           6 :                 if (nEndLevel)
     216             :                 {
     217           0 :                     ScOutlineCollection::const_iterator it = aCollections[nEndLevel-1].begin();
     218           0 :                     std::advance(it, nEndIndex);
     219           0 :                     if (it->second->GetEnd() == nEndCol)
     220           0 :                         FindEntry(nEndCol, nEndLevel, nEndIndex, nFindMax);
     221             :                 }
     222           6 :                 bCont = true;
     223             :             }
     224             :         }
     225             :     }
     226          76 :     while ( !bFound && bCont );
     227             : 
     228          64 :     if (!bFound)
     229           0 :         return false;
     230             : 
     231          64 :     size_t nLevel = nStartLevel;
     232             : 
     233             :     // Move the ones underneath
     234          64 :     bool bNeedSize = false;
     235          64 :     if (nDepth > 0)
     236             :     {
     237          92 :         for (size_t nMoveLevel = nDepth-1; nMoveLevel >= nLevel; --nMoveLevel)
     238             :         {
     239          88 :             ScOutlineCollection& rColl = aCollections[nMoveLevel];
     240          88 :             ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
     241         266 :             while (it != itEnd)
     242             :             {
     243          90 :                 ScOutlineEntry* pEntry = it->second;
     244          90 :                 SCCOLROW nEntryStart = pEntry->GetStart();
     245          90 :                 if (nEntryStart >= nStartCol && nEntryStart <= nEndCol)
     246             :                 {
     247          56 :                     if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
     248             :                     {
     249           0 :                         rSizeChanged = false; // No more room
     250           0 :                         return false;
     251             :                     }
     252          56 :                     aCollections[nMoveLevel+1].insert(new ScOutlineEntry(*pEntry));
     253          56 :                     size_t nPos = std::distance(rColl.begin(), it);
     254          56 :                     rColl.erase(it);
     255          56 :                     it = rColl.begin();
     256          56 :                     std::advance(it, nPos);
     257          56 :                     itEnd = rColl.end();
     258          56 :                     if (nMoveLevel == nDepth - 1)
     259          32 :                         bNeedSize = true;
     260             :                 }
     261             :                 else
     262          34 :                     ++it;
     263             :             }
     264          88 :             if (nMoveLevel == 0)
     265          40 :                 break;
     266             :         }
     267             :     }
     268             : 
     269          64 :     if (bNeedSize)
     270             :     {
     271          30 :         ++nDepth;
     272          30 :         rSizeChanged = true;
     273             :     }
     274             : 
     275          64 :     if (nDepth <= nLevel)
     276             :     {
     277          24 :         nDepth = nLevel+1;
     278          24 :         rSizeChanged = true;
     279             :     }
     280             : 
     281          64 :     ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
     282          64 :     pNewEntry->SetVisible( bVisible );
     283          64 :     aCollections[nLevel].insert(pNewEntry);
     284             : 
     285          64 :     return true;
     286             : }
     287             : 
     288        6896 : bool ScOutlineArray::FindTouchedLevel(
     289             :     SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rFindLevel) const
     290             : {
     291        6896 :     bool bFound = false;
     292        6896 :     rFindLevel = 0;
     293             : 
     294        7082 :     for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
     295             :     {
     296         186 :         const ScOutlineCollection* pCollect = &aCollections[nLevel];
     297         186 :         ScOutlineCollection::const_iterator it = pCollect->begin(), itEnd = pCollect->end();
     298         388 :         for (; it != itEnd; ++it)
     299             :         {
     300         202 :             const ScOutlineEntry* pEntry = it->second;
     301         202 :             SCCOLROW nStart = pEntry->GetStart();
     302         202 :             SCCOLROW nEnd   = pEntry->GetEnd();
     303             : 
     304         202 :             if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
     305          74 :                  ( nBlockEnd  >=nStart && nBlockEnd  <=nEnd ) )
     306             :             {
     307          52 :                 rFindLevel = nLevel; // Actual Level
     308          52 :                 bFound = true;
     309             :             }
     310             :         }
     311             :     }
     312             : 
     313        6896 :     return bFound;
     314             : }
     315             : 
     316           0 : void ScOutlineArray::RemoveSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nLevel)
     317             : {
     318           0 :     if ( nLevel >= nDepth )
     319           0 :         return;
     320             : 
     321           0 :     ScOutlineCollection& rColl = aCollections[nLevel];
     322             : 
     323           0 :     ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
     324           0 :     while (it != itEnd)
     325             :     {
     326           0 :         ScOutlineEntry* pEntry = it->second;
     327           0 :         SCCOLROW nStart = pEntry->GetStart();
     328           0 :         SCCOLROW nEnd   = pEntry->GetEnd();
     329           0 :         if (nStart >= nStartPos && nEnd <= nEndPos)
     330             :         {
     331             :             // Overlaps
     332           0 :             RemoveSub( nStart, nEnd, nLevel+1 );
     333             : 
     334             :             // Re-calc iterator positions after the tree gets invalidated
     335           0 :             size_t nPos = std::distance(rColl.begin(), it);
     336           0 :             rColl.erase(it);
     337           0 :             it = rColl.begin();
     338           0 :             std::advance(it, nPos);
     339           0 :             itEnd = rColl.end();
     340             :         }
     341             :         else
     342           0 :             ++it;
     343             :     }
     344             : 
     345           0 :     it = rColl.begin();
     346           0 :     itEnd = rColl.end();
     347             : 
     348           0 :     while (it != itEnd)
     349             :     {
     350           0 :         ScOutlineEntry* pEntry = it->second;
     351           0 :         SCCOLROW nStart = pEntry->GetStart();
     352           0 :         SCCOLROW nEnd   = pEntry->GetEnd();
     353             : 
     354           0 :         if (nStart >= nStartPos && nEnd <= nEndPos)
     355             :         {
     356           0 :             RemoveSub( nStart, nEnd, nLevel+1 );
     357             : 
     358             :             // Re-calc iterator positions after the tree gets invalidated
     359           0 :             size_t nPos = std::distance(rColl.begin(), it);
     360           0 :             rColl.erase(it);
     361           0 :             it = rColl.begin();
     362           0 :             std::advance(it, nPos);
     363           0 :             itEnd = rColl.end();
     364             :         }
     365             :         else
     366           0 :             ++it;
     367             :     }
     368             : }
     369             : 
     370           8 : void ScOutlineArray::PromoteSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nStartLevel)
     371             : {
     372           8 :     if (nStartLevel==0)
     373             :     {
     374             :         OSL_FAIL("PromoteSub with Level 0");
     375           8 :         return;
     376             :     }
     377             : 
     378          20 :     for (size_t nLevel = nStartLevel; nLevel < nDepth; ++nLevel)
     379             :     {
     380          12 :         ScOutlineCollection& rColl = aCollections[nLevel];
     381          12 :         ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
     382          36 :         while (it != itEnd)
     383             :         {
     384          12 :             ScOutlineEntry* pEntry = it->second;
     385          12 :             SCCOLROW nStart = pEntry->GetStart();
     386          12 :             SCCOLROW nEnd   = pEntry->GetEnd();
     387          12 :             if (nStart >= nStartPos && nEnd <= nEndPos)
     388             :             {
     389           0 :                 aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
     390             : 
     391             :                 // Re-calc iterator positions after the tree gets invalidated
     392           0 :                 size_t nPos = std::distance(rColl.begin(), it);
     393           0 :                 rColl.erase(it);
     394           0 :                 it = rColl.begin();
     395           0 :                 std::advance(it, nPos);
     396           0 :                 itEnd = rColl.end();
     397             :             }
     398             :             else
     399          12 :                 ++it;
     400             :         }
     401             : 
     402          12 :         it = rColl.begin();
     403          12 :         itEnd = rColl.end();
     404             : 
     405          36 :         while (it != itEnd)
     406             :         {
     407          12 :             ScOutlineEntry* pEntry = it->second;
     408          12 :             SCCOLROW nStart = pEntry->GetStart();
     409          12 :             SCCOLROW nEnd   = pEntry->GetEnd();
     410          12 :             if (nStart >= nStartPos && nEnd <= nEndPos)
     411             :             {
     412           0 :                 aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
     413             : 
     414             :                 // Re-calc iterator positions after the tree gets invalidated
     415           0 :                 size_t nPos = std::distance(rColl.begin(), it);
     416           0 :                 rColl.erase(it);
     417           0 :                 it = rColl.begin();
     418           0 :                 std::advance(it, nPos);
     419           0 :                 itEnd = rColl.end();
     420             :             }
     421             :             else
     422          12 :                 ++it;
     423             :         }
     424             :     }
     425             : }
     426             : 
     427             : /**
     428             :  * Adapt nDepth for empty Levels
     429             :  */
     430           8 : bool ScOutlineArray::DecDepth()
     431             : {
     432           8 :     bool bChanged = false;
     433             :     bool bCont;
     434          12 :     do
     435             :     {
     436          12 :         bCont = false;
     437          12 :         if (nDepth)
     438             :         {
     439          10 :             if (aCollections[nDepth-1].empty())
     440             :             {
     441           4 :                 --nDepth;
     442           4 :                 bChanged = true;
     443           4 :                 bCont = true;
     444             :             }
     445             :         }
     446             :     }
     447             :     while (bCont);
     448             : 
     449           8 :     return bChanged;
     450             : }
     451             : 
     452           8 : bool ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, bool& rSizeChanged )
     453             : {
     454             :     size_t nLevel;
     455           8 :     FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
     456             : 
     457           8 :     ScOutlineCollection* pCollect = &aCollections[nLevel];
     458           8 :     ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
     459           8 :     bool bAny = false;
     460          28 :     while (it != itEnd)
     461             :     {
     462          12 :         ScOutlineEntry* pEntry = it->second;
     463          12 :         SCCOLROW nStart = pEntry->GetStart();
     464          12 :         SCCOLROW nEnd   = pEntry->GetEnd();
     465          12 :         if (nBlockStart <= nEnd && nBlockEnd >= nStart)
     466             :         {
     467             :             // Overlaps
     468           8 :             pCollect->erase(it);
     469           8 :             PromoteSub( nStart, nEnd, nLevel+1 );
     470           8 :             itEnd = pCollect->end();
     471           8 :             it = pCollect->FindStart( nEnd+1 );
     472           8 :             bAny = true;
     473             :         }
     474             :         else
     475           4 :             ++it;
     476             :     }
     477             : 
     478           8 :     if (bAny) // Adapt Depth
     479           8 :         if (DecDepth())
     480           4 :             rSizeChanged = true;
     481             : 
     482           8 :     return bAny;
     483             : }
     484             : 
     485         144 : ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex)
     486             : {
     487         144 :     if (nLevel >= nDepth)
     488           0 :         return NULL;
     489             : 
     490         144 :     ScOutlineCollection& rColl = aCollections[nLevel];
     491         144 :     if (nIndex >= rColl.size())
     492           0 :         return NULL;
     493             : 
     494         144 :     ScOutlineCollection::iterator it = rColl.begin();
     495         144 :     std::advance(it, nIndex);
     496         144 :     return it->second;
     497             : }
     498             : 
     499          50 : const ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex) const
     500             : {
     501          50 :     if (nLevel >= nDepth)
     502           0 :         return NULL;
     503             : 
     504          50 :     const ScOutlineCollection& rColl = aCollections[nLevel];
     505          50 :     if (nIndex >= rColl.size())
     506           0 :         return NULL;
     507             : 
     508          50 :     ScOutlineCollection::const_iterator it = rColl.begin();
     509          50 :     std::advance(it, nIndex);
     510          50 :     return it->second;
     511             : }
     512             : 
     513          93 : size_t ScOutlineArray::GetCount(size_t nLevel) const
     514             : {
     515          93 :     if (nLevel >= nDepth)
     516           2 :         return 0;
     517             : 
     518          91 :     return aCollections[nLevel].size();
     519             : }
     520             : 
     521        7162 : const ScOutlineEntry* ScOutlineArray::GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
     522             : {
     523        7162 :     if (nLevel >= nDepth)
     524        7156 :         return NULL;
     525             : 
     526           6 :     const ScOutlineCollection& rColl = aCollections[nLevel];
     527           6 :     ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
     528           6 :     for (; it != itEnd; ++it)
     529             :     {
     530           6 :         const ScOutlineEntry* pEntry = it->second;
     531           6 :         if (pEntry->GetStart() <= nPos && nPos <= pEntry->GetEnd())
     532           6 :             return pEntry;
     533             :     }
     534             : 
     535           0 :     return NULL;
     536             : }
     537             : 
     538           0 : bool ScOutlineArray::GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t& rnIndex) const
     539             : {
     540           0 :     if (nLevel >= nDepth)
     541           0 :         return false;
     542             : 
     543             :     // Found entry contains passed position
     544           0 :     const ScOutlineCollection& rColl = aCollections[nLevel];
     545           0 :     ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
     546           0 :     for (; it != itEnd; ++it)
     547             :     {
     548           0 :         const ScOutlineEntry* p = it->second;
     549           0 :         if (p->GetStart() <= nPos && nPos <= p->GetEnd())
     550             :         {
     551           0 :             rnIndex = std::distance(rColl.begin(), it);
     552           0 :             return true;
     553             :         }
     554             :     }
     555           0 :     return false;
     556             : }
     557             : 
     558           0 : bool ScOutlineArray::GetEntryIndexInRange(
     559             :     size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rnIndex) const
     560             : {
     561           0 :     if (nLevel >= nDepth)
     562           0 :         return false;
     563             : 
     564             :     // Found entry will be completely inside of passed range
     565           0 :     const ScOutlineCollection& rColl = aCollections[nLevel];
     566           0 :     ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
     567           0 :     for (; it != itEnd; ++it)
     568             :     {
     569           0 :         const ScOutlineEntry* p = it->second;
     570           0 :         if (nBlockStart <= p->GetStart() && p->GetEnd() <= nBlockEnd)
     571             :         {
     572           0 :             rnIndex = std::distance(rColl.begin(), it);
     573           0 :             return true;
     574             :         }
     575             :     }
     576           0 :     return false;
     577             : }
     578             : 
     579          32 : void ScOutlineArray::SetVisibleBelow(
     580             :     size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden)
     581             : {
     582          32 :     const ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
     583          32 :     if (!pEntry)
     584          32 :         return;
     585             : 
     586          32 :     SCCOLROW nStart = pEntry->GetStart();
     587          32 :     SCCOLROW nEnd   = pEntry->GetEnd();
     588             : 
     589          98 :     for (size_t nSubLevel = nLevel+1; nSubLevel < nDepth; ++nSubLevel)
     590             :     {
     591          66 :         ScOutlineCollection& rColl = aCollections[nSubLevel];
     592          66 :         ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
     593         134 :         for (; it != itEnd; ++it)
     594             :         {
     595          68 :             ScOutlineEntry* p = it->second;
     596          68 :             if (p->GetStart() >= nStart && p->GetEnd() <= nEnd)
     597             :             {
     598          44 :                 p->SetVisible(bValue);
     599          44 :                 if (bSkipHidden && !p->IsHidden())
     600             :                 {
     601           0 :                     size_t nPos = std::distance(rColl.begin(), it);
     602           0 :                     SetVisibleBelow(nSubLevel, nPos, bValue, true);
     603             :                 }
     604             :             }
     605             :         }
     606             : 
     607          66 :         if (bSkipHidden)
     608           0 :             nSubLevel = nDepth; // Bail out
     609             :     }
     610             : }
     611             : 
     612         100 : void ScOutlineArray::GetRange(SCCOLROW& rStart, SCCOLROW& rEnd) const
     613             : {
     614         100 :     const ScOutlineCollection& rColl = aCollections[0];
     615         100 :     if (!rColl.empty())
     616             :     {
     617          20 :         ScOutlineCollection::const_iterator it = rColl.begin();
     618          20 :         rStart = it->second->GetStart();
     619          20 :         std::advance(it, rColl.size()-1);
     620          20 :         rEnd = it->second->GetEnd();
     621             :     }
     622             :     else
     623          80 :         rStart = rEnd = 0;
     624         100 : }
     625             : 
     626          44 : void ScOutlineArray::ExtendBlock(size_t nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd)
     627             : {
     628          44 :     if (nLevel >= nDepth)
     629          46 :         return;
     630             : 
     631          42 :     const ScOutlineCollection& rColl = aCollections[nLevel];
     632          42 :     ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
     633          94 :     for (; it != itEnd; ++it)
     634             :     {
     635          52 :         const ScOutlineEntry* pEntry = it->second;
     636          52 :         SCCOLROW nStart = pEntry->GetStart();
     637          52 :         SCCOLROW nEnd   = pEntry->GetEnd();
     638             : 
     639          52 :         if (rBlkStart <= nEnd && rBlkEnd >= nStart)
     640             :         {
     641          28 :             if (nStart < rBlkStart)
     642           0 :                 rBlkStart = nStart;
     643          28 :             if (nEnd > rBlkEnd)
     644           6 :                 rBlkEnd = nEnd;
     645             :         }
     646             :     }
     647             : }
     648             : 
     649           0 : bool ScOutlineArray::TestInsertSpace(SCSIZE nSize, SCCOLROW nMaxVal) const
     650             : {
     651           0 :     const ScOutlineCollection& rColl = aCollections[0];
     652           0 :     if (rColl.empty())
     653           0 :         return true;
     654             : 
     655           0 :     ScOutlineCollection::const_iterator it = rColl.begin();
     656           0 :     std::advance(it, rColl.size()-1);
     657           0 :     SCCOLROW nEnd = it->second->GetEnd();
     658           0 :     return sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal;
     659             : }
     660             : 
     661           0 : void ScOutlineArray::InsertSpace(SCCOLROW nStartPos, SCSIZE nSize)
     662             : {
     663           0 :     ScSubOutlineIterator aIter( this );
     664             :     ScOutlineEntry* pEntry;
     665           0 :     while ((pEntry = aIter.GetNext()) != NULL)
     666             :     {
     667           0 :         if ( pEntry->GetStart() >= nStartPos )
     668           0 :             pEntry->Move(static_cast<SCsCOLROW>(nSize));
     669             :         else
     670             :         {
     671           0 :             SCCOLROW nEnd = pEntry->GetEnd();
     672             :             // Always expand if inserted within the group
     673             :             // When inserting at the end, only if the group is not hidden
     674           0 :             if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
     675             :             {
     676           0 :                 SCSIZE nEntrySize = pEntry->GetSize();
     677           0 :                 nEntrySize += nSize;
     678           0 :                 pEntry->SetSize( nEntrySize );
     679             :             }
     680             :         }
     681             :     }
     682           0 : }
     683             : 
     684           4 : bool ScOutlineArray::DeleteSpace(SCCOLROW nStartPos, SCSIZE nSize)
     685             : {
     686           4 :     SCCOLROW nEndPos = nStartPos + nSize - 1;
     687           4 :     bool bNeedSave = false; // Do we need the original one for Undo?
     688           4 :     bool bChanged = false; // For Level test
     689             : 
     690           4 :     ScSubOutlineIterator aIter( this );
     691             :     ScOutlineEntry* pEntry;
     692           8 :     while((pEntry=aIter.GetNext())!=NULL)
     693             :     {
     694           0 :         SCCOLROW nEntryStart = pEntry->GetStart();
     695           0 :         SCCOLROW nEntryEnd   = pEntry->GetEnd();
     696           0 :         SCSIZE nEntrySize    = pEntry->GetSize();
     697             : 
     698           0 :         if ( nEntryEnd >= nStartPos )
     699             :         {
     700           0 :             if ( nEntryStart > nEndPos ) // Right
     701           0 :                 pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
     702           0 :             else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // Outside
     703           0 :                 pEntry->SetSize( nEntrySize-nSize );
     704             :             else
     705             :             {
     706           0 :                 bNeedSave = true;
     707           0 :                 if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // Inside
     708             :                 {
     709           0 :                     aIter.DeleteLast();
     710           0 :                     bChanged = true;
     711             :                 }
     712           0 :                 else if ( nEntryStart >= nStartPos ) // Top right
     713           0 :                     pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
     714             :                 else // Top left
     715           0 :                     pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
     716             :             }
     717             :         }
     718             :     }
     719             : 
     720           4 :     if (bChanged)
     721           0 :         DecDepth();
     722             : 
     723           4 :     return bNeedSave;
     724             : }
     725             : 
     726         122 : bool ScOutlineArray::ManualAction(
     727             :     SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, const ScTable& rTable, bool bCol)
     728             : {
     729         122 :     bool bModified = false;
     730         122 :     ScSubOutlineIterator aIter( this );
     731             :     ScOutlineEntry* pEntry;
     732         268 :     while((pEntry=aIter.GetNext())!=NULL)
     733             :     {
     734          24 :         SCCOLROW nEntryStart = pEntry->GetStart();
     735          24 :         SCCOLROW nEntryEnd   = pEntry->GetEnd();
     736             : 
     737          24 :         if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
     738             :         {
     739           0 :             if ( pEntry->IsHidden() == bShow )
     740             :             {
     741             :                 // #i12341# hide if all columns/rows are hidden, show if at least one
     742             :                 // is visible
     743           0 :                 SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
     744           0 :                 bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
     745           0 :                         ::std::numeric_limits<SCCOLROW>::max());
     746             : 
     747           0 :                 bool bToggle = ( bShow != bAllHidden );
     748           0 :                 if ( bToggle )
     749             :                 {
     750           0 :                     pEntry->SetHidden( !bShow );
     751           0 :                     SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
     752           0 :                     bModified = true;
     753             :                 }
     754             :             }
     755             :         }
     756             :     }
     757         122 :     return bModified;
     758             : }
     759             : 
     760           2 : void ScOutlineArray::RemoveAll()
     761             : {
     762           6 :     for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
     763           4 :         aCollections[nLevel].clear();
     764             : 
     765           2 :     nDepth = 0;
     766           2 : }
     767             : 
     768         424 : ScOutlineTable::ScOutlineTable()
     769             : {
     770         424 : }
     771             : 
     772         216 : ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
     773             :     aColOutline( rOutline.aColOutline ),
     774         216 :     aRowOutline( rOutline.aRowOutline )
     775             : {
     776         216 : }
     777             : 
     778           0 : bool ScOutlineTable::TestInsertCol( SCSIZE nSize )
     779             : {
     780           0 :     return aColOutline.TestInsertSpace( nSize, MAXCOL );
     781             : }
     782             : 
     783           0 : void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
     784             : {
     785           0 :     aColOutline.InsertSpace( nStartCol, nSize );
     786           0 : }
     787             : 
     788           0 : bool ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
     789             : {
     790           0 :     return aColOutline.DeleteSpace( nStartCol, nSize );
     791             : }
     792             : 
     793           0 : bool ScOutlineTable::TestInsertRow( SCSIZE nSize )
     794             : {
     795           0 :     return aRowOutline.TestInsertSpace( nSize, MAXROW );
     796             : }
     797             : 
     798           0 : void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
     799             : {
     800           0 :     aRowOutline.InsertSpace( nStartRow, nSize );
     801           0 : }
     802             : 
     803           4 : bool ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     804             : {
     805           4 :     return aRowOutline.DeleteSpace( nStartRow, nSize );
     806             : }
     807             : 
     808         184 : ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
     809             :         pArray( pOutlineArray ),
     810             :         nStart( 0 ),
     811             :         nEnd( SCCOLROW_MAX ), // Iterate over all of them
     812             :         nSubLevel( 0 ),
     813         184 :         nSubEntry( 0 )
     814             : {
     815         184 :     nDepth = pArray->nDepth;
     816         184 : }
     817             : 
     818           0 : ScSubOutlineIterator::ScSubOutlineIterator(
     819             :     ScOutlineArray* pOutlineArray, size_t nLevel, size_t nEntry ) :
     820           0 :         pArray( pOutlineArray )
     821             : {
     822           0 :     const ScOutlineCollection& rColl = pArray->aCollections[nLevel];
     823           0 :     ScOutlineCollection::const_iterator it = rColl.begin();
     824           0 :     std::advance(it, nEntry);
     825           0 :     const ScOutlineEntry* pEntry = it->second;
     826           0 :     nStart = pEntry->GetStart();
     827           0 :     nEnd   = pEntry->GetEnd();
     828           0 :     nSubLevel = nLevel + 1;
     829           0 :     nSubEntry = 0;
     830           0 :     nDepth = pArray->nDepth;
     831           0 : }
     832             : 
     833         394 : ScOutlineEntry* ScSubOutlineIterator::GetNext()
     834             : {
     835         394 :     ScOutlineEntry* pEntry = NULL;
     836         394 :     bool bFound = false;
     837         414 :     do
     838             :     {
     839         598 :         if (nSubLevel >= nDepth)
     840         184 :             return NULL;
     841             : 
     842         414 :         ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
     843         414 :         if (nSubEntry < rColl.size())
     844             :         {
     845         210 :             ScOutlineCollection::iterator it = rColl.begin();
     846         210 :             std::advance(it, nSubEntry);
     847         210 :             pEntry = it->second;
     848             : 
     849         210 :             if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
     850         210 :                 bFound = true;
     851             : 
     852         210 :             ++nSubEntry;
     853             :         }
     854             :         else
     855             :         {
     856             :             // Go to the next sub-level
     857         204 :             nSubEntry = 0;
     858         204 :             ++nSubLevel;
     859             :         }
     860             :     }
     861         414 :     while (!bFound);
     862         210 :     return pEntry; // nSubLevel valid, if pEntry != 0
     863             : }
     864             : 
     865           0 : size_t ScSubOutlineIterator::LastEntry() const
     866             : {
     867           0 :     if (nSubEntry == 0)
     868             :     {
     869             :         OSL_FAIL("ScSubOutlineIterator::LastEntry before GetNext");
     870           0 :         return 0;
     871             :     }
     872           0 :     return nSubEntry-1;
     873             : }
     874             : 
     875           0 : void ScSubOutlineIterator::DeleteLast()
     876             : {
     877           0 :     if (nSubLevel >= nDepth)
     878             :     {
     879             :         OSL_FAIL("ScSubOutlineIterator::DeleteLast after End");
     880           0 :         return;
     881             :     }
     882           0 :     if (nSubEntry == 0)
     883             :     {
     884             :         OSL_FAIL("ScSubOutlineIterator::DeleteLast before GetNext");
     885           0 :         return;
     886             :     }
     887             : 
     888           0 :     --nSubEntry;
     889           0 :     ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
     890             :     OSL_ASSERT(nSubEntry < rColl.size());
     891           0 :     ScOutlineCollection::iterator it = rColl.begin();
     892           0 :     std::advance(it, nSubEntry);
     893           0 :     rColl.erase(it);
     894         228 : }
     895             : 
     896             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10