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

Generated by: LCOV version 1.10