LCOV - code coverage report
Current view: top level - sc/source/core/tool - rangelst.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 703 0.0 %
Date: 2014-04-14 Functions: 0 80 0.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 <stdlib.h>
      21             : #include <comphelper/string.hxx>
      22             : #include <unotools/collatorwrapper.hxx>
      23             : 
      24             : #include "rangelst.hxx"
      25             : #include "document.hxx"
      26             : #include "refupdat.hxx"
      27             : #include "rechead.hxx"
      28             : #include "compiler.hxx"
      29             : #include "stlalgorithm.hxx"
      30             : 
      31             : using ::std::vector;
      32             : using ::std::advance;
      33             : using ::std::find_if;
      34             : using ::std::for_each;
      35             : using ::formula::FormulaGrammar;
      36             : 
      37             : namespace {
      38             : 
      39             : template<typename T>
      40             : class FindEnclosingRange : public ::std::unary_function<ScRange*, bool>
      41             : {
      42             : public:
      43           0 :     FindEnclosingRange(const T& rTest) : mrTest(rTest) {}
      44           0 :     FindEnclosingRange(const FindEnclosingRange& r) : mrTest(r.mrTest) {}
      45           0 :     bool operator() (const ScRange* pRange) const
      46             :     {
      47           0 :         return pRange->In(mrTest);
      48             :     }
      49             : private:
      50             :     const T& mrTest;
      51             : };
      52             : 
      53             : template<typename T>
      54             : class FindRangeIn : public ::std::unary_function<ScRange*, bool>
      55             : {
      56             : public:
      57           0 :     FindRangeIn(const T& rTest) : mrTest(rTest) {}
      58             :     FindRangeIn(const FindRangeIn& r) : mrTest(r.mrTest) {}
      59           0 :     bool operator() (const ScRange* pRange) const
      60             :     {
      61           0 :         return mrTest.In(*pRange);
      62             :     }
      63             : private:
      64             :     const T& mrTest;
      65             : };
      66             : 
      67             : template<typename T>
      68             : class FindIntersectingRange : public ::std::unary_function<ScRange*, bool>
      69             : {
      70             : public:
      71           0 :     FindIntersectingRange(const T& rTest) : mrTest(rTest) {}
      72           0 :     FindIntersectingRange(const FindIntersectingRange& r) : mrTest(r.mrTest) {}
      73           0 :     bool operator() (const ScRange* pRange) const
      74             :     {
      75           0 :         return pRange->Intersects(mrTest);
      76             :     }
      77             : private:
      78             :     const T& mrTest;
      79             : };
      80             : 
      81             : class AppendToList : public ::std::unary_function<const ScRange*, void>
      82             : {
      83             : public:
      84           0 :     AppendToList(vector<ScRange*>& rRanges) : mrRanges(rRanges) {}
      85           0 :     AppendToList(const AppendToList& r) : mrRanges(r.mrRanges) {}
      86           0 :     void operator() (const ScRange* p)
      87             :     {
      88           0 :         mrRanges.push_back(new ScRange(*p));
      89           0 :     }
      90             : private:
      91             :     vector<ScRange*>& mrRanges;
      92             : };
      93             : 
      94             : class CountCells : public ::std::unary_function<const ScRange*, void>
      95             : {
      96             : public:
      97           0 :     CountCells() : mnCellCount(0) {}
      98           0 :     CountCells(const CountCells& r) : mnCellCount(r.mnCellCount) {}
      99             : 
     100           0 :     void operator() (const ScRange* p)
     101             :     {
     102             :         mnCellCount +=
     103           0 :               size_t(p->aEnd.Col() - p->aStart.Col() + 1)
     104           0 :             * size_t(p->aEnd.Row() - p->aStart.Row() + 1)
     105           0 :             * size_t(p->aEnd.Tab() - p->aStart.Tab() + 1);
     106           0 :     }
     107             : 
     108           0 :     size_t getCellCount() const { return mnCellCount; }
     109             : 
     110             : private:
     111             :     size_t mnCellCount;
     112             : };
     113             : 
     114             : class FormatString : public ::std::unary_function<const ScRange*, void>
     115             : {
     116             : public:
     117           0 :     FormatString(OUString& rStr, sal_uInt16 nFlags, ScDocument* pDoc, FormulaGrammar::AddressConvention eConv, sal_Unicode cDelim) :
     118             :         mrStr(rStr),
     119             :         mnFlags(nFlags),
     120             :         mpDoc(pDoc),
     121             :         meConv(eConv),
     122             :         mcDelim(cDelim),
     123           0 :         mbFirst(true) {}
     124             : 
     125           0 :     FormatString(const FormatString& r) :
     126             :         mrStr(r.mrStr),
     127             :         mnFlags(r.mnFlags),
     128             :         mpDoc(r.mpDoc),
     129             :         meConv(r.meConv),
     130             :         mcDelim(r.mcDelim),
     131           0 :         mbFirst(r.mbFirst) {}
     132             : 
     133           0 :     void operator() (const ScRange* p)
     134             :     {
     135           0 :         OUString aStr(p->Format(mnFlags, mpDoc, meConv));
     136           0 :         if (mbFirst)
     137           0 :             mbFirst = false;
     138             :         else
     139           0 :             mrStr += OUString(mcDelim);
     140           0 :         mrStr += aStr;
     141           0 :     }
     142             : private:
     143             :     OUString& mrStr;
     144             :     sal_uInt16 mnFlags;
     145             :     ScDocument* mpDoc;
     146             :     FormulaGrammar::AddressConvention meConv;
     147             :     sal_Unicode mcDelim;
     148             :     bool mbFirst;
     149             : };
     150             : 
     151             : }
     152             : 
     153             : //  ScRangeList
     154           0 : ScRangeList::~ScRangeList()
     155             : {
     156           0 :     RemoveAll();
     157           0 : }
     158             : 
     159           0 : sal_uInt16 ScRangeList::Parse( const OUString& rStr, ScDocument* pDoc, sal_uInt16 nMask,
     160             :                            formula::FormulaGrammar::AddressConvention eConv,
     161             :                            SCTAB nDefaultTab, sal_Unicode cDelimiter )
     162             : {
     163           0 :     if ( !rStr.isEmpty() )
     164             :     {
     165           0 :         if (!cDelimiter)
     166           0 :             cDelimiter = ScCompiler::GetNativeSymbolChar(ocSep);
     167             : 
     168           0 :         nMask |= SCA_VALID;             // falls das jemand vergessen sollte
     169           0 :         sal_uInt16 nResult = (sal_uInt16)~0;    // alle Bits setzen
     170           0 :         ScRange aRange;
     171           0 :         OUString aOne;
     172           0 :         SCTAB nTab = 0;
     173           0 :         if ( pDoc )
     174             :         {
     175           0 :             nTab = nDefaultTab;
     176             :         }
     177             :         else
     178           0 :             nTab = 0;
     179           0 :         sal_uInt16 nTCount = comphelper::string::getTokenCount(rStr, cDelimiter);
     180           0 :         for ( sal_uInt16 i=0; i<nTCount; i++ )
     181             :         {
     182           0 :             aOne = rStr.getToken( i, cDelimiter );
     183           0 :             aRange.aStart.SetTab( nTab );   // Default Tab wenn nicht angegeben
     184           0 :             sal_uInt16 nRes = aRange.ParseAny( aOne, pDoc, eConv );
     185           0 :             sal_uInt16 nEndRangeBits = SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2;
     186           0 :             sal_uInt16 nTmp1 = ( nRes & SCA_BITS );
     187           0 :             sal_uInt16 nTmp2 = ( nRes & nEndRangeBits );
     188             :             // If we have a valid single range with
     189             :             // any of the address bits we are interested in
     190             :             // set - set the equiv end range bits
     191           0 :             if ( (nRes & SCA_VALID ) && nTmp1 && ( nTmp2 != nEndRangeBits ) )
     192           0 :                     nRes |= ( nTmp1 << 4 );
     193             : 
     194           0 :             if ( (nRes & nMask) == nMask )
     195           0 :                 Append( aRange );
     196           0 :             nResult &= nRes;        // alle gemeinsamen Bits bleiben erhalten
     197             :         }
     198           0 :         return nResult;             // SCA_VALID gesetzt wenn alle ok
     199             :     }
     200             :     else
     201           0 :         return 0;
     202             : }
     203             : 
     204           0 : void ScRangeList::Format( OUString& rStr, sal_uInt16 nFlags, ScDocument* pDoc,
     205             :                           formula::FormulaGrammar::AddressConvention eConv,
     206             :                           sal_Unicode cDelimiter ) const
     207             : {
     208             : 
     209           0 :     if (!cDelimiter)
     210           0 :         cDelimiter = ScCompiler::GetNativeSymbolChar(ocSep);
     211             : 
     212           0 :     OUString aStr;
     213           0 :     FormatString func(aStr, nFlags, pDoc, eConv, cDelimiter);
     214           0 :     for_each(maRanges.begin(), maRanges.end(), func);
     215           0 :     rStr = aStr;
     216           0 : }
     217             : 
     218           0 : void ScRangeList::Join( const ScRange& r, bool bIsInList )
     219             : {
     220           0 :     if ( maRanges.empty() )
     221             :     {
     222           0 :         Append( r );
     223           0 :         return ;
     224             :     }
     225           0 :     SCCOL nCol1 = r.aStart.Col();
     226           0 :     SCROW nRow1 = r.aStart.Row();
     227           0 :     SCTAB nTab1 = r.aStart.Tab();
     228           0 :     SCCOL nCol2 = r.aEnd.Col();
     229           0 :     SCROW nRow2 = r.aEnd.Row();
     230           0 :     SCTAB nTab2 = r.aEnd.Tab();
     231             : 
     232           0 :     ScRange* pOver = (ScRange*) &r;     // fies aber wahr wenn bInList
     233           0 :     size_t nOldPos = 0;
     234           0 :     if ( bIsInList )
     235             :     {
     236             :         // Find the current position of this range.
     237           0 :         for ( size_t i = 0, nRanges = maRanges.size(); i < nRanges; ++i )
     238             :         {
     239           0 :             if ( maRanges[i] == pOver )
     240             :             {
     241           0 :                 nOldPos = i;
     242           0 :                 break;
     243             :             }
     244             :         }
     245             :     }
     246           0 :     bool bJoinedInput = false;
     247             : 
     248             :     // We need to query the size of the container dynamically since its size
     249             :     // may change during the loop.
     250           0 :     for ( size_t i = 0; i < maRanges.size() && pOver; ++i )
     251             :     {
     252           0 :         ScRange* p = maRanges[i];
     253           0 :         if ( p == pOver )
     254           0 :             continue;           // derselbe, weiter mit dem naechsten
     255           0 :         bool bJoined = false;
     256           0 :         if ( p->In( r ) )
     257             :         {   // Range r in Range p enthalten oder identisch
     258           0 :             if ( bIsInList )
     259           0 :                 bJoined = true;     // weg mit Range r
     260             :             else
     261             :             {   // das war's dann
     262           0 :                 bJoinedInput = true;    // nicht anhaengen
     263           0 :                 break;  // for
     264             :             }
     265             :         }
     266           0 :         else if ( r.In( *p ) )
     267             :         {   // Range p in Range r enthalten, r zum neuen Range machen
     268           0 :             *p = r;
     269           0 :             bJoined = true;
     270             :         }
     271           0 :         if ( !bJoined && p->aStart.Tab() == nTab1 && p->aEnd.Tab() == nTab2 )
     272             :         {   // 2D
     273           0 :             if ( p->aStart.Col() == nCol1 && p->aEnd.Col() == nCol2 )
     274             :             {
     275           0 :                 if ( p->aStart.Row() == nRow2+1 )
     276             :                 {   // oben
     277           0 :                     p->aStart.SetRow( nRow1 );
     278           0 :                     bJoined = true;
     279             :                 }
     280           0 :                 else if ( p->aEnd.Row() == nRow1-1 )
     281             :                 {   // unten
     282           0 :                     p->aEnd.SetRow( nRow2 );
     283           0 :                     bJoined = true;
     284             :                 }
     285             :             }
     286           0 :             else if ( p->aStart.Row() == nRow1 && p->aEnd.Row() == nRow2 )
     287             :             {
     288           0 :                 if ( p->aStart.Col() == nCol2+1 )
     289             :                 {   // links
     290           0 :                     p->aStart.SetCol( nCol1 );
     291           0 :                     bJoined = true;
     292             :                 }
     293           0 :                 else if ( p->aEnd.Col() == nCol1-1 )
     294             :                 {   // rechts
     295           0 :                     p->aEnd.SetCol( nCol2 );
     296           0 :                     bJoined = true;
     297             :                 }
     298             :             }
     299             :         }
     300           0 :         if ( bJoined )
     301             :         {
     302           0 :             if ( bIsInList )
     303             :             {   // innerhalb der Liste Range loeschen
     304           0 :                 Remove(nOldPos);
     305           0 :                 i--;
     306           0 :                 delete pOver;
     307           0 :                 pOver = NULL;
     308           0 :                 if ( nOldPos )
     309           0 :                     nOldPos--;          // Seek richtig aufsetzen
     310             :             }
     311           0 :             bJoinedInput = true;
     312           0 :             Join( *p, true );           // rekursiv!
     313             :         }
     314             :     }
     315           0 :     if (  !bIsInList && !bJoinedInput )
     316           0 :         Append( r );
     317             : }
     318             : 
     319           0 : bool ScRangeList::operator==( const ScRangeList& r ) const
     320             : {
     321           0 :     if ( this == &r )
     322           0 :         return true;
     323             : 
     324           0 :     if (maRanges.size() != r.maRanges.size())
     325           0 :         return false;
     326             : 
     327           0 :     vector<ScRange*>::const_iterator itr1 = maRanges.begin(), itrEnd = maRanges.end();
     328           0 :     vector<ScRange*>::const_iterator itr2 = r.maRanges.begin();
     329           0 :     for (; itr1 != itrEnd; ++itr1, ++itr2)
     330             :     {
     331           0 :         const ScRange* p1 = *itr1;
     332           0 :         const ScRange* p2 = *itr2;
     333           0 :         if (*p1 != *p2)
     334           0 :             return false;
     335             :     }
     336           0 :     return true;
     337             : }
     338             : 
     339           0 : bool ScRangeList::operator!=( const ScRangeList& r ) const
     340             : {
     341           0 :     return !operator==( r );
     342             : }
     343             : 
     344           0 : bool ScRangeList::UpdateReference(
     345             :     UpdateRefMode eUpdateRefMode,
     346             :     ScDocument* pDoc,
     347             :     const ScRange& rWhere,
     348             :     SCsCOL nDx,
     349             :     SCsROW nDy,
     350             :     SCsTAB nDz
     351             : )
     352             : {
     353           0 :     if (maRanges.empty())
     354             :         // No ranges to update.  Bail out.
     355           0 :         return false;
     356             : 
     357           0 :     bool bChanged = false;
     358             :     SCCOL nCol1;
     359             :     SCROW nRow1;
     360             :     SCTAB nTab1;
     361             :     SCCOL nCol2;
     362             :     SCROW nRow2;
     363             :     SCTAB nTab2;
     364           0 :     rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     365             : 
     366           0 :     if(eUpdateRefMode == URM_INSDEL)
     367             :     {
     368             :         // right now this only works for nTab1 == nTab2
     369           0 :         if(nTab1 == nTab2)
     370             :         {
     371           0 :             if(nDx < 0)
     372             :             {
     373           0 :                 DeleteArea(nCol1+nDx, nRow1, nTab1, nCol1-1, nRow2, nTab2);
     374             :             }
     375           0 :             if(nDy < 0)
     376             :             {
     377           0 :                 DeleteArea(nCol1, nRow1+nDy, nTab1, nCol2, nRow1-1, nTab2);
     378             :             }
     379             :             SAL_WARN_IF(nDx < 0 && nDy < 0, "sc", "nDx and nDy are negative, check why");
     380             :         }
     381             :     }
     382             : 
     383           0 :     if(maRanges.empty())
     384           0 :         return true;
     385             : 
     386           0 :     iterator itr = maRanges.begin(), itrEnd = maRanges.end();
     387           0 :     for (; itr != itrEnd; ++itr)
     388             :     {
     389           0 :         ScRange* pR = *itr;
     390             :         SCCOL theCol1;
     391             :         SCROW theRow1;
     392             :         SCTAB theTab1;
     393             :         SCCOL theCol2;
     394             :         SCROW theRow2;
     395             :         SCTAB theTab2;
     396           0 :         pR->GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
     397           0 :         if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
     398             :                 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
     399             :                 nDx, nDy, nDz,
     400           0 :                 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 )
     401             :                 != UR_NOTHING )
     402             :         {
     403           0 :             bChanged = true;
     404           0 :             pR->aStart.Set( theCol1, theRow1, theTab1 );
     405           0 :             pR->aEnd.Set( theCol2, theRow2, theTab2 );
     406             :         }
     407             :     }
     408             : 
     409           0 :     if(eUpdateRefMode == URM_INSDEL)
     410             :     {
     411           0 :         if( nDx < 0 || nDy < 0 )
     412             :         {
     413           0 :             size_t n = maRanges.size();
     414           0 :             Join(*maRanges[n-1], true);
     415             :         }
     416             :     }
     417             : 
     418           0 :     return bChanged;
     419             : }
     420             : 
     421           0 : void ScRangeList::InsertRow( SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, SCROW nRowPos, SCSIZE nSize )
     422             : {
     423           0 :     std::vector<ScRange> aNewRanges;
     424           0 :     for(iterator it = maRanges.begin(), itEnd = maRanges.end(); it != itEnd;
     425             :             ++it)
     426             :     {
     427           0 :         ScRange* pRange = *it;
     428           0 :         if(pRange->aStart.Tab() <= nTab && pRange->aEnd.Tab() >= nTab)
     429             :         {
     430           0 :             if(pRange->aEnd.Row() == nRowPos - 1 && (nColStart <= pRange->aEnd.Col() || nColEnd >= pRange->aStart.Col()))
     431             :             {
     432           0 :                 SCCOL nNewRangeStartCol = std::max<SCCOL>(nColStart, pRange->aStart.Col());
     433           0 :                 SCCOL nNewRangeEndCol = std::min<SCCOL>(nColEnd, pRange->aEnd.Col());
     434           0 :                 SCROW nNewRangeStartRow = pRange->aEnd.Row() + 1;
     435           0 :                 SCROW nNewRangeEndRow = nRowPos + nSize - 1;
     436             :                 aNewRanges.push_back(ScRange(nNewRangeStartCol, nNewRangeStartRow, nTab, nNewRangeEndCol,
     437           0 :                             nNewRangeEndRow, nTab));
     438             :             }
     439             :         }
     440             :     }
     441             : 
     442           0 :     for(std::vector<ScRange>::const_iterator it = aNewRanges.begin(), itEnd = aNewRanges.end();
     443             :             it != itEnd; ++it)
     444             :     {
     445           0 :         if(!it->IsValid())
     446           0 :             continue;
     447             : 
     448           0 :         Join(*it);
     449           0 :     }
     450           0 : }
     451             : 
     452           0 : void ScRangeList::InsertCol( SCTAB nTab, SCROW nRowStart, SCROW nRowEnd, SCCOL nColPos, SCSIZE nSize )
     453             : {
     454           0 :     std::vector<ScRange> aNewRanges;
     455           0 :     for(iterator it = maRanges.begin(), itEnd = maRanges.end(); it != itEnd;
     456             :             ++it)
     457             :     {
     458           0 :         ScRange* pRange = *it;
     459           0 :         if(pRange->aStart.Tab() <= nTab && pRange->aEnd.Tab() >= nTab)
     460             :         {
     461           0 :             if(pRange->aEnd.Col() == nColPos - 1 && (nRowStart <= pRange->aEnd.Row() || nRowEnd >= pRange->aStart.Row()))
     462             :             {
     463           0 :                 SCROW nNewRangeStartRow = std::max<SCROW>(nRowStart, pRange->aStart.Row());
     464           0 :                 SCROW nNewRangeEndRow = std::min<SCROW>(nRowEnd, pRange->aEnd.Row());
     465           0 :                 SCCOL nNewRangeStartCol = pRange->aEnd.Col() + 1;
     466           0 :                 SCCOL nNewRangeEndCol = nColPos + nSize - 1;
     467             :                 aNewRanges.push_back(ScRange(nNewRangeStartCol, nNewRangeStartRow, nTab, nNewRangeEndCol,
     468           0 :                             nNewRangeEndRow, nTab));
     469             :             }
     470             :         }
     471             :     }
     472             : 
     473           0 :     for(std::vector<ScRange>::const_iterator it = aNewRanges.begin(), itEnd = aNewRanges.end();
     474             :             it != itEnd; ++it)
     475             :     {
     476           0 :         if(!it->IsValid())
     477           0 :             continue;
     478             : 
     479           0 :         Join(*it);
     480           0 :     }
     481           0 : }
     482             : 
     483             : namespace {
     484             : 
     485             : /**
     486             :  * Check if the deleting range cuts the test range exactly into a single
     487             :  * piece.
     488             :  *
     489             :  * X = column ; Y = row
     490             :  * +------+    +------+
     491             :  * |xxxxxx|    |      |
     492             :  * +------+ or +------+
     493             :  * |      |    |xxxxxx|
     494             :  * +------+    +------+
     495             :  *
     496             :  * X = row; Y = column
     497             :  * +--+--+    +--+--+
     498             :  * |xx|  |    |  |xx|
     499             :  * |xx|  | or |  |xx|
     500             :  * |xx|  |    |  |xx|
     501             :  * +--+--+    +--+--+
     502             :  * where xxx is the deleted region.
     503             :  */
     504             : template<typename X, typename Y>
     505           0 : bool checkForOneRange(
     506             :    X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
     507             : {
     508           0 :     if (nDeleteX1 <= nX1 && nX2 <= nDeleteX2 && (nDeleteY1 <= nY1 || nY2 <= nDeleteY2))
     509           0 :         return true;
     510             : 
     511           0 :     return false;
     512             : }
     513             : 
     514           0 : bool handleOneRange( const ScRange& rDeleteRange, ScRange* p )
     515             : {
     516           0 :     const ScAddress& rDelStart = rDeleteRange.aStart;
     517           0 :     const ScAddress& rDelEnd = rDeleteRange.aEnd;
     518           0 :     ScAddress aPStart = p->aStart;
     519           0 :     ScAddress aPEnd = p->aEnd;
     520           0 :     SCCOL nDeleteCol1 = rDelStart.Col();
     521           0 :     SCCOL nDeleteCol2 = rDelEnd.Col();
     522           0 :     SCROW nDeleteRow1 = rDelStart.Row();
     523           0 :     SCROW nDeleteRow2 = rDelEnd.Row();
     524           0 :     SCCOL nCol1 = aPStart.Col();
     525           0 :     SCCOL nCol2 = aPEnd.Col();
     526           0 :     SCROW nRow1 = aPStart.Row();
     527           0 :     SCROW nRow2 = aPEnd.Row();
     528             : 
     529           0 :     if (checkForOneRange(nDeleteCol1, nDeleteCol2, nDeleteRow1, nDeleteRow2, nCol1, nCol2, nRow1, nRow2))
     530             :     {
     531             :         // Deleting range fully overlaps the column range.  Adjust the row span.
     532           0 :         if (nDeleteRow1 <= nRow1)
     533             :         {
     534             :             // +------+
     535             :             // |xxxxxx|
     536             :             // +------+
     537             :             // |      |
     538             :             // +------+ (xxx) = deleted region
     539             : 
     540           0 :             p->aStart.SetRow(nDeleteRow1+1);
     541           0 :             return true;
     542             :         }
     543           0 :         else if (nRow2 <= nDeleteRow2)
     544             :         {
     545             :             // +------+
     546             :             // |      |
     547             :             // +------+
     548             :             // |xxxxxx|
     549             :             // +------+ (xxx) = deleted region
     550             : 
     551           0 :             p->aEnd.SetRow(nDeleteRow1-1);
     552           0 :             return true;
     553             :         }
     554             :     }
     555           0 :     else if (checkForOneRange(nDeleteRow1, nDeleteRow2, nDeleteCol1, nDeleteCol2, nRow1, nRow2, nCol1, nCol2))
     556             :     {
     557             :         // Deleting range fully overlaps the row range.  Adjust the column span.
     558           0 :         if (nDeleteCol1 <= nCol1)
     559             :         {
     560             :             // +--+--+
     561             :             // |xx|  |
     562             :             // |xx|  |
     563             :             // |xx|  |
     564             :             // +--+--+ (xxx) = deleted region
     565             : 
     566           0 :             p->aStart.SetCol(nDeleteCol2+1);
     567           0 :             return true;
     568             :         }
     569           0 :         else if (nCol2 <= nDeleteCol2)
     570             :         {
     571             :             // +--+--+
     572             :             // |  |xx|
     573             :             // |  |xx|
     574             :             // |  |xx|
     575             :             // +--+--+ (xxx) = deleted region
     576             : 
     577           0 :             p->aEnd.SetCol(nDeleteCol1-1);
     578           0 :             return true;
     579             :         }
     580             :     }
     581           0 :     return false;
     582             : }
     583             : 
     584             : /**
     585             :  * Check if the deleting range cuts the test range in the middle, to
     586             :  * separate it into exactly two pieces.
     587             :  *
     588             :  * Either
     589             :  * +--------+    +--+-+--+
     590             :  * |        |    |  |x|  |
     591             :  * +--------+    |  |x|  |
     592             :  * |xxxxxxxx| or |  |x|  |
     593             :  * +--------+    |  |x|  |
     594             :  * |        |    |  |x|  |
     595             :  * +--------+    +--+-+--+
     596             :  * where xxx is the deleted region.
     597             :  */
     598             : template<typename X, typename Y>
     599             : bool checkForTwoRangesCase2(
     600             :    X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
     601             : {
     602             :     if (nY1 < nDeleteY1 && nDeleteY2 < nY2 && nDeleteX1 <= nX1 && nX2 <= nDeleteX2)
     603             :         return true;
     604             : 
     605             :     return false;
     606             : }
     607             : 
     608           0 : bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRange>& rNewRanges )
     609             : {
     610           0 :     const ScAddress& rDelStart = rDeleteRange.aStart;
     611           0 :     const ScAddress& rDelEnd = rDeleteRange.aEnd;
     612           0 :     ScAddress aPStart = p->aStart;
     613           0 :     ScAddress aPEnd = p->aEnd;
     614           0 :     SCCOL nDeleteCol1 = rDelStart.Col();
     615           0 :     SCCOL nDeleteCol2 = rDelEnd.Col();
     616           0 :     SCROW nDeleteRow1 = rDelStart.Row();
     617           0 :     SCROW nDeleteRow2 = rDelEnd.Row();
     618           0 :     SCCOL nCol1 = aPStart.Col();
     619           0 :     SCCOL nCol2 = aPEnd.Col();
     620           0 :     SCROW nRow1 = aPStart.Row();
     621           0 :     SCROW nRow2 = aPEnd.Row();
     622           0 :     SCTAB nTab = aPStart.Tab();
     623             : 
     624           0 :     if (nCol1 < nDeleteCol1 && nDeleteCol1 <= nCol2 && nCol2 <= nDeleteCol2)
     625             :     {
     626             :         // column deleted :     |-------|
     627             :         // column original: |-------|
     628           0 :         if (nRow1 < nDeleteRow1 && nDeleteRow1 <= nRow2 && nRow2 <= nDeleteRow2)
     629             :         {
     630             :             // row deleted:     |------|
     631             :             // row original: |------|
     632             :             //
     633             :             // +-------+
     634             :             // |   1   |
     635             :             // +---+---+---+
     636             :             // | 2 |xxxxxxx|
     637             :             // +---+xxxxxxx|
     638             :             //     |xxxxxxx|
     639             :             //     +-------+ (xxx) deleted region
     640             : 
     641           0 :             ScRange aNewRange( nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nRow2, nTab ); // 2
     642           0 :             rNewRanges.push_back(aNewRange);
     643             : 
     644           0 :             p->aEnd.SetRow(nDeleteRow1-1); // 1
     645           0 :             return true;
     646             :         }
     647           0 :         else if (nRow1 <= nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
     648             :         {
     649             :             // row deleted:  |------|
     650             :             // row original:    |------|
     651             :             //
     652             :             //     +-------+
     653             :             //     |xxxxxxx|
     654             :             // +---+xxxxxxx|
     655             :             // | 1 |xxxxxxx|
     656             :             // +---+---+---+
     657             :             // |   2   |    (xxx) deleted region
     658             :             // +-------+
     659             : 
     660           0 :             ScRange aNewRange( aPStart, ScAddress(nDeleteCol1-1, nRow2, nTab) ); // 1
     661           0 :             rNewRanges.push_back(aNewRange);
     662             : 
     663           0 :             p->aStart.SetRow(nDeleteRow2+1); // 2
     664           0 :             return true;
     665           0 :         }
     666             :     }
     667           0 :     else if (nCol1 <= nDeleteCol2 && nDeleteCol2 < nCol2 && nDeleteCol1 <= nCol1)
     668             :     {
     669             :         // column deleted : |-------|
     670             :         // column original:     |-------|
     671           0 :         if (nRow1 < nDeleteRow1 && nDeleteRow1 <= nRow2 && nRow2 <= nDeleteRow2)
     672             :         {
     673             :             // row deleted:     |------|
     674             :             // row original: |------|
     675             :             //
     676             :             //     +-------+
     677             :             //     |   1   |
     678             :             // +-------+---+
     679             :             // |xxxxxxx| 2 |
     680             :             // |xxxxxxx+---+
     681             :             // |xxxxxxx|
     682             :             // +-------+
     683             :             //  (xxx) deleted region
     684             : 
     685           0 :             ScRange aNewRange( ScAddress( nDeleteCol2+1, nDeleteRow1, nTab ), aPEnd ); // 2
     686           0 :             rNewRanges.push_back(aNewRange);
     687             : 
     688           0 :             p->aEnd.SetRow(nDeleteRow1-1); // 1
     689           0 :             return true;
     690             :         }
     691           0 :         else if (nRow1 <= nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
     692             :         {
     693             :             // row deleted:  |-------|
     694             :             // row original:     |--------|
     695             :             //
     696             :             // +-------+
     697             :             // |xxxxxxx|
     698             :             // |xxxxxxx+---+
     699             :             // |xxxxxxx| 1 |
     700             :             // +-------+---+
     701             :             //     |   2   |
     702             :             //     +-------+ (xxx) deleted region
     703             : 
     704           0 :             ScRange aNewRange(nDeleteCol2+1, nRow1, nTab, nCol2, nDeleteRow2, nTab); // 1
     705           0 :             rNewRanges.push_back(aNewRange);
     706             : 
     707           0 :             p->aStart.SetRow(nDeleteRow2+1); // 2
     708           0 :             return true;
     709           0 :         }
     710             :     }
     711           0 :     else if (nRow1 < nDeleteRow1 && nDeleteRow2 < nRow2 && nDeleteCol1 <= nCol1 && nCol2 <= nDeleteCol2)
     712             :     {
     713             :         // +--------+
     714             :         // |   1    |
     715             :         // +--------+
     716             :         // |xxxxxxxx| (xxx) deleted region
     717             :         // +--------+
     718             :         // |   2    |
     719             :         // +--------+
     720             : 
     721           0 :         ScRange aNewRange( aPStart, ScAddress(nCol2, nDeleteRow1-1, nTab) ); // 1
     722           0 :         rNewRanges.push_back(aNewRange);
     723             : 
     724           0 :         p->aStart.SetRow(nDeleteRow2+1); // 2
     725           0 :         return true;
     726             :     }
     727           0 :     else if (nCol1 < nDeleteCol1 && nDeleteCol2 < nCol2 && nDeleteRow1 <= nRow1 && nRow2 <= nDeleteRow2)
     728             :     {
     729             :         // +---+-+---+
     730             :         // |   |x|   |
     731             :         // |   |x|   |
     732             :         // | 1 |x| 2 | (xxx) deleted region
     733             :         // |   |x|   |
     734             :         // |   |x|   |
     735             :         // +---+-+---+
     736             : 
     737           0 :         ScRange aNewRange( aPStart, ScAddress(nDeleteCol1-1, nRow2, nTab) ); // 1
     738           0 :         rNewRanges.push_back(aNewRange);
     739             : 
     740           0 :         p->aStart.SetCol(nDeleteCol2+1); // 2
     741           0 :         return true;
     742             :     }
     743             : 
     744           0 :     return false;
     745             : }
     746             : 
     747             : /**
     748             :  * Check if any of the followings applies:
     749             :  *
     750             :  * X = column; Y = row
     751             :  * +----------+           +----------+
     752             :  * |          |           |          |
     753             :  * |  +-------+---+    +--+-------+  |
     754             :  * |  |xxxxxxxxxxx| or |xxxxxxxxxx|  |
     755             :  * |  +-------+---+    +--+-------+  |
     756             :  * |          |           |          |
     757             :  * +----------+           +----------+
     758             :  *
     759             :  * X = row; Y = column
     760             :  *     +--+
     761             :  *     |xx|
     762             :  * +---+xx+---+    +----------+
     763             :  * |   |xx|   |    |          |
     764             :  * |   |xx|   | or |   +--+   |
     765             :  * |   +--+   |    |   |xx|   |
     766             :  * |          |    |   |xx|   |
     767             :  * +----------+    +---+xx+---+
     768             :  *                     |xx|
     769             :  *                     +--+     (xxx) deleted region
     770             :  */
     771             : template<typename X, typename Y>
     772           0 : bool checkForThreeRanges(
     773             :    X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
     774             : {
     775           0 :     if (nX1 <= nDeleteX1 && nX2 <= nDeleteX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
     776           0 :         return true;
     777             : 
     778           0 :     if (nDeleteX1 <= nX1 && nDeleteX2 <= nX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
     779           0 :         return true;
     780             : 
     781           0 :     return false;
     782             : }
     783             : 
     784           0 : bool handleThreeRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRange>& rNewRanges )
     785             : {
     786           0 :     const ScAddress& rDelStart = rDeleteRange.aStart;
     787           0 :     const ScAddress& rDelEnd = rDeleteRange.aEnd;
     788           0 :     ScAddress aPStart = p->aStart;
     789           0 :     ScAddress aPEnd = p->aEnd;
     790           0 :     SCCOL nDeleteCol1 = rDelStart.Col();
     791           0 :     SCCOL nDeleteCol2 = rDelEnd.Col();
     792           0 :     SCROW nDeleteRow1 = rDelStart.Row();
     793           0 :     SCROW nDeleteRow2 = rDelEnd.Row();
     794           0 :     SCCOL nCol1 = aPStart.Col();
     795           0 :     SCCOL nCol2 = aPEnd.Col();
     796           0 :     SCROW nRow1 = aPStart.Row();
     797           0 :     SCROW nRow2 = aPEnd.Row();
     798           0 :     SCTAB nTab = aPStart.Tab();
     799             : 
     800           0 :     if (checkForThreeRanges(nDeleteCol1, nDeleteCol2, nDeleteRow1, nDeleteRow2, nCol1, nCol2, nRow1, nRow2))
     801             :     {
     802           0 :         if (nCol1 < nDeleteCol1)
     803             :         {
     804             :             // +---+------+
     805             :             // |   |  2   |
     806             :             // |   +------+---+
     807             :             // | 1 |xxxxxxxxxx|
     808             :             // |   +------+---+
     809             :             // |   |  3   |
     810             :             // +---+------+
     811             : 
     812           0 :             ScRange aNewRange(nDeleteCol1, nRow1, nTab, nCol2, nDeleteRow1-1, nTab); // 2
     813           0 :             rNewRanges.push_back(aNewRange);
     814             : 
     815           0 :             aNewRange = ScRange(ScAddress(nDeleteCol1, nDeleteRow2+1, nTab), aPEnd); // 3
     816           0 :             rNewRanges.push_back(aNewRange);
     817             : 
     818           0 :             p->aEnd.SetCol(nDeleteCol1-1); // 1
     819             :         }
     820             :         else
     821             :         {
     822             :             //     +------+---+
     823             :             //     |  1   |   |
     824             :             // +---+------+   |
     825             :             // |xxxxxxxxxx| 2 |
     826             :             // +---+------+   |
     827             :             //     |  3   |   |
     828             :             //     +------+---+
     829             : 
     830           0 :             ScRange aNewRange(aPStart, ScAddress(nDeleteCol2, nDeleteRow1-1, nTab)); // 1
     831           0 :             rNewRanges.push_back(aNewRange);
     832             : 
     833           0 :             aNewRange = ScRange(nCol1, nDeleteRow2+1, nTab, nDeleteCol2, nRow2, nTab); // 3
     834           0 :             rNewRanges.push_back(aNewRange);
     835             : 
     836           0 :             p->aStart.SetCol(nDeleteCol2+1); // 2
     837             :         }
     838           0 :         return true;
     839             :     }
     840           0 :     else if (checkForThreeRanges(nDeleteRow1, nDeleteRow2, nDeleteCol1, nDeleteCol2, nRow1, nRow2, nCol1, nCol2))
     841             :     {
     842           0 :         if (nRow1 < nDeleteRow1)
     843             :         {
     844             :             // +----------+
     845             :             // |    1     |
     846             :             // +---+--+---+
     847             :             // |   |xx|   |
     848             :             // | 2 |xx| 3 |
     849             :             // |   |xx|   |
     850             :             // +---+xx+---+
     851             :             //     |xx|
     852             :             //     +--+
     853             : 
     854           0 :             ScRange aNewRange(nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nRow2, nTab); // 2
     855           0 :             rNewRanges.push_back( aNewRange );
     856             : 
     857           0 :             aNewRange = ScRange(ScAddress(nDeleteCol2+1, nDeleteRow1, nTab), aPEnd); // 3
     858           0 :             rNewRanges.push_back( aNewRange );
     859             : 
     860           0 :             p->aEnd.SetRow(nDeleteRow1-1); // 1
     861             :         }
     862             :         else
     863             :         {
     864             :             //     +--+
     865             :             //     |xx|
     866             :             // +---+xx+---+
     867             :             // | 1 |xx| 2 |
     868             :             // |   |xx|   |
     869             :             // +---+--+---+
     870             :             // |    3     |
     871             :             // +----------+
     872             : 
     873           0 :             ScRange aNewRange(aPStart, ScAddress(nDeleteCol1-1, nDeleteRow2, nTab)); // 1
     874           0 :             rNewRanges.push_back(aNewRange);
     875             : 
     876           0 :             aNewRange = ScRange(nDeleteCol2+1, nRow1, nTab, nCol2, nDeleteRow2, nTab); // 2
     877           0 :             rNewRanges.push_back( aNewRange );
     878             : 
     879           0 :             p->aStart.SetRow(nDeleteRow2+1); // 3
     880             :         }
     881           0 :         return true;
     882             :     }
     883             : 
     884           0 :     return false;
     885             : }
     886             : 
     887           0 : bool handleFourRanges( const ScRange& rDelRange, ScRange* p, std::vector<ScRange>& rNewRanges )
     888             : {
     889           0 :     const ScAddress& rDelStart = rDelRange.aStart;
     890           0 :     const ScAddress& rDelEnd = rDelRange.aEnd;
     891           0 :     ScAddress aPStart = p->aStart;
     892           0 :     ScAddress aPEnd = p->aEnd;
     893           0 :     SCCOL nDeleteCol1 = rDelStart.Col();
     894           0 :     SCCOL nDeleteCol2 = rDelEnd.Col();
     895           0 :     SCROW nDeleteRow1 = rDelStart.Row();
     896           0 :     SCROW nDeleteRow2 = rDelEnd.Row();
     897           0 :     SCCOL nCol1 = aPStart.Col();
     898           0 :     SCCOL nCol2 = aPEnd.Col();
     899           0 :     SCROW nRow1 = aPStart.Row();
     900           0 :     SCROW nRow2 = aPEnd.Row();
     901           0 :     SCTAB nTab = aPStart.Tab();
     902             : 
     903           0 :     if (nCol1 < nDeleteCol1 && nDeleteCol2 < nCol2 && nRow1 < nDeleteRow1 && nDeleteRow2 < nRow2)
     904             :     {
     905             : 
     906             :         // +---------------+
     907             :         // |       1       |
     908             :         // +---+-------+---+
     909             :         // |   |xxxxxxx|   |
     910             :         // | 2 |xxxxxxx| 3 |
     911             :         // |   |xxxxxxx|   |
     912             :         // +---+-------+---+
     913             :         // |       4       |
     914             :         // +---------------+
     915             : 
     916           0 :         ScRange aNewRange(ScAddress(nCol1, nDeleteRow2+1, nTab), aPEnd); // 4
     917           0 :         rNewRanges.push_back( aNewRange );
     918             : 
     919           0 :         aNewRange = ScRange(nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nDeleteRow2, nTab); // 2
     920           0 :         rNewRanges.push_back( aNewRange );
     921             : 
     922           0 :         aNewRange = ScRange(nDeleteCol2+1, nDeleteRow1, nTab, nCol2, nDeleteRow2, nTab); // 3
     923           0 :         rNewRanges.push_back( aNewRange );
     924             : 
     925           0 :         p->aEnd.SetRow(nDeleteRow1-1); // 1
     926             : 
     927           0 :         return true;
     928             :     }
     929             : 
     930           0 :     return false;
     931             : }
     932             : 
     933             : }
     934             : 
     935           0 : void ScRangeList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
     936             :                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
     937             : {
     938           0 :     ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     939           0 :     for(size_t i = 0; i < maRanges.size();)
     940             :     {
     941           0 :         if(FindRangeIn< ScRange >(aRange)(maRanges[i]))
     942             :         {
     943           0 :             ScRange* pRange = Remove(i);
     944           0 :             delete pRange;
     945             :         }
     946             :         else
     947           0 :             ++i;
     948             :     }
     949             : 
     950           0 :     std::vector<ScRange> aNewRanges;
     951             : 
     952           0 :     for(iterator itr = maRanges.begin(); itr != maRanges.end(); ++itr)
     953             :     {
     954             :         // we have two basic cases here:
     955             :         // 1. Delete area and pRange intersect
     956             :         // 2. Delete area and pRange are not intersecting
     957             :         // checking for 2 and if true skip this range
     958           0 :         if(!(*itr)->Intersects(aRange))
     959           0 :             continue;
     960             : 
     961             :         // We get between 1 and 4 ranges from the difference of the first with the second
     962             : 
     963             :         // X either Col or Row and Y then the opposite
     964             :         // r = deleteRange, p = entry from ScRangeList
     965             : 
     966             :         // getting exactly one range is the simple case
     967             :         // r.aStart.X() <= p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
     968             :         // && ( r.aStart.Y() <= p.aStart.Y() || r.aEnd.Y() >= r.aEnd.Y() )
     969           0 :         if(handleOneRange( aRange, *itr ))
     970           0 :             continue;
     971             : 
     972             :         // getting two ranges
     973             :         // r.aStart.X()
     974           0 :         else if(handleTwoRanges( aRange, *itr, aNewRanges ))
     975           0 :             continue;
     976             : 
     977             :         // getting 3 ranges
     978             :         // r.aStart.X() > p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
     979             :         // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
     980             :         // or
     981             :         // r.aStart.X() <= p.aStart.X() && r.aEnd.X() < p.aEnd.X()
     982             :         // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
     983           0 :         else if(handleThreeRanges( aRange, *itr, aNewRanges ))
     984           0 :             continue;
     985             : 
     986             :         // getting 4 ranges
     987             :         // r.aStart.X() > p.aStart.X() && r.aEnd().X() < p.aEnd.X()
     988             :         // && r.aStart.Y() > p.aStart.Y() && r.aEnd().Y() < p.aEnd.Y()
     989           0 :         else if(handleFourRanges( aRange, *itr, aNewRanges ))
     990           0 :             continue;
     991             :     }
     992           0 :     for(vector<ScRange>::iterator itr = aNewRanges.begin(); itr != aNewRanges.end(); ++itr)
     993           0 :         Join( *itr, false);
     994           0 : }
     995             : 
     996           0 : const ScRange* ScRangeList::Find( const ScAddress& rAdr ) const
     997             : {
     998             :     const_iterator itr = find_if(
     999           0 :         maRanges.begin(), maRanges.end(), FindEnclosingRange<ScAddress>(rAdr));
    1000           0 :     return itr == maRanges.end() ? NULL : *itr;
    1001             : }
    1002             : 
    1003           0 : ScRange* ScRangeList::Find( const ScAddress& rAdr )
    1004             : {
    1005             :     iterator itr = find_if(
    1006           0 :         maRanges.begin(), maRanges.end(), FindEnclosingRange<ScAddress>(rAdr));
    1007           0 :     return itr == maRanges.end() ? NULL : *itr;
    1008             : }
    1009             : 
    1010           0 : ScRangeList::ScRangeList() {}
    1011             : 
    1012           0 : ScRangeList::ScRangeList( const ScRangeList& rList ) :
    1013           0 :     SvRefBase()
    1014             : {
    1015           0 :     maRanges.reserve(rList.maRanges.size());
    1016           0 :     for_each(rList.maRanges.begin(), rList.maRanges.end(), AppendToList(maRanges));
    1017           0 : }
    1018             : 
    1019           0 : ScRangeList::ScRangeList( const ScRange& rRange )
    1020             : {
    1021           0 :     maRanges.reserve(1);
    1022           0 :     Append(rRange);
    1023           0 : }
    1024             : 
    1025           0 : ScRangeList& ScRangeList::operator=(const ScRangeList& rList)
    1026             : {
    1027           0 :     RemoveAll();
    1028           0 :     maRanges.reserve(rList.maRanges.size());
    1029           0 :     for_each(rList.maRanges.begin(), rList.maRanges.end(), AppendToList(maRanges));
    1030           0 :     return *this;
    1031             : }
    1032             : 
    1033           0 : void ScRangeList::Append( const ScRange& rRange )
    1034             : {
    1035           0 :     ScRange* pR = new ScRange( rRange );
    1036           0 :     maRanges.push_back( pR );
    1037           0 : }
    1038             : 
    1039           0 : bool ScRangeList::Intersects( const ScRange& rRange ) const
    1040             : {
    1041           0 :     const_iterator itrEnd = maRanges.end();
    1042             :     const_iterator itr =
    1043           0 :         find_if(maRanges.begin(), itrEnd, FindIntersectingRange<ScRange>(rRange));
    1044           0 :     return itr != itrEnd;
    1045             : }
    1046             : 
    1047           0 : bool ScRangeList::In( const ScRange& rRange ) const
    1048             : {
    1049           0 :     const_iterator itrEnd = maRanges.end();
    1050             :     const_iterator itr =
    1051           0 :         find_if(maRanges.begin(), itrEnd, FindEnclosingRange<ScRange>(rRange));
    1052           0 :     return itr != itrEnd;
    1053             : }
    1054             : 
    1055           0 : size_t ScRangeList::GetCellCount() const
    1056             : {
    1057           0 :     CountCells func;
    1058           0 :     return for_each(maRanges.begin(), maRanges.end(), func).getCellCount();
    1059             : }
    1060             : 
    1061           0 : ScRange* ScRangeList::Remove(size_t nPos)
    1062             : {
    1063           0 :     if (maRanges.size() <= nPos)
    1064             :         // Out-of-bound condition.  Bail out.
    1065           0 :         return NULL;
    1066             : 
    1067           0 :     iterator itr = maRanges.begin();
    1068           0 :     advance(itr, nPos);
    1069           0 :     ScRange* p = *itr;
    1070           0 :     maRanges.erase(itr);
    1071           0 :     return p;
    1072             : }
    1073             : 
    1074           0 : void ScRangeList::RemoveAll()
    1075             : {
    1076           0 :     for_each(maRanges.begin(), maRanges.end(), ScDeleteObjectByPtr<ScRange>());
    1077           0 :     maRanges.clear();
    1078           0 : }
    1079             : 
    1080           0 : ScRange ScRangeList::Combine() const
    1081             : {
    1082           0 :     if (maRanges.empty())
    1083           0 :         return ScRange();
    1084             : 
    1085           0 :     const_iterator itr = maRanges.begin(), itrEnd = maRanges.end();
    1086           0 :     ScRange aRet = **itr;
    1087           0 :     ++itr;
    1088           0 :     for (; itr != itrEnd; ++itr)
    1089             :     {
    1090           0 :         const ScRange& r = **itr;
    1091           0 :         SCROW nRow1 = r.aStart.Row(), nRow2 = r.aEnd.Row();
    1092           0 :         SCCOL nCol1 = r.aStart.Col(), nCol2 = r.aEnd.Col();
    1093           0 :         SCTAB nTab1 = r.aStart.Tab(), nTab2 = r.aEnd.Tab();
    1094           0 :         if (aRet.aStart.Row() > nRow1)
    1095           0 :             aRet.aStart.SetRow(nRow1);
    1096           0 :         if (aRet.aStart.Col() > nCol1)
    1097           0 :             aRet.aStart.SetCol(nCol1);
    1098           0 :         if (aRet.aStart.Tab() > nTab1)
    1099           0 :             aRet.aStart.SetTab(nTab1);
    1100           0 :         if (aRet.aEnd.Row() < nRow2)
    1101           0 :             aRet.aEnd.SetRow(nRow2);
    1102           0 :         if (aRet.aEnd.Col() < nCol2)
    1103           0 :             aRet.aEnd.SetCol(nCol2);
    1104           0 :         if (aRet.aEnd.Tab() < nTab2)
    1105           0 :             aRet.aEnd.SetTab(nTab2);
    1106             :     }
    1107           0 :     return aRet;
    1108             : }
    1109             : 
    1110           0 : bool ScRangeList::empty() const
    1111             : {
    1112           0 :     return maRanges.empty();
    1113             : }
    1114             : 
    1115           0 : size_t ScRangeList::size() const
    1116             : {
    1117           0 :     return maRanges.size();
    1118             : }
    1119             : 
    1120           0 : ScRange* ScRangeList::operator [](size_t idx)
    1121             : {
    1122           0 :     return maRanges[idx];
    1123             : }
    1124             : 
    1125           0 : const ScRange* ScRangeList::operator [](size_t idx) const
    1126             : {
    1127           0 :     return maRanges[idx];
    1128             : }
    1129             : 
    1130           0 : ScRange* ScRangeList::front()
    1131             : {
    1132           0 :     return maRanges.front();
    1133             : }
    1134             : 
    1135           0 : const ScRange* ScRangeList::front() const
    1136             : {
    1137           0 :     return maRanges.front();
    1138             : }
    1139             : 
    1140           0 : ScRange* ScRangeList::back()
    1141             : {
    1142           0 :     return maRanges.back();
    1143             : }
    1144             : 
    1145           0 : const ScRange* ScRangeList::back() const
    1146             : {
    1147           0 :     return maRanges.back();
    1148             : }
    1149             : 
    1150           0 : void ScRangeList::push_back(ScRange* p)
    1151             : {
    1152           0 :     maRanges.push_back(p);
    1153           0 : }
    1154             : 
    1155           0 : ScAddress ScRangeList::GetTopLeftCorner() const
    1156             : {
    1157           0 :     if(empty())
    1158           0 :         return ScAddress();
    1159             : 
    1160           0 :     ScAddress aAddr = maRanges[0]->aStart;
    1161           0 :     for(size_t i = 1, n = size(); i < n; ++i)
    1162             :     {
    1163           0 :         if(maRanges[i]->aStart < aAddr)
    1164           0 :             aAddr = maRanges[i]->aStart;
    1165             :     }
    1166             : 
    1167           0 :     return aAddr;
    1168             : }
    1169             : 
    1170           0 : ScRangeList ScRangeList::GetIntersectedRange(const ScRange& rRange) const
    1171             : {
    1172           0 :     ScRangeList aReturn;
    1173           0 :     for(const_iterator itr = maRanges.begin(), itrEnd = maRanges.end();
    1174             :             itr != itrEnd; ++itr)
    1175             :     {
    1176           0 :         if((*itr)->Intersects(rRange))
    1177             :         {
    1178             :             SCCOL nColStart1, nColEnd1, nColStart2, nColEnd2;
    1179             :             SCROW nRowStart1, nRowEnd1, nRowStart2, nRowEnd2;
    1180             :             SCTAB nTabStart1, nTabEnd1, nTabStart2, nTabEnd2;
    1181           0 :             (*itr)->GetVars(nColStart1, nRowStart1, nTabStart1,
    1182           0 :                         nColEnd1, nRowEnd1, nTabEnd1);
    1183             :             rRange.GetVars(nColStart2, nRowStart2, nTabStart2,
    1184           0 :                         nColEnd2, nRowEnd2, nTabEnd2);
    1185             : 
    1186           0 :             ScRange aNewRange(std::max<SCCOL>(nColStart1, nColStart2), std::max<SCROW>(nRowStart1, nRowStart2),
    1187           0 :                     std::max<SCTAB>(nTabStart1, nTabStart2), std::min<SCCOL>(nColEnd1, nColEnd2),
    1188           0 :                     std::min<SCROW>(nRowEnd1, nRowEnd2), std::min<SCTAB>(nTabEnd1, nTabEnd2));
    1189           0 :             aReturn.Join(aNewRange);
    1190             :         }
    1191             :     }
    1192             : 
    1193           0 :     return aReturn;
    1194             : }
    1195             : 
    1196             : //  ScRangePairList
    1197           0 : ScRangePairList::~ScRangePairList()
    1198             : {
    1199           0 :     for_each( maPairs.begin(), maPairs.end(), ScDeleteObjectByPtr<ScRangePair>() );
    1200           0 :     maPairs.clear();
    1201           0 : }
    1202             : 
    1203           0 : ScRangePair* ScRangePairList::Remove(size_t nPos)
    1204             : {
    1205           0 :     if (maPairs.size() <= nPos)
    1206             :         // Out-of-bound condition.  Bail out.
    1207           0 :         return NULL;
    1208             : 
    1209           0 :     vector<ScRangePair*>::iterator itr = maPairs.begin();
    1210           0 :     advance(itr, nPos);
    1211           0 :     ScRangePair* p = *itr;
    1212           0 :     maPairs.erase(itr);
    1213           0 :     return p;
    1214             : }
    1215             : 
    1216           0 : ScRangePair* ScRangePairList::Remove( ScRangePair* Adr)
    1217             : {
    1218           0 :     ScRangePair* p = NULL;
    1219             : 
    1220           0 :     if (Adr == NULL) return NULL;
    1221             : 
    1222           0 :     for ( vector<ScRangePair*>::iterator itr = maPairs.begin(); itr < maPairs.end(); ++itr )
    1223             :     {
    1224           0 :         if ( Adr == (p = *itr) )
    1225             :         {
    1226           0 :             maPairs.erase( itr );
    1227           0 :             break;
    1228             :         }
    1229             :     }
    1230           0 :     return p;
    1231             : }
    1232             : 
    1233           0 : bool ScRangePairList::operator==( const ScRangePairList& r ) const
    1234             : {
    1235           0 :     if ( this == &r )
    1236           0 :         return true;                // identical reference
    1237           0 :     if ( maPairs.size() != r.size() )
    1238           0 :         return false;
    1239           0 :     for ( size_t nIdx = 0, nCnt = maPairs.size(); nIdx < nCnt; ++nIdx )
    1240             :     {
    1241           0 :         if ( *maPairs[ nIdx ] != *r[ nIdx ] )
    1242           0 :             return false;           // auch andere Reihenfolge ist ungleich
    1243             :     }
    1244           0 :     return true;
    1245             : }
    1246             : 
    1247           0 : ScRangePair* ScRangePairList::operator [](size_t idx)
    1248             : {
    1249           0 :     return maPairs[idx];
    1250             : }
    1251             : 
    1252           0 : const ScRangePair* ScRangePairList::operator [](size_t idx) const
    1253             : {
    1254           0 :     return maPairs[idx];
    1255             : }
    1256             : 
    1257           0 : size_t ScRangePairList::size() const
    1258             : {
    1259           0 :     return maPairs.size();
    1260             : }
    1261             : 
    1262           0 : bool ScRangePairList::UpdateReference( UpdateRefMode eUpdateRefMode,
    1263             :                                     ScDocument* pDoc, const ScRange& rWhere,
    1264             :                                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    1265             : {
    1266           0 :     bool bChanged = false;
    1267           0 :     if ( !maPairs.empty() )
    1268             :     {
    1269             :         SCCOL nCol1;
    1270             :         SCROW nRow1;
    1271             :         SCTAB nTab1;
    1272             :         SCCOL nCol2;
    1273             :         SCROW nRow2;
    1274             :         SCTAB nTab2;
    1275           0 :         rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    1276           0 :         for ( size_t i = 0, nPairs = maPairs.size(); i < nPairs; ++i )
    1277             :         {
    1278           0 :             ScRangePair* pR = maPairs[ i ];
    1279           0 :             for ( sal_uInt16 j=0; j<2; j++ )
    1280             :             {
    1281           0 :                 ScRange& rRange = pR->GetRange(j);
    1282             :                 SCCOL theCol1;
    1283             :                 SCROW theRow1;
    1284             :                 SCTAB theTab1;
    1285             :                 SCCOL theCol2;
    1286             :                 SCROW theRow2;
    1287             :                 SCTAB theTab2;
    1288           0 :                 rRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
    1289           0 :                 if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
    1290             :                         nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
    1291             :                         nDx, nDy, nDz,
    1292           0 :                         theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 )
    1293             :                         != UR_NOTHING )
    1294             :                 {
    1295           0 :                     bChanged = true;
    1296           0 :                     rRange.aStart.Set( theCol1, theRow1, theTab1 );
    1297           0 :                     rRange.aEnd.Set( theCol2, theRow2, theTab2 );
    1298             :                 }
    1299             :             }
    1300             :         }
    1301             :     }
    1302           0 :     return bChanged;
    1303             : }
    1304             : 
    1305             : // Delete entries that have the labels (first range) on nTab
    1306           0 : void ScRangePairList::DeleteOnTab( SCTAB nTab )
    1307             : {
    1308           0 :     size_t nListCount = maPairs.size();
    1309           0 :     size_t nPos = 0;
    1310           0 :     while ( nPos < nListCount )
    1311             :     {
    1312           0 :         ScRangePair* pR = maPairs[  nPos ];
    1313           0 :         ScRange aRange = pR->GetRange(0);
    1314           0 :         if ( aRange.aStart.Tab() == nTab && aRange.aEnd.Tab() == nTab )
    1315             :         {
    1316           0 :             Remove( nPos );
    1317           0 :             delete pR;
    1318           0 :             nListCount = maPairs.size();
    1319             :         }
    1320             :         else
    1321           0 :             ++nPos;
    1322             :     }
    1323           0 : }
    1324             : 
    1325           0 : ScRangePair* ScRangePairList::Find( const ScAddress& rAdr ) const
    1326             : {
    1327           0 :     for ( size_t j = 0, nListCount = maPairs.size(); j < nListCount; j++ )
    1328             :     {
    1329           0 :         ScRangePair* pR = maPairs[ j ];
    1330           0 :         if ( pR->GetRange(0).In( rAdr ) )
    1331           0 :             return pR;
    1332             :     }
    1333           0 :     return NULL;
    1334             : }
    1335             : 
    1336           0 : ScRangePair* ScRangePairList::Find( const ScRange& rRange ) const
    1337             : {
    1338           0 :     for ( size_t j = 0, nListCount = maPairs.size(); j < nListCount; j++ )
    1339             :     {
    1340           0 :         ScRangePair* pR = maPairs[ j ];
    1341           0 :         if ( pR->GetRange(0) == rRange )
    1342           0 :             return pR;
    1343             :     }
    1344           0 :     return NULL;
    1345             : }
    1346             : 
    1347           0 : ScRangePairList* ScRangePairList::Clone() const
    1348             : {
    1349           0 :     ScRangePairList* pNew = new ScRangePairList;
    1350           0 :     for ( size_t j = 0, nListCount = maPairs.size(); j < nListCount; j++ )
    1351             :     {
    1352           0 :         pNew->Append( *maPairs[ j ] );
    1353             :     }
    1354           0 :     return pNew;
    1355             : }
    1356             : 
    1357             : struct ScRangePairNameSort
    1358             : {
    1359             :     ScRangePair*    pPair;
    1360             :     ScDocument*     pDoc;
    1361             : };
    1362             : 
    1363             : extern "C"
    1364           0 : int SAL_CALL ScRangePairList_QsortNameCompare( const void* p1, const void* p2 )
    1365             : {
    1366           0 :     const ScRangePairNameSort* ps1 = (const ScRangePairNameSort*)p1;
    1367           0 :     const ScRangePairNameSort* ps2 = (const ScRangePairNameSort*)p2;
    1368           0 :     const ScAddress& rStartPos1 = ps1->pPair->GetRange(0).aStart;
    1369           0 :     const ScAddress& rStartPos2 = ps2->pPair->GetRange(0).aStart;
    1370           0 :     OUString aStr1, aStr2;
    1371             :     sal_Int32 nComp;
    1372           0 :     if ( rStartPos1.Tab() == rStartPos2.Tab() )
    1373           0 :         nComp = 0;
    1374             :     else
    1375             :     {
    1376           0 :         ps1->pDoc->GetName( rStartPos1.Tab(), aStr1 );
    1377           0 :         ps2->pDoc->GetName( rStartPos2.Tab(), aStr2 );
    1378           0 :         nComp = ScGlobal::GetCollator()->compareString( aStr1, aStr2 );
    1379             :     }
    1380           0 :     if (nComp < 0)
    1381             :     {
    1382           0 :         return -1;
    1383             :     }
    1384           0 :     else if (nComp > 0)
    1385             :     {
    1386           0 :         return 1;
    1387             :     }
    1388             :     else
    1389             :     {
    1390             :         // gleiche Tabs
    1391           0 :         if ( rStartPos1.Col() < rStartPos2.Col() )
    1392           0 :             return -1;
    1393           0 :         if ( rStartPos1.Col() > rStartPos2.Col() )
    1394           0 :             return 1;
    1395             :         // gleiche Cols
    1396           0 :         if ( rStartPos1.Row() < rStartPos2.Row() )
    1397           0 :             return -1;
    1398           0 :         if ( rStartPos1.Row() > rStartPos2.Row() )
    1399           0 :             return 1;
    1400             :         // erste Ecke gleich, zweite Ecke
    1401             :         {
    1402           0 :             const ScAddress& rEndPos1 = ps1->pPair->GetRange(0).aEnd;
    1403           0 :             const ScAddress& rEndPos2 = ps2->pPair->GetRange(0).aEnd;
    1404           0 :             if ( rEndPos1.Tab() == rEndPos2.Tab() )
    1405           0 :                 nComp = 0;
    1406             :             else
    1407             :             {
    1408           0 :                 ps1->pDoc->GetName( rEndPos1.Tab(), aStr1 );
    1409           0 :                 ps2->pDoc->GetName( rEndPos2.Tab(), aStr2 );
    1410           0 :                 nComp = ScGlobal::GetCollator()->compareString( aStr1, aStr2 );
    1411             :             }
    1412           0 :             if (nComp < 0)
    1413             :             {
    1414           0 :                 return -1;
    1415             :             }
    1416           0 :             else if (nComp > 0)
    1417             :             {
    1418           0 :                 return 1;
    1419             :             }
    1420             :             else
    1421             :             {
    1422             :                 // gleiche Tabs
    1423           0 :                 if ( rEndPos1.Col() < rEndPos2.Col() )
    1424           0 :                     return -1;
    1425           0 :                 if ( rEndPos1.Col() > rEndPos2.Col() )
    1426           0 :                     return 1;
    1427             :                 // gleiche Cols
    1428           0 :                 if ( rEndPos1.Row() < rEndPos2.Row() )
    1429           0 :                     return -1;
    1430           0 :                 if ( rEndPos1.Row() > rEndPos2.Row() )
    1431           0 :                     return 1;
    1432           0 :                 return 0;
    1433             :             }
    1434             :         }
    1435             :     }
    1436             : #ifndef _MSC_VER // MSVC is good enough to warn about unreachable code here.
    1437             :                  // Or stupid enough to bother warning about it, depending
    1438             :                  // on your point of view.
    1439           0 :     return 0; // just in case
    1440             : #endif
    1441             : }
    1442             : 
    1443           0 : void ScRangePairList::Join( const ScRangePair& r, bool bIsInList )
    1444             : {
    1445           0 :     if ( maPairs.empty() )
    1446             :     {
    1447           0 :         Append( r );
    1448           0 :         return ;
    1449             :     }
    1450           0 :     const ScRange& r1 = r.GetRange(0);
    1451           0 :     const ScRange& r2 = r.GetRange(1);
    1452           0 :     SCCOL nCol1 = r1.aStart.Col();
    1453           0 :     SCROW nRow1 = r1.aStart.Row();
    1454           0 :     SCTAB nTab1 = r1.aStart.Tab();
    1455           0 :     SCCOL nCol2 = r1.aEnd.Col();
    1456           0 :     SCROW nRow2 = r1.aEnd.Row();
    1457           0 :     SCTAB nTab2 = r1.aEnd.Tab();
    1458           0 :     ScRangePair* pOver = (ScRangePair*) &r;     // fies aber wahr wenn bInList
    1459           0 :     size_t nOldPos = 0;
    1460           0 :     if ( bIsInList )
    1461             :     {
    1462             :         // Find the current position of this range.
    1463           0 :         for ( size_t i = 0, nPairs = maPairs.size(); i < nPairs; ++i )
    1464             :         {
    1465           0 :             if ( maPairs[i] == pOver )
    1466             :             {
    1467           0 :                 nOldPos = i;
    1468           0 :                 break;
    1469             :             }
    1470             :         }
    1471             :     }
    1472           0 :     bool bJoinedInput = false;
    1473             : 
    1474           0 :     for ( size_t i = 0; i < maPairs.size() && pOver; ++i )
    1475             :     {
    1476           0 :         ScRangePair* p = maPairs[ i ];
    1477           0 :         if ( p == pOver )
    1478           0 :             continue;           // derselbe, weiter mit dem naechsten
    1479           0 :         bool bJoined = false;
    1480           0 :         ScRange& rp1 = p->GetRange(0);
    1481           0 :         ScRange& rp2 = p->GetRange(1);
    1482           0 :         if ( rp2 == r2 )
    1483             :         {   // nur wenn Range2 gleich ist
    1484           0 :             if ( rp1.In( r1 ) )
    1485             :             {   // RangePair r in RangePair p enthalten oder identisch
    1486           0 :                 if ( bIsInList )
    1487           0 :                     bJoined = true;     // weg mit RangePair r
    1488             :                 else
    1489             :                 {   // das war's dann
    1490           0 :                     bJoinedInput = true;    // nicht anhaengen
    1491           0 :                     break;  // for
    1492             :                 }
    1493             :             }
    1494           0 :             else if ( r1.In( rp1 ) )
    1495             :             {   // RangePair p in RangePair r enthalten, r zum neuen RangePair machen
    1496           0 :                 *p = r;
    1497           0 :                 bJoined = true;
    1498             :             }
    1499             :         }
    1500           0 :         if ( !bJoined && rp1.aStart.Tab() == nTab1 && rp1.aEnd.Tab() == nTab2
    1501           0 :           && rp2.aStart.Tab() == r2.aStart.Tab()
    1502           0 :           && rp2.aEnd.Tab() == r2.aEnd.Tab() )
    1503             :         {   // 2D, Range2 muss genauso nebeneinander liegen wie Range1
    1504           0 :             if ( rp1.aStart.Col() == nCol1 && rp1.aEnd.Col() == nCol2
    1505           0 :               && rp2.aStart.Col() == r2.aStart.Col()
    1506           0 :               && rp2.aEnd.Col() == r2.aEnd.Col() )
    1507             :             {
    1508           0 :                 if ( rp1.aStart.Row() == nRow2+1
    1509           0 :                   && rp2.aStart.Row() == r2.aEnd.Row()+1 )
    1510             :                 {   // oben
    1511           0 :                     rp1.aStart.SetRow( nRow1 );
    1512           0 :                     rp2.aStart.SetRow( r2.aStart.Row() );
    1513           0 :                     bJoined = true;
    1514             :                 }
    1515           0 :                 else if ( rp1.aEnd.Row() == nRow1-1
    1516           0 :                   && rp2.aEnd.Row() == r2.aStart.Row()-1 )
    1517             :                 {   // unten
    1518           0 :                     rp1.aEnd.SetRow( nRow2 );
    1519           0 :                     rp2.aEnd.SetRow( r2.aEnd.Row() );
    1520           0 :                     bJoined = true;
    1521             :                 }
    1522             :             }
    1523           0 :             else if ( rp1.aStart.Row() == nRow1 && rp1.aEnd.Row() == nRow2
    1524           0 :               && rp2.aStart.Row() == r2.aStart.Row()
    1525           0 :               && rp2.aEnd.Row() == r2.aEnd.Row() )
    1526             :             {
    1527           0 :                 if ( rp1.aStart.Col() == nCol2+1
    1528           0 :                   && rp2.aStart.Col() == r2.aEnd.Col()+1 )
    1529             :                 {   // links
    1530           0 :                     rp1.aStart.SetCol( nCol1 );
    1531           0 :                     rp2.aStart.SetCol( r2.aStart.Col() );
    1532           0 :                     bJoined = true;
    1533             :                 }
    1534           0 :                 else if ( rp1.aEnd.Col() == nCol1-1
    1535           0 :                   && rp2.aEnd.Col() == r2.aEnd.Col()-1 )
    1536             :                 {   // rechts
    1537           0 :                     rp1.aEnd.SetCol( nCol2 );
    1538           0 :                     rp2.aEnd.SetCol( r2.aEnd.Col() );
    1539           0 :                     bJoined = true;
    1540             :                 }
    1541             :             }
    1542             :         }
    1543           0 :         if ( bJoined )
    1544             :         {
    1545           0 :             if ( bIsInList )
    1546             :             {   // innerhalb der Liste RangePair loeschen
    1547           0 :                 Remove( nOldPos );
    1548           0 :                 i--;
    1549           0 :                 delete pOver;
    1550           0 :                 pOver = NULL;
    1551           0 :                 if ( nOldPos )
    1552           0 :                     nOldPos--;          // Seek richtig aufsetzen
    1553             :             }
    1554           0 :             bJoinedInput = true;
    1555           0 :             Join( *p, true );           // rekursiv!
    1556             :         }
    1557             :     }
    1558           0 :     if ( !bIsInList && !bJoinedInput )
    1559           0 :         Append( r );
    1560             : }
    1561             : 
    1562           0 : ScRangePair** ScRangePairList::CreateNameSortedArray( size_t& nListCount,
    1563             :         ScDocument* pDoc ) const
    1564             : {
    1565           0 :     nListCount = maPairs.size();
    1566             :     OSL_ENSURE( nListCount * sizeof(ScRangePairNameSort) <= (size_t)~0x1F,
    1567             :         "ScRangePairList::CreateNameSortedArray nListCount * sizeof(ScRangePairNameSort) > (size_t)~0x1F" );
    1568             :     ScRangePairNameSort* pSortArray = (ScRangePairNameSort*)
    1569           0 :         new sal_uInt8 [ nListCount * sizeof(ScRangePairNameSort) ];
    1570             :     sal_uLong j;
    1571           0 :     for ( j=0; j < nListCount; j++ )
    1572             :     {
    1573           0 :         pSortArray[j].pPair = maPairs[ j ];
    1574           0 :         pSortArray[j].pDoc = pDoc;
    1575             :     }
    1576           0 :     qsort( (void*)pSortArray, nListCount, sizeof(ScRangePairNameSort), &ScRangePairList_QsortNameCompare );
    1577             :     // ScRangePair Pointer aufruecken
    1578           0 :     ScRangePair** ppSortArray = (ScRangePair**)pSortArray;
    1579           0 :     for ( j=0; j < nListCount; j++ )
    1580             :     {
    1581           0 :         ppSortArray[j] = pSortArray[j].pPair;
    1582             :     }
    1583           0 :     return ppSortArray;
    1584             : }
    1585             : 
    1586             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10