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

Generated by: LCOV version 1.10