| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| |
| //------------------------------------------------------------------------ |
| |
| #define SC_RANGELST_CXX //fuer ICC |
| |
| #include <tools/debug.hxx> |
| #include <stdlib.h> // qsort |
| #include <unotools/collatorwrapper.hxx> |
| |
| #include "rangelst.hxx" |
| #include "document.hxx" |
| #include "refupdat.hxx" |
| #include "rechead.hxx" |
| #include "compiler.hxx" |
| |
| // === ScRangeList ==================================================== |
| |
| ScRangeList::~ScRangeList() |
| { |
| for ( ScRangePtr pR = First(); pR; pR = Next() ) |
| delete pR; |
| } |
| |
| void ScRangeList::RemoveAll() |
| { |
| for ( ScRangePtr pR = First(); pR; pR = Next() ) |
| delete pR; |
| Clear(); |
| } |
| |
| sal_uInt16 ScRangeList::Parse( const String& rStr, ScDocument* pDoc, sal_uInt16 nMask, |
| formula::FormulaGrammar::AddressConvention eConv, |
| sal_Unicode cDelimiter ) |
| { |
| if ( rStr.Len() ) |
| { |
| if (!cDelimiter) |
| cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); |
| |
| nMask |= SCA_VALID; // falls das jemand vergessen sollte |
| sal_uInt16 nResult = (sal_uInt16)~0; // alle Bits setzen |
| ScRange aRange; |
| String aOne; |
| SCTAB nTab = 0; |
| if ( pDoc ) |
| { |
| //! erste markierte Tabelle gibts nicht mehr am Dokument |
| //! -> uebergeben? oder spaeter an den Ranges setzen |
| } |
| else |
| nTab = 0; |
| sal_uInt16 nTCount = rStr.GetTokenCount( cDelimiter ); |
| for ( sal_uInt16 i=0; i<nTCount; i++ ) |
| { |
| aOne = rStr.GetToken( i, cDelimiter ); |
| // FIXME : broken for Lotus |
| if ( aOne.Search( ':' ) == STRING_NOTFOUND ) |
| { // Range muss es sein |
| String aStrTmp( aOne ); |
| aOne += ':'; |
| aOne += aStrTmp; |
| } |
| aRange.aStart.SetTab( nTab ); // Default Tab wenn nicht angegeben |
| sal_uInt16 nRes = aRange.Parse( aOne, pDoc, eConv ); |
| if ( (nRes & nMask) == nMask ) |
| Append( aRange ); |
| nResult &= nRes; // alle gemeinsamen Bits bleiben erhalten |
| } |
| return nResult; // SCA_VALID gesetzt wenn alle ok |
| } |
| else |
| return 0; |
| } |
| |
| |
| void ScRangeList::Format( String& rStr, sal_uInt16 nFlags, ScDocument* pDoc, |
| formula::FormulaGrammar::AddressConvention eConv, |
| sal_Unicode cDelimiter ) const |
| { |
| rStr.Erase(); |
| |
| if (!cDelimiter) |
| cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); |
| |
| sal_uLong nCnt = Count(); |
| for ( sal_uLong nIdx = 0; nIdx < nCnt; nIdx++ ) |
| { |
| String aStr; |
| GetObject( nIdx )->Format( aStr, nFlags, pDoc, eConv ); |
| if ( nIdx ) |
| rStr += cDelimiter; |
| rStr += aStr; |
| } |
| } |
| |
| |
| void ScRangeList::Join( const ScRange& r, sal_Bool bIsInList ) |
| { |
| if ( !Count() ) |
| { |
| Append( r ); |
| return ; |
| } |
| SCCOL nCol1 = r.aStart.Col(); |
| SCROW nRow1 = r.aStart.Row(); |
| SCTAB nTab1 = r.aStart.Tab(); |
| SCCOL nCol2 = r.aEnd.Col(); |
| SCROW nRow2 = r.aEnd.Row(); |
| SCTAB nTab2 = r.aEnd.Tab(); |
| ScRangePtr pOver = (ScRangePtr) &r; // fies aber wahr wenn bInList |
| sal_uLong nOldPos = 0; |
| if ( bIsInList ) |
| { // merken um ggbf. zu loeschen bzw. wiederherzustellen |
| nOldPos = GetPos( pOver ); |
| } |
| sal_Bool bJoinedInput = sal_False; |
| for ( ScRangePtr p = First(); p && pOver; p = Next() ) |
| { |
| if ( p == pOver ) |
| continue; // derselbe, weiter mit dem naechsten |
| sal_Bool bJoined = sal_False; |
| if ( p->In( r ) ) |
| { // Range r in Range p enthalten oder identisch |
| if ( bIsInList ) |
| bJoined = sal_True; // weg mit Range r |
| else |
| { // das war's dann |
| bJoinedInput = sal_True; // nicht anhaengen |
| break; // for |
| } |
| } |
| else if ( r.In( *p ) ) |
| { // Range p in Range r enthalten, r zum neuen Range machen |
| *p = r; |
| bJoined = sal_True; |
| } |
| if ( !bJoined && p->aStart.Tab() == nTab1 && p->aEnd.Tab() == nTab2 ) |
| { // 2D |
| if ( p->aStart.Col() == nCol1 && p->aEnd.Col() == nCol2 ) |
| { |
| if ( p->aStart.Row() == nRow2+1 ) |
| { // oben |
| p->aStart.SetRow( nRow1 ); |
| bJoined = sal_True; |
| } |
| else if ( p->aEnd.Row() == nRow1-1 ) |
| { // unten |
| p->aEnd.SetRow( nRow2 ); |
| bJoined = sal_True; |
| } |
| } |
| else if ( p->aStart.Row() == nRow1 && p->aEnd.Row() == nRow2 ) |
| { |
| if ( p->aStart.Col() == nCol2+1 ) |
| { // links |
| p->aStart.SetCol( nCol1 ); |
| bJoined = sal_True; |
| } |
| else if ( p->aEnd.Col() == nCol1-1 ) |
| { // rechts |
| p->aEnd.SetCol( nCol2 ); |
| bJoined = sal_True; |
| } |
| } |
| } |
| if ( bJoined ) |
| { |
| if ( bIsInList ) |
| { // innerhalb der Liste Range loeschen |
| Remove( nOldPos ); |
| delete pOver; |
| pOver = NULL; |
| if ( nOldPos ) |
| nOldPos--; // Seek richtig aufsetzen |
| } |
| bJoinedInput = sal_True; |
| Join( *p, sal_True ); // rekursiv! |
| } |
| } |
| if ( bIsInList ) |
| Seek( nOldPos ); |
| else if ( !bJoinedInput ) |
| Append( r ); |
| } |
| |
| |
| sal_Bool ScRangeList::operator==( const ScRangeList& r ) const |
| { |
| if ( this == &r ) |
| return sal_True; // identische Referenz |
| if ( Count() != r.Count() ) |
| return sal_False; |
| sal_uLong nCnt = Count(); |
| for ( sal_uLong nIdx = 0; nIdx < nCnt; nIdx++ ) |
| { |
| if ( *GetObject( nIdx ) != *r.GetObject( nIdx ) ) |
| return sal_False; // auch andere Reihenfolge ist ungleich |
| } |
| return sal_True; |
| } |
| |
| sal_Bool ScRangeList::operator!=( const ScRangeList& r ) const |
| { |
| return !operator==( r ); |
| } |
| |
| sal_Bool ScRangeList::UpdateReference( UpdateRefMode eUpdateRefMode, |
| ScDocument* pDoc, const ScRange& rWhere, |
| SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) |
| { |
| sal_Bool bChanged = sal_False; |
| if ( Count() ) |
| { |
| SCCOL nCol1; |
| SCROW nRow1; |
| SCTAB nTab1; |
| SCCOL nCol2; |
| SCROW nRow2; |
| SCTAB nTab2; |
| rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); |
| for ( ScRange* pR = First(); pR; pR = Next() ) |
| { |
| SCCOL theCol1; |
| SCROW theRow1; |
| SCTAB theTab1; |
| SCCOL theCol2; |
| SCROW theRow2; |
| SCTAB theTab2; |
| pR->GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); |
| if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, |
| nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, |
| nDx, nDy, nDz, |
| theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) |
| != UR_NOTHING ) |
| { |
| bChanged = sal_True; |
| pR->aStart.Set( theCol1, theRow1, theTab1 ); |
| pR->aEnd.Set( theCol2, theRow2, theTab2 ); |
| } |
| } |
| } |
| return bChanged; |
| } |
| |
| |
| ScRange* ScRangeList::Find( const ScAddress& rAdr ) const |
| { |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| { |
| ScRange* pR = GetObject( j ); |
| if ( pR->In( rAdr ) ) |
| return pR; |
| } |
| return NULL; |
| } |
| |
| |
| ScRangeList::ScRangeList( const ScRangeList& rList ) : |
| ScRangeListBase(), |
| SvRefBase() |
| { |
| sal_uLong nListCount = rList.Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| Append( *rList.GetObject( j ) ); |
| } |
| |
| |
| ScRangeList& ScRangeList::operator=(const ScRangeList& rList) |
| { |
| RemoveAll(); |
| |
| sal_uLong nListCount = rList.Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| Append( *rList.GetObject( j ) ); |
| |
| return *this; |
| } |
| |
| |
| sal_Bool ScRangeList::Intersects( const ScRange& rRange ) const |
| { |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| if ( GetObject(j)->Intersects( rRange ) ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| |
| sal_Bool ScRangeList::In( const ScRange& rRange ) const |
| { |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| if ( GetObject(j)->In( rRange ) ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| |
| sal_uLong ScRangeList::GetCellCount() const |
| { |
| sal_uLong nCellCount = 0; |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| { |
| ScRange* pR = GetObject( j ); |
| nCellCount += sal_uLong(pR->aEnd.Col() - pR->aStart.Col() + 1) |
| * sal_uLong(pR->aEnd.Row() - pR->aStart.Row() + 1) |
| * sal_uLong(pR->aEnd.Tab() - pR->aStart.Tab() + 1); |
| } |
| return nCellCount; |
| } |
| |
| |
| // === ScRangePairList ==================================================== |
| |
| ScRangePairList::~ScRangePairList() |
| { |
| for ( ScRangePair* pR = First(); pR; pR = Next() ) |
| delete pR; |
| } |
| |
| |
| void ScRangePairList::Join( const ScRangePair& r, sal_Bool bIsInList ) |
| { |
| if ( !Count() ) |
| { |
| Append( r ); |
| return ; |
| } |
| const ScRange& r1 = r.GetRange(0); |
| const ScRange& r2 = r.GetRange(1); |
| SCCOL nCol1 = r1.aStart.Col(); |
| SCROW nRow1 = r1.aStart.Row(); |
| SCTAB nTab1 = r1.aStart.Tab(); |
| SCCOL nCol2 = r1.aEnd.Col(); |
| SCROW nRow2 = r1.aEnd.Row(); |
| SCTAB nTab2 = r1.aEnd.Tab(); |
| ScRangePair* pOver = (ScRangePair*) &r; // fies aber wahr wenn bInList |
| sal_uLong nOldPos = 0; |
| if ( bIsInList ) |
| { // merken um ggbf. zu loeschen bzw. wiederherzustellen |
| nOldPos = GetPos( pOver ); |
| } |
| sal_Bool bJoinedInput = sal_False; |
| for ( ScRangePair* p = First(); p && pOver; p = Next() ) |
| { |
| if ( p == pOver ) |
| continue; // derselbe, weiter mit dem naechsten |
| sal_Bool bJoined = sal_False; |
| ScRange& rp1 = p->GetRange(0); |
| ScRange& rp2 = p->GetRange(1); |
| if ( rp2 == r2 ) |
| { // nur wenn Range2 gleich ist |
| if ( rp1.In( r1 ) ) |
| { // RangePair r in RangePair p enthalten oder identisch |
| if ( bIsInList ) |
| bJoined = sal_True; // weg mit RangePair r |
| else |
| { // das war's dann |
| bJoinedInput = sal_True; // nicht anhaengen |
| break; // for |
| } |
| } |
| else if ( r1.In( rp1 ) ) |
| { // RangePair p in RangePair r enthalten, r zum neuen RangePair machen |
| *p = r; |
| bJoined = sal_True; |
| } |
| } |
| if ( !bJoined && rp1.aStart.Tab() == nTab1 && rp1.aEnd.Tab() == nTab2 |
| && rp2.aStart.Tab() == r2.aStart.Tab() |
| && rp2.aEnd.Tab() == r2.aEnd.Tab() ) |
| { // 2D, Range2 muss genauso nebeneinander liegen wie Range1 |
| if ( rp1.aStart.Col() == nCol1 && rp1.aEnd.Col() == nCol2 |
| && rp2.aStart.Col() == r2.aStart.Col() |
| && rp2.aEnd.Col() == r2.aEnd.Col() ) |
| { |
| if ( rp1.aStart.Row() == nRow2+1 |
| && rp2.aStart.Row() == r2.aEnd.Row()+1 ) |
| { // oben |
| rp1.aStart.SetRow( nRow1 ); |
| rp2.aStart.SetRow( r2.aStart.Row() ); |
| bJoined = sal_True; |
| } |
| else if ( rp1.aEnd.Row() == nRow1-1 |
| && rp2.aEnd.Row() == r2.aStart.Row()-1 ) |
| { // unten |
| rp1.aEnd.SetRow( nRow2 ); |
| rp2.aEnd.SetRow( r2.aEnd.Row() ); |
| bJoined = sal_True; |
| } |
| } |
| else if ( rp1.aStart.Row() == nRow1 && rp1.aEnd.Row() == nRow2 |
| && rp2.aStart.Row() == r2.aStart.Row() |
| && rp2.aEnd.Row() == r2.aEnd.Row() ) |
| { |
| if ( rp1.aStart.Col() == nCol2+1 |
| && rp2.aStart.Col() == r2.aEnd.Col()+1 ) |
| { // links |
| rp1.aStart.SetCol( nCol1 ); |
| rp2.aStart.SetCol( r2.aStart.Col() ); |
| bJoined = sal_True; |
| } |
| else if ( rp1.aEnd.Col() == nCol1-1 |
| && rp2.aEnd.Col() == r2.aEnd.Col()-1 ) |
| { // rechts |
| rp1.aEnd.SetCol( nCol2 ); |
| rp2.aEnd.SetCol( r2.aEnd.Col() ); |
| bJoined = sal_True; |
| } |
| } |
| } |
| if ( bJoined ) |
| { |
| if ( bIsInList ) |
| { // innerhalb der Liste RangePair loeschen |
| Remove( nOldPos ); |
| delete pOver; |
| pOver = NULL; |
| if ( nOldPos ) |
| nOldPos--; // Seek richtig aufsetzen |
| } |
| bJoinedInput = sal_True; |
| Join( *p, sal_True ); // rekursiv! |
| } |
| } |
| if ( bIsInList ) |
| Seek( nOldPos ); |
| else if ( !bJoinedInput ) |
| Append( r ); |
| } |
| |
| |
| sal_Bool ScRangePairList::operator==( const ScRangePairList& r ) const |
| { |
| if ( this == &r ) |
| return sal_True; // identische Referenz |
| if ( Count() != r.Count() ) |
| return sal_False; |
| sal_uLong nCnt = Count(); |
| for ( sal_uLong nIdx = 0; nIdx < nCnt; nIdx++ ) |
| { |
| if ( *GetObject( nIdx ) != *r.GetObject( nIdx ) ) |
| return sal_False; // auch andere Reihenfolge ist ungleich |
| } |
| return sal_True; |
| } |
| |
| |
| sal_Bool ScRangePairList::UpdateReference( UpdateRefMode eUpdateRefMode, |
| ScDocument* pDoc, const ScRange& rWhere, |
| SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) |
| { |
| sal_Bool bChanged = sal_False; |
| if ( Count() ) |
| { |
| SCCOL nCol1; |
| SCROW nRow1; |
| SCTAB nTab1; |
| SCCOL nCol2; |
| SCROW nRow2; |
| SCTAB nTab2; |
| rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); |
| for ( ScRangePair* pR = First(); pR; pR = Next() ) |
| { |
| for ( sal_uInt16 j=0; j<2; j++ ) |
| { |
| ScRange& rRange = pR->GetRange(j); |
| SCCOL theCol1; |
| SCROW theRow1; |
| SCTAB theTab1; |
| SCCOL theCol2; |
| SCROW theRow2; |
| SCTAB theTab2; |
| rRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); |
| if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, |
| nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, |
| nDx, nDy, nDz, |
| theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) |
| != UR_NOTHING ) |
| { |
| bChanged = sal_True; |
| rRange.aStart.Set( theCol1, theRow1, theTab1 ); |
| rRange.aEnd.Set( theCol2, theRow2, theTab2 ); |
| } |
| } |
| } |
| } |
| return bChanged; |
| } |
| |
| |
| void ScRangePairList::DeleteOnTab( SCTAB nTab ) |
| { |
| // Delete entries that have the labels (first range) on nTab |
| |
| sal_uLong nListCount = Count(); |
| sal_uLong nPos = 0; |
| while ( nPos < nListCount ) |
| { |
| ScRangePair* pR = GetObject( nPos ); |
| ScRange aRange = pR->GetRange(0); |
| if ( aRange.aStart.Tab() == nTab && aRange.aEnd.Tab() == nTab ) |
| { |
| Remove( nPos ); |
| delete pR; |
| nListCount = Count(); |
| } |
| else |
| ++nPos; |
| } |
| } |
| |
| |
| ScRangePair* ScRangePairList::Find( const ScAddress& rAdr ) const |
| { |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| { |
| ScRangePair* pR = GetObject( j ); |
| if ( pR->GetRange(0).In( rAdr ) ) |
| return pR; |
| } |
| return NULL; |
| } |
| |
| |
| ScRangePair* ScRangePairList::Find( const ScRange& rRange ) const |
| { |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| { |
| ScRangePair* pR = GetObject( j ); |
| if ( pR->GetRange(0) == rRange ) |
| return pR; |
| } |
| return NULL; |
| } |
| |
| |
| ScRangePairList* ScRangePairList::Clone() const |
| { |
| ScRangePairList* pNew = new ScRangePairList; |
| sal_uLong nListCount = Count(); |
| for ( sal_uLong j = 0; j < nListCount; j++ ) |
| { |
| pNew->Append( *GetObject( j ) ); |
| } |
| return pNew; |
| } |
| |
| |
| struct ScRangePairNameSort |
| { |
| ScRangePair* pPair; |
| ScDocument* pDoc; |
| }; |
| |
| |
| extern "C" int |
| #ifdef WNT |
| __cdecl |
| #endif |
| ScRangePairList_QsortNameCompare( const void* p1, const void* p2 ) |
| { |
| const ScRangePairNameSort* ps1 = (const ScRangePairNameSort*)p1; |
| const ScRangePairNameSort* ps2 = (const ScRangePairNameSort*)p2; |
| const ScAddress& rStartPos1 = ps1->pPair->GetRange(0).aStart; |
| const ScAddress& rStartPos2 = ps2->pPair->GetRange(0).aStart; |
| String aStr1, aStr2; |
| sal_Int32 nComp; |
| if ( rStartPos1.Tab() == rStartPos2.Tab() ) |
| nComp = COMPARE_EQUAL; |
| else |
| { |
| ps1->pDoc->GetName( rStartPos1.Tab(), aStr1 ); |
| ps2->pDoc->GetName( rStartPos2.Tab(), aStr2 ); |
| nComp = ScGlobal::GetCollator()->compareString( aStr1, aStr2 ); |
| } |
| switch ( nComp ) |
| { |
| case COMPARE_LESS: |
| return -1; |
| //break; |
| case COMPARE_GREATER: |
| return 1; |
| //break; |
| default: |
| // gleiche Tabs |
| if ( rStartPos1.Col() < rStartPos2.Col() ) |
| return -1; |
| if ( rStartPos1.Col() > rStartPos2.Col() ) |
| return 1; |
| // gleiche Cols |
| if ( rStartPos1.Row() < rStartPos2.Row() ) |
| return -1; |
| if ( rStartPos1.Row() > rStartPos2.Row() ) |
| return 1; |
| // erste Ecke gleich, zweite Ecke |
| { |
| const ScAddress& rEndPos1 = ps1->pPair->GetRange(0).aEnd; |
| const ScAddress& rEndPos2 = ps2->pPair->GetRange(0).aEnd; |
| if ( rEndPos1.Tab() == rEndPos2.Tab() ) |
| nComp = COMPARE_EQUAL; |
| else |
| { |
| ps1->pDoc->GetName( rEndPos1.Tab(), aStr1 ); |
| ps2->pDoc->GetName( rEndPos2.Tab(), aStr2 ); |
| nComp = ScGlobal::GetCollator()->compareString( aStr1, aStr2 ); |
| } |
| switch ( nComp ) |
| { |
| case COMPARE_LESS: |
| return -1; |
| //break; |
| case COMPARE_GREATER: |
| return 1; |
| //break; |
| default: |
| // gleiche Tabs |
| if ( rEndPos1.Col() < rEndPos2.Col() ) |
| return -1; |
| if ( rEndPos1.Col() > rEndPos2.Col() ) |
| return 1; |
| // gleiche Cols |
| if ( rEndPos1.Row() < rEndPos2.Row() ) |
| return -1; |
| if ( rEndPos1.Row() > rEndPos2.Row() ) |
| return 1; |
| return 0; |
| } |
| } |
| return 0; |
| } |
| return 0; // just in case |
| } |
| |
| |
| ScRangePair** ScRangePairList::CreateNameSortedArray( sal_uLong& nListCount, |
| ScDocument* pDoc ) const |
| { |
| nListCount = Count(); |
| DBG_ASSERT( nListCount * sizeof(ScRangePairNameSort) <= (size_t)~0x1F, |
| "ScRangePairList::CreateNameSortedArray nListCount * sizeof(ScRangePairNameSort) > (size_t)~0x1F" ); |
| ScRangePairNameSort* pSortArray = (ScRangePairNameSort*) |
| new sal_uInt8 [ nListCount * sizeof(ScRangePairNameSort) ]; |
| sal_uLong j; |
| for ( j=0; j < nListCount; j++ ) |
| { |
| pSortArray[j].pPair = GetObject( j ); |
| pSortArray[j].pDoc = pDoc; |
| } |
| #if !(defined(ICC ) && defined(OS2)) |
| qsort( (void*)pSortArray, nListCount, sizeof(ScRangePairNameSort), &ScRangePairList_QsortNameCompare ); |
| #else |
| qsort( (void*)pSortArray, nListCount, sizeof(ScRangePairNameSort), ICCQsortRPairCompare ); |
| #endif |
| // ScRangePair Pointer aufruecken |
| ScRangePair** ppSortArray = (ScRangePair**)pSortArray; |
| for ( j=0; j < nListCount; j++ ) |
| { |
| ppSortArray[j] = pSortArray[j].pPair; |
| } |
| return ppSortArray; |
| } |
| |
| |
| |
| |