diff options
Diffstat (limited to 'bf_sc/source/core/tool/sc_rangelst.cxx')
-rw-r--r-- | bf_sc/source/core/tool/sc_rangelst.cxx | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/bf_sc/source/core/tool/sc_rangelst.cxx b/bf_sc/source/core/tool/sc_rangelst.cxx new file mode 100644 index 000000000..aca814da7 --- /dev/null +++ b/bf_sc/source/core/tool/sc_rangelst.cxx @@ -0,0 +1,494 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#define SC_RANGELST_CXX //fuer ICC + +#include <stdlib.h> // qsort + +#include "document.hxx" +#include "refupdat.hxx" +#include "rechead.hxx" +namespace binfilter { + + +// === ScRangeList ==================================================== + +/*N*/ ScRangeList::~ScRangeList() +/*N*/ { + for ( size_t i = 0, n = maList.size(); i < n; ++i ) + delete maList[ i ]; + maList.clear(); +/*N*/ } + +/*N*/ void ScRangeList::RemoveAll() +/*N*/ { + for ( size_t i = 0, n = maList.size(); i < n; ++i ) + delete maList[ i ]; + maList.clear(); +/*N*/ } + +/*N*/ USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask ) +/*N*/ { +/*N*/ if ( rStr.Len() ) +/*N*/ { +/*N*/ nMask |= SCA_VALID; // falls das jemand vergessen sollte +/*N*/ USHORT nResult = (USHORT)~0; // alle Bits setzen +/*N*/ ScRange aRange; +/*N*/ String aOne; +/*N*/ USHORT nTab = 0; +/*N*/ if ( pDoc ) +/*N*/ { +/*N*/ //! erste markierte Tabelle gibts nicht mehr am Dokument +/*N*/ //! -> uebergeben? oder spaeter an den Ranges setzen +/*N*/ } +/*N*/ else +/*N*/ nTab = 0; +/*N*/ USHORT nTCount = rStr.GetTokenCount(); +/*N*/ for ( USHORT i=0; i<nTCount; i++ ) +/*N*/ { +/*N*/ aOne = rStr.GetToken(i); +/*N*/ if ( aOne.Search( ':' ) == STRING_NOTFOUND ) +/*N*/ { // Range muss es sein +/*N*/ String aStrTmp( aOne ); +/*N*/ aOne += ':'; +/*N*/ aOne += aStrTmp; +/*N*/ } +/*N*/ aRange.aStart.SetTab( nTab ); // Default Tab wenn nicht angegeben +/*N*/ USHORT nRes = aRange.Parse( aOne, pDoc ); +/*N*/ if ( (nRes & nMask) == nMask ) +/*N*/ Append( aRange ); +/*N*/ nResult &= nRes; // alle gemeinsamen Bits bleiben erhalten +/*N*/ } +/*N*/ return nResult; // SCA_VALID gesetzt wenn alle ok +/*N*/ } +/*N*/ else +/*N*/ return 0; +/*N*/ } + + +/*N*/ void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc ) const +/*N*/ { +/*N*/ rStr.Erase(); +/*N*/ ULONG nCnt = Count(); +/*N*/ for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ ) +/*N*/ { +/*N*/ String aStr; +/*N*/ GetObject( nIdx )->Format( aStr, nFlags, pDoc ); +/*N*/ if ( nIdx ) +/*N*/ rStr += ';'; +/*N*/ rStr += aStr; +/*N*/ } +/*N*/ } + + +/*N*/ void ScRangeList::Join( const ScRange& r, BOOL bIsInList ) +/*N*/ { +/*N*/ if ( !Count() ) +/*N*/ { +/*N*/ Append( r ); +/*N*/ return ; +/*N*/ } +/*N*/ USHORT nCol1 = r.aStart.Col(); +/*N*/ USHORT nRow1 = r.aStart.Row(); +/*N*/ USHORT nTab1 = r.aStart.Tab(); +/*N*/ USHORT nCol2 = r.aEnd.Col(); +/*N*/ USHORT nRow2 = r.aEnd.Row(); +/*N*/ USHORT nTab2 = r.aEnd.Tab(); +/*N*/ ScRangePtr pOver = (ScRangePtr) &r; // fies aber wahr wenn bInList +/*N*/ ULONG nOldPos(0); +/*N*/ if ( bIsInList ) +/*N*/ { // merken um ggbf. zu loeschen bzw. wiederherzustellen +/*N*/ nOldPos = GetPos( pOver ); +/*N*/ } +/*N*/ BOOL bJoinedInput = FALSE; +/*N*/ for ( ScRangePtr p = First(); p && pOver; p = Next() ) +/*N*/ { +/*N*/ if ( p == pOver ) +/*N*/ continue; // derselbe, weiter mit dem naechsten +/*N*/ BOOL bJoined = FALSE; +/*N*/ if ( p->In( r ) ) +/*N*/ { // Range r in Range p enthalten oder identisch +/*N*/ if ( bIsInList ) +/*N*/ bJoined = TRUE; // weg mit Range r +/*N*/ else +/*N*/ { // das war's dann +/*N*/ bJoinedInput = TRUE; // nicht anhaengen +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ else if ( r.In( *p ) ) +/*N*/ { // Range p in Range r enthalten, r zum neuen Range machen +/*N*/ *p = r; +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ if ( !bJoined && p->aStart.Tab() == nTab1 && p->aEnd.Tab() == nTab2 ) +/*N*/ { // 2D +/*N*/ if ( p->aStart.Col() == nCol1 && p->aEnd.Col() == nCol2 ) +/*N*/ { +/*N*/ if ( p->aStart.Row() == nRow2+1 ) +/*N*/ { // oben +/*?*/ p->aStart.SetRow( nRow1 ); +/*?*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( p->aEnd.Row() == nRow1-1 ) +/*N*/ { // unten +/*N*/ p->aEnd.SetRow( nRow2 ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if ( p->aStart.Row() == nRow1 && p->aEnd.Row() == nRow2 ) +/*N*/ { +/*N*/ if ( p->aStart.Col() == nCol2+1 ) +/*N*/ { // links +/*?*/ p->aStart.SetCol( nCol1 ); +/*?*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( p->aEnd.Col() == nCol1-1 ) +/*N*/ { // rechts +/*N*/ p->aEnd.SetCol( nCol2 ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bJoined ) +/*N*/ { +/*N*/ if ( bIsInList ) +/*N*/ { // innerhalb der Liste Range loeschen +/*N*/ Remove( nOldPos ); +/*N*/ delete pOver; +/*N*/ pOver = NULL; +/*N*/ if ( nOldPos ) +/*N*/ nOldPos--; // Seek richtig aufsetzen +/*N*/ } +/*N*/ bJoinedInput = TRUE; +/*N*/ Join( *p, TRUE ); // rekursiv! +/*N*/ } +/*N*/ } +/*N*/ if ( bIsInList ) +/*N*/ Seek( nOldPos ); +/*N*/ else if ( !bJoinedInput ) +/*N*/ Append( r ); +/*N*/ } + +/*N*/ BOOL ScRangeList::Load( SvStream& rStream, USHORT /*nVer*/ ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ ScRange aRange; +/*N*/ UINT32 n; +/*N*/ rStream >> n; +/*N*/ ULONG nLclCount = n; +/*N*/ for ( ULONG j = 0; j < nLclCount && bOk; j++ ) +/*N*/ { +/*N*/ rStream >> aRange; +/*N*/ Append( aRange ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScRangeList::UpdateReference( UpdateRefMode eUpdateRefMode, +/*N*/ ScDocument* pDoc, const ScRange& rWhere, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ BOOL bChanged = FALSE; +/*N*/ if ( Count() ) +/*N*/ { +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ for ( ScRange* pR = First(); pR; pR = Next() ) +/*N*/ { +/*N*/ USHORT theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; +/*N*/ pR->GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); +/*N*/ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, +/*N*/ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, +/*N*/ nDx, nDy, nDz, +/*N*/ theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) +/*N*/ != UR_NOTHING ) +/*N*/ { +/*?*/ bChanged = TRUE; +/*?*/ pR->aStart.Set( theCol1, theRow1, theTab1 ); +/*?*/ pR->aEnd.Set( theCol2, theRow2, theTab2 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return bChanged; +/*N*/ } + + + + + + +/*N*/ ScRangeList::ScRangeList( const ScRangeList& rList ) +/*N*/ : SvRefBase() +/*N*/ { +/*N*/ ULONG nLclCount = rList.Count(); +/*N*/ for ( ULONG j = 0; j < nLclCount; j++ ) +/*N*/ Append( *rList.GetObject( j ) ); +/*N*/ } + + + + +/*N*/ ScRangeList& ScRangeList::operator=(const ScRangeList& rList) +/*N*/ { +/*N*/ RemoveAll(); +/*N*/ +/*N*/ ULONG nLclCount = rList.Count(); +/*N*/ for ( ULONG j = 0; j < nLclCount; j++ ) +/*N*/ Append( *rList.GetObject( j ) ); +/*N*/ +/*N*/ return *this; +/*N*/ } + + + + + + + + +// === ScRangePairList ==================================================== + +/*N*/ ScRangePairList::~ScRangePairList() +/*N*/ { +/*N*/ for ( ScRangePair* pR = First(); pR; pR = Next() ) +/*?*/ delete pR; +/*N*/ } + + +/*N*/ void ScRangePairList::Join( const ScRangePair& r, BOOL bIsInList ) +/*N*/ { +/*N*/ if ( !Count() ) +/*N*/ { +/*N*/ Append( r ); +/*N*/ return ; +/*N*/ } +/*N*/ const ScRange& r1 = r.GetRange(0); +/*N*/ const ScRange& r2 = r.GetRange(1); +/*N*/ USHORT nCol1 = r1.aStart.Col(); +/*N*/ USHORT nRow1 = r1.aStart.Row(); +/*N*/ USHORT nTab1 = r1.aStart.Tab(); +/*N*/ USHORT nCol2 = r1.aEnd.Col(); +/*N*/ USHORT nRow2 = r1.aEnd.Row(); +/*N*/ USHORT nTab2 = r1.aEnd.Tab(); +/*N*/ ScRangePair* pOver = (ScRangePair*) &r; // fies aber wahr wenn bInList +/*N*/ ULONG nOldPos(0); +/*N*/ if ( bIsInList ) +/*N*/ { // merken um ggbf. zu loeschen bzw. wiederherzustellen +/*N*/ nOldPos = GetPos( pOver ); +/*N*/ } +/*N*/ BOOL bJoinedInput = FALSE; +/*N*/ for ( ScRangePair* p = First(); p && pOver; p = Next() ) +/*N*/ { +/*N*/ if ( p == pOver ) +/*N*/ continue; // derselbe, weiter mit dem naechsten +/*N*/ BOOL bJoined = FALSE; +/*N*/ ScRange& rp1 = p->GetRange(0); +/*N*/ ScRange& rp2 = p->GetRange(1); +/*N*/ if ( rp2 == r2 ) +/*N*/ { // nur wenn Range2 gleich ist +/*N*/ if ( rp1.In( r1 ) ) +/*N*/ { // RangePair r in RangePair p enthalten oder identisch +/*N*/ if ( bIsInList ) +/*N*/ bJoined = TRUE; // weg mit RangePair r +/*N*/ else +/*N*/ { // das war's dann +/*N*/ bJoinedInput = TRUE; // nicht anhaengen +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ else if ( r1.In( rp1 ) ) +/*N*/ { // RangePair p in RangePair r enthalten, r zum neuen RangePair machen +/*N*/ *p = r; +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ if ( !bJoined && rp1.aStart.Tab() == nTab1 && rp1.aEnd.Tab() == nTab2 +/*N*/ && rp2.aStart.Tab() == r2.aStart.Tab() +/*N*/ && rp2.aEnd.Tab() == r2.aEnd.Tab() ) +/*N*/ { // 2D, Range2 muss genauso nebeneinander liegen wie Range1 +/*N*/ if ( rp1.aStart.Col() == nCol1 && rp1.aEnd.Col() == nCol2 +/*N*/ && rp2.aStart.Col() == r2.aStart.Col() +/*N*/ && rp2.aEnd.Col() == r2.aEnd.Col() ) +/*N*/ { +/*N*/ if ( rp1.aStart.Row() == nRow2+1 +/*N*/ && rp2.aStart.Row() == r2.aEnd.Row()+1 ) +/*N*/ { // oben +/*N*/ rp1.aStart.SetRow( nRow1 ); +/*N*/ rp2.aStart.SetRow( r2.aStart.Row() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( rp1.aEnd.Row() == nRow1-1 +/*N*/ && rp2.aEnd.Row() == r2.aStart.Row()-1 ) +/*N*/ { // unten +/*N*/ rp1.aEnd.SetRow( nRow2 ); +/*N*/ rp2.aEnd.SetRow( r2.aEnd.Row() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if ( rp1.aStart.Row() == nRow1 && rp1.aEnd.Row() == nRow2 +/*N*/ && rp2.aStart.Row() == r2.aStart.Row() +/*N*/ && rp2.aEnd.Row() == r2.aEnd.Row() ) +/*N*/ { +/*N*/ if ( rp1.aStart.Col() == nCol2+1 +/*N*/ && rp2.aStart.Col() == r2.aEnd.Col()+1 ) +/*N*/ { // links +/*N*/ rp1.aStart.SetCol( nCol1 ); +/*N*/ rp2.aStart.SetCol( r2.aStart.Col() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( rp1.aEnd.Col() == nCol1-1 +/*N*/ && rp2.aEnd.Col() == r2.aEnd.Col()-1 ) +/*N*/ { // rechts +/*N*/ rp1.aEnd.SetCol( nCol2 ); +/*N*/ rp2.aEnd.SetCol( r2.aEnd.Col() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bJoined ) +/*N*/ { +/*N*/ if ( bIsInList ) +/*N*/ { // innerhalb der Liste RangePair loeschen +/*N*/ Remove( nOldPos ); +/*N*/ delete pOver; +/*N*/ pOver = NULL; +/*N*/ if ( nOldPos ) +/*N*/ nOldPos--; // Seek richtig aufsetzen +/*N*/ } +/*N*/ bJoinedInput = TRUE; +/*N*/ Join( *p, TRUE ); // rekursiv! +/*N*/ } +/*N*/ } +/*N*/ if ( bIsInList ) +/*N*/ Seek( nOldPos ); +/*N*/ else if ( !bJoinedInput ) +/*N*/ Append( r ); +/*N*/ } + +/*N*/ BOOL ScRangePairList::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ ScRangePair aRangePair; +/*N*/ ScRange aRange; +/*N*/ UINT32 n; +/*N*/ rStream >> n; +/*N*/ ULONG nLclCount = n; +/*N*/ for ( ULONG j = 0; j < nLclCount && bOk; j++ ) +/*N*/ { +/*N*/ if ( nVer < SC_COLROWNAME_RANGEPAIR ) +/*N*/ { // aus technical Beta 4.0 versuchen mit altem Verhalten zu uebernehmen +/*N*/ rStream >> aRange; +/*N*/ aRangePair.GetRange(0) = aRange; +/*N*/ ScRange& r = aRangePair.GetRange(1); +/*N*/ r = aRange; +/*N*/ USHORT nCol2 = aRange.aEnd.Col(); +/*N*/ USHORT nRow2 = aRange.aEnd.Row(); +/*N*/ if ( nCol2 - aRange.aStart.Col() >= nRow2 - aRange.aStart.Row() ) +/*N*/ { // ColNames +/*N*/ r.aStart.SetRow( (USHORT) Min( (ULONG)nRow2 + 1, (ULONG)MAXROW ) ); +/*N*/ r.aEnd.SetRow( MAXROW ); +/*N*/ } +/*N*/ else +/*N*/ { // RowNames +/*N*/ r.aStart.SetCol( (USHORT) Min( (ULONG)(nCol2 + 1), (ULONG)MAXCOL ) ); +/*N*/ r.aEnd.SetCol( MAXCOL ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ rStream >> aRangePair; +/*N*/ Append( aRangePair ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScRangePairList::UpdateReference( UpdateRefMode eUpdateRefMode, +/*N*/ ScDocument* pDoc, const ScRange& rWhere, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ BOOL bChanged = FALSE; +/*N*/ if ( Count() ) +/*N*/ { +/*?*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*?*/ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*?*/ for ( ScRangePair* pR = First(); pR; pR = Next() ) +/*?*/ { +/*?*/ for ( USHORT j=0; j<2; j++ ) +/*?*/ { +/*?*/ ScRange& rRange = pR->GetRange(j); +/*?*/ USHORT theCol1, theRow1, theTab1, theCol2, theRow2, 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 = TRUE; +/*?*/ rRange.aStart.Set( theCol1, theRow1, theTab1 ); +/*?*/ rRange.aEnd.Set( theCol2, theRow2, theTab2 ); +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ return bChanged; +/*N*/ } + + +/*N*/ ScRangePair* ScRangePairList::Find( const ScRange& rRange ) const +/*N*/ { +/*N*/ ULONG nLclCount = Count(); +/*N*/ for ( ULONG j = 0; j < nLclCount; j++ ) +/*N*/ { +/*N*/ ScRangePair* pR = GetObject( j ); +/*N*/ if ( pR->GetRange(0) == rRange ) +/*N*/ return pR; +/*N*/ } +/*N*/ return NULL; +/*N*/ } + + +/*N*/ ScRangePairList* ScRangePairList::Clone() const +/*N*/ { +/*N*/ ScRangePairList* pNew = new ScRangePairList; +/*N*/ ULONG nLclCount = Count(); +/*N*/ for ( ULONG j = 0; j < nLclCount; j++ ) +/*N*/ { +/*N*/ pNew->Append( *GetObject( j ) ); +/*N*/ } +/*N*/ return pNew; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |