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

Generated by: LCOV version 1.11