diff options
Diffstat (limited to 'sc/source/core/tool/refupdat.cxx')
-rw-r--r-- | sc/source/core/tool/refupdat.cxx | 939 |
1 files changed, 939 insertions, 0 deletions
diff --git a/sc/source/core/tool/refupdat.cxx b/sc/source/core/tool/refupdat.cxx new file mode 100644 index 000000000000..ad11190be75d --- /dev/null +++ b/sc/source/core/tool/refupdat.cxx @@ -0,0 +1,939 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "refupdat.hxx" +#include "document.hxx" +#include "compiler.hxx" +#include "bigrange.hxx" +#include "chgtrack.hxx" + +//------------------------------------------------------------------------ + +template< typename R, typename S, typename U > +BOOL lcl_MoveStart( R& rRef, U nStart, S nDelta, U nMask ) +{ + BOOL bCut = FALSE; + if ( rRef >= nStart ) + rRef = sal::static_int_cast<R>( rRef + nDelta ); + else if ( nDelta < 0 && rRef >= nStart + nDelta ) + rRef = nStart + nDelta; //! begrenzen ??? + if ( rRef < 0 ) + { + rRef = 0; + bCut = TRUE; + } + else if ( rRef > nMask ) + { + rRef = nMask; + bCut = TRUE; + } + return bCut; +} + +template< typename R, typename S, typename U > +BOOL lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask ) +{ + BOOL bCut = FALSE; + if ( rRef >= nStart ) + rRef = sal::static_int_cast<R>( rRef + nDelta ); + else if ( nDelta < 0 && rRef >= nStart + nDelta ) + rRef = nStart + nDelta - 1; //! begrenzen ??? + if ( rRef < 0 ) + { + rRef = 0; + bCut = TRUE; + } + else if ( rRef > nMask ) + { + rRef = nMask; + bCut = TRUE; + } + return bCut; +} + +template< typename R, typename S, typename U > +BOOL lcl_MoveReorder( R& rRef, U nStart, U nEnd, S nDelta ) +{ + if ( rRef >= nStart && rRef <= nEnd ) + { + rRef = sal::static_int_cast<R>( rRef + nDelta ); + return TRUE; + } + + if ( nDelta > 0 ) // nach hinten schieben + { + if ( rRef >= nStart && rRef <= nEnd + nDelta ) + { + if ( rRef <= nEnd ) + rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range + else + rRef -= nEnd - nStart + 1; // nachruecken + return TRUE; + } + } + else // nach vorne schieben + { + if ( rRef >= nStart + nDelta && rRef <= nEnd ) + { + if ( rRef >= nStart ) + rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range + else + rRef += nEnd - nStart + 1; // nachruecken + return TRUE; + } + } + + return FALSE; +} + +template< typename R, typename S, typename U > +BOOL lcl_MoveItCut( R& rRef, S nDelta, U nMask ) +{ + BOOL bCut = FALSE; + rRef = sal::static_int_cast<R>( rRef + nDelta ); + if ( rRef < 0 ) + { + rRef = 0; + bCut = TRUE; + } + else if ( rRef > nMask ) + { + rRef = nMask; + bCut = TRUE; + } + return bCut; +} + +template< typename R, typename S, typename U > +void lcl_MoveItWrap( R& rRef, S nDelta, U nMask ) +{ + rRef = sal::static_int_cast<R>( rRef + nDelta ); + if ( rRef < 0 ) + rRef += nMask+1; + else if ( rRef > nMask ) + rRef -= nMask+1; +} + +template< typename R, typename S, typename U > +BOOL lcl_MoveRefPart( R& rRef1Val, BOOL& rRef1Del, BOOL bDo1, + R& rRef2Val, BOOL& rRef2Del, BOOL bDo2, + U nStart, U nEnd, S nDelta, U nMask ) +{ + if ( nDelta ) + { + BOOL bDel, bCut1, bCut2; + bDel = bCut1 = bCut2 = FALSE; + S n; + if (bDo1 && bDo2) + { + if ( nDelta < 0 ) + { + n = nStart + nDelta; + if ( n <= rRef1Val && rRef1Val < nStart + && n <= rRef2Val && rRef2Val < nStart ) + bDel = TRUE; + } + else + { + n = nEnd + nDelta; + if ( nEnd < rRef1Val && rRef1Val <= n + && nEnd < rRef2Val && rRef2Val <= n ) + bDel = TRUE; + } + } + if ( bDel ) + { // move deleted along + rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta ); + rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta ); + } + else + { + if (bDo1) + { + if ( rRef1Del ) + rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta ); + else + bCut1 = lcl_MoveStart( rRef1Val, nStart, nDelta, nMask ); + } + if (bDo2) + { + if ( rRef2Del ) + rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta ); + else + bCut2 = lcl_MoveEnd( rRef2Val, nStart, nDelta, nMask ); + } + } + if ( bDel || (bCut1 && bCut2) ) + rRef1Del = rRef2Del = TRUE; + return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del; + } + else + return FALSE; +} + +template< typename R, typename S, typename U > +BOOL IsExpand( R n1, R n2, U nStart, S nD ) +{ //! vor normalem Move... + return + nD > 0 // Insert + && n1 < n2 // mindestens zwei Cols/Rows/Tabs in Ref + && ( + (nStart <= n1 && n1 < nStart + nD) // n1 innerhalb des Insert + || (n2 + 1 == nStart) // n2 direkt vor Insert + ); // n1 < nStart <= n2 wird sowieso expanded! +} + + +template< typename R, typename S, typename U > +void Expand( R& n1, R& n2, U nStart, S nD ) +{ //! nach normalem Move..., nur wenn IsExpand vorher TRUE war! + //! erst das Ende + if ( n2 + 1 == nStart ) + { // am Ende + n2 = sal::static_int_cast<R>( n2 + nD ); + return; + } + // am Anfang + n1 = sal::static_int_cast<R>( n1 - nD ); +} + + +BOOL lcl_IsWrapBig( INT32 nRef, INT32 nDelta ) +{ + if ( nRef > 0 && nDelta > 0 ) + return nRef + nDelta <= 0; + else if ( nRef < 0 && nDelta < 0 ) + return nRef + nDelta >= 0; + return FALSE; +} + + +BOOL lcl_MoveBig( INT32& rRef, INT32 nStart, INT32 nDelta ) +{ + BOOL bCut = FALSE; + if ( rRef >= nStart ) + { + if ( nDelta > 0 ) + bCut = lcl_IsWrapBig( rRef, nDelta ); + if ( bCut ) + rRef = nInt32Max; + else + rRef += nDelta; + } + return bCut; +} + +BOOL lcl_MoveItCutBig( INT32& rRef, INT32 nDelta ) +{ + BOOL bCut = lcl_IsWrapBig( rRef, nDelta ); + rRef += nDelta; + return bCut; +} + + +ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMode, + SCCOL nCol1, SCROW nRow1, SCTAB nTab1, + SCCOL nCol2, SCROW nRow2, SCTAB nTab2, + SCsCOL nDx, SCsROW nDy, SCsTAB nDz, + SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1, + SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 ) +{ + ScRefUpdateRes eRet = UR_NOTHING; + + SCCOL oldCol1 = theCol1; + SCROW oldRow1 = theRow1; + SCTAB oldTab1 = theTab1; + SCCOL oldCol2 = theCol2; + SCROW oldRow2 = theRow2; + SCTAB oldTab2 = theTab2; + + BOOL bCut1, bCut2; + + if (eUpdateRefMode == URM_INSDEL) + { + BOOL bExpand = pDoc->IsExpandRefs(); + if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && + (theTab1 >= nTab1) && (theTab2 <= nTab2) ) + { + BOOL bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx )); + bCut1 = lcl_MoveStart( theCol1, nCol1, nDx, MAXCOL ); + bCut2 = lcl_MoveEnd( theCol2, nCol1, nDx, MAXCOL ); + if ( theCol2 < theCol1 ) + { + eRet = UR_INVALID; + theCol2 = theCol1; + } + else if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + if ( bExp ) + { + Expand( theCol1, theCol2, nCol1, nDx ); + eRet = UR_UPDATED; + } + } + if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && + (theTab1 >= nTab1) && (theTab2 <= nTab2) ) + { + BOOL bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy )); + bCut1 = lcl_MoveStart( theRow1, nRow1, nDy, MAXROW ); + bCut2 = lcl_MoveEnd( theRow2, nRow1, nDy, MAXROW ); + if ( theRow2 < theRow1 ) + { + eRet = UR_INVALID; + theRow2 = theRow1; + } + else if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + if ( bExp ) + { + Expand( theRow1, theRow2, nRow1, nDy ); + eRet = UR_UPDATED; + } + } + if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && + (theRow1 >= nRow1) && (theRow2 <= nRow2) ) + { + SCsTAB nMaxTab = pDoc->GetTableCount() - 1; + nMaxTab = sal::static_int_cast<SCsTAB>(nMaxTab + nDz); // adjust to new count + BOOL bExp = (bExpand && IsExpand( theTab1, theTab2, nTab1, nDz )); + bCut1 = lcl_MoveStart( theTab1, nTab1, nDz, static_cast<SCTAB>(nMaxTab) ); + bCut2 = lcl_MoveEnd( theTab2, nTab1, nDz, static_cast<SCTAB>(nMaxTab) ); + if ( theTab2 < theTab1 ) + { + eRet = UR_INVALID; + theTab2 = theTab1; + } + else if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + if ( bExp ) + { + Expand( theTab1, theTab2, nTab1, nDz ); + eRet = UR_UPDATED; + } + } + } + else if (eUpdateRefMode == URM_MOVE) + { + if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) && + (theCol2 <= nCol2-nDx) && (theRow2 <= nRow2-nDy) && (theTab2 <= nTab2-nDz)) + { + if ( nDx ) + { + bCut1 = lcl_MoveItCut( theCol1, nDx, MAXCOL ); + bCut2 = lcl_MoveItCut( theCol2, nDx, MAXCOL ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + } + if ( nDy ) + { + bCut1 = lcl_MoveItCut( theRow1, nDy, MAXROW ); + bCut2 = lcl_MoveItCut( theRow2, nDy, MAXROW ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + } + if ( nDz ) + { + SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1; + bCut1 = lcl_MoveItCut( theTab1, nDz, static_cast<SCTAB>(nMaxTab) ); + bCut2 = lcl_MoveItCut( theTab2, nDz, static_cast<SCTAB>(nMaxTab) ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + } + } + } + else if (eUpdateRefMode == URM_REORDER) + { + // bisher nur fuer nDz (MoveTab) + DBG_ASSERT ( !nDx && !nDy, "URM_REORDER fuer x und y noch nicht implementiert" ); + + if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && + (theRow1 >= nRow1) && (theRow2 <= nRow2) ) + { + bCut1 = lcl_MoveReorder( theTab1, nTab1, nTab2, nDz ); + bCut2 = lcl_MoveReorder( theTab2, nTab1, nTab2, nDz ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + } + } + + if ( eRet == UR_NOTHING ) + { + if (oldCol1 != theCol1 + || oldRow1 != theRow1 + || oldTab1 != theTab1 + || oldCol2 != theCol2 + || oldRow2 != theRow2 + || oldTab2 != theTab2 + ) + eRet = UR_UPDATED; + } + return eRet; +} + + +// simples UpdateReference fuer ScBigRange (ScChangeAction/ScChangeTrack) +// Referenzen koennen auch ausserhalb des Dokuments liegen! +// Ganze Spalten/Zeilen (nInt32Min..nInt32Max) bleiben immer solche! +ScRefUpdateRes ScRefUpdate::Update( UpdateRefMode eUpdateRefMode, + const ScBigRange& rWhere, INT32 nDx, INT32 nDy, INT32 nDz, + ScBigRange& rWhat ) +{ + ScRefUpdateRes eRet = UR_NOTHING; + const ScBigRange aOldRange( rWhat ); + + INT32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + INT32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; + rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); + + BOOL bCut1, bCut2; + + if (eUpdateRefMode == URM_INSDEL) + { + if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && + (theTab1 >= nTab1) && (theTab2 <= nTab2) && + !(theCol1 == nInt32Min && theCol2 == nInt32Max) ) + { + bCut1 = lcl_MoveBig( theCol1, nCol1, nDx ); + bCut2 = lcl_MoveBig( theCol2, nCol1, nDx ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + rWhat.aStart.SetCol( theCol1 ); + rWhat.aEnd.SetCol( theCol2 ); + } + if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && + (theTab1 >= nTab1) && (theTab2 <= nTab2) && + !(theRow1 == nInt32Min && theRow2 == nInt32Max) ) + { + bCut1 = lcl_MoveBig( theRow1, nRow1, nDy ); + bCut2 = lcl_MoveBig( theRow2, nRow1, nDy ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + rWhat.aStart.SetRow( theRow1 ); + rWhat.aEnd.SetRow( theRow2 ); + } + if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && + (theRow1 >= nRow1) && (theRow2 <= nRow2) && + !(theTab1 == nInt32Min && theTab2 == nInt32Max) ) + { + bCut1 = lcl_MoveBig( theTab1, nTab1, nDz ); + bCut2 = lcl_MoveBig( theTab2, nTab1, nDz ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + rWhat.aStart.SetTab( theTab1 ); + rWhat.aEnd.SetTab( theTab2 ); + } + } + else if (eUpdateRefMode == URM_MOVE) + { + if ( rWhere.In( rWhat ) ) + { + if ( nDx && !(theCol1 == nInt32Min && theCol2 == nInt32Max) ) + { + bCut1 = lcl_MoveItCutBig( theCol1, nDx ); + bCut2 = lcl_MoveItCutBig( theCol2, nDx ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + rWhat.aStart.SetCol( theCol1 ); + rWhat.aEnd.SetCol( theCol2 ); + } + if ( nDy && !(theRow1 == nInt32Min && theRow2 == nInt32Max) ) + { + bCut1 = lcl_MoveItCutBig( theRow1, nDy ); + bCut2 = lcl_MoveItCutBig( theRow2, nDy ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + rWhat.aStart.SetRow( theRow1 ); + rWhat.aEnd.SetRow( theRow2 ); + } + if ( nDz && !(theTab1 == nInt32Min && theTab2 == nInt32Max) ) + { + bCut1 = lcl_MoveItCutBig( theTab1, nDz ); + bCut2 = lcl_MoveItCutBig( theTab2, nDz ); + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + rWhat.aStart.SetTab( theTab1 ); + rWhat.aEnd.SetTab( theTab2 ); + } + } + } + + if ( eRet == UR_NOTHING && rWhat != aOldRange ) + eRet = UR_UPDATED; + + return eRet; +} + + +ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eMode, + const ScAddress& rPos, const ScRange& r, + SCsCOL nDx, SCsROW nDy, SCsTAB nDz, + ScComplexRefData& rRef, WhatType eWhat ) +{ + ScRefUpdateRes eRet = UR_NOTHING; + + 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(); + + if( eMode == URM_INSDEL ) + { + BOOL bExpand = pDoc->IsExpandRefs(); + + const ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); + BOOL bInDeleteUndo = + ( pChangeTrack ? pChangeTrack->IsInDeleteUndo() : FALSE ); + + SCCOL oldCol1 = rRef.Ref1.nCol; + SCROW oldRow1 = rRef.Ref1.nRow; + SCTAB oldTab1 = rRef.Ref1.nTab; + SCCOL oldCol2 = rRef.Ref2.nCol; + SCROW oldRow2 = rRef.Ref2.nRow; + SCTAB oldTab2 = rRef.Ref2.nTab; + + BOOL bRef1ColDel = rRef.Ref1.IsColDeleted(); + BOOL bRef2ColDel = rRef.Ref2.IsColDeleted(); + BOOL bRef1RowDel = rRef.Ref1.IsRowDeleted(); + BOOL bRef2RowDel = rRef.Ref2.IsRowDeleted(); + BOOL bRef1TabDel = rRef.Ref1.IsTabDeleted(); + BOOL bRef2TabDel = rRef.Ref2.IsTabDeleted(); + + if( nDx && + ((rRef.Ref1.nRow >= nRow1 + && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel)) + && + ((rRef.Ref1.nTab >= nTab1 + && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel)) + ) + { + BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nCol, + rRef.Ref2.nCol, nCol1, nDx )); + BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == + ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsColRel())); + BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat == + ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsColRel())); + if ( lcl_MoveRefPart( rRef.Ref1.nCol, bRef1ColDel, bDo1, + rRef.Ref2.nCol, bRef2ColDel, bDo2, + nCol1, nCol2, nDx, MAXCOL ) ) + { + eRet = UR_UPDATED; + if ( bInDeleteUndo && (bRef1ColDel || bRef2ColDel) ) + { + if ( bRef1ColDel && nCol1 <= rRef.Ref1.nCol && + rRef.Ref1.nCol <= nCol1 + nDx ) + rRef.Ref1.SetColDeleted( FALSE ); + if ( bRef2ColDel && nCol1 <= rRef.Ref2.nCol && + rRef.Ref2.nCol <= nCol1 + nDx ) + rRef.Ref2.SetColDeleted( FALSE ); + } + else + { + if ( bRef1ColDel ) + rRef.Ref1.SetColDeleted( TRUE ); + if ( bRef2ColDel ) + rRef.Ref2.SetColDeleted( TRUE ); + } + } + if ( bExp ) + { + Expand( rRef.Ref1.nCol, rRef.Ref2.nCol, nCol1, nDx ); + eRet = UR_UPDATED; + } + } + if( nDy && + ((rRef.Ref1.nCol >= nCol1 + && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel)) + && + ((rRef.Ref1.nTab >= nTab1 + && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel)) + ) + { + BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nRow, + rRef.Ref2.nRow, nRow1, nDy )); + BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == + ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsRowRel())); + BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat == + ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsRowRel())); + if ( lcl_MoveRefPart( rRef.Ref1.nRow, bRef1RowDel, bDo1, + rRef.Ref2.nRow, bRef2RowDel, bDo2, + nRow1, nRow2, nDy, MAXROW ) ) + { + eRet = UR_UPDATED; + if ( bInDeleteUndo && (bRef1RowDel || bRef2RowDel) ) + { + if ( bRef1RowDel && nRow1 <= rRef.Ref1.nRow && + rRef.Ref1.nRow <= nRow1 + nDy ) + rRef.Ref1.SetRowDeleted( FALSE ); + if ( bRef2RowDel && nRow1 <= rRef.Ref2.nRow && + rRef.Ref2.nRow <= nRow1 + nDy ) + rRef.Ref2.SetRowDeleted( FALSE ); + } + else + { + if ( bRef1RowDel ) + rRef.Ref1.SetRowDeleted( TRUE ); + if ( bRef2RowDel ) + rRef.Ref2.SetRowDeleted( TRUE ); + } + } + if ( bExp ) + { + Expand( rRef.Ref1.nRow, rRef.Ref2.nRow, nRow1, nDy ); + eRet = UR_UPDATED; + } + } + if( nDz && + ((rRef.Ref1.nCol >= nCol1 + && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel)) + && + ((rRef.Ref1.nRow >= nRow1 + && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel)) + ) + { + BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nTab, + rRef.Ref2.nTab, nTab1, nDz )); + SCTAB nMaxTab = pDoc->GetTableCount() - 1; + BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == + ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsTabRel())); + BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat == + ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsTabRel())); + if ( lcl_MoveRefPart( rRef.Ref1.nTab, bRef1TabDel, bDo1, + rRef.Ref2.nTab, bRef2TabDel, bDo2, + nTab1, nTab2, nDz, nMaxTab ) ) + { + eRet = UR_UPDATED; + if ( bInDeleteUndo && (bRef1TabDel || bRef2TabDel) ) + { + if ( bRef1TabDel && nTab1 <= rRef.Ref1.nTab && + rRef.Ref1.nTab <= nTab1 + nDz ) + rRef.Ref1.SetTabDeleted( FALSE ); + if ( bRef2TabDel && nTab1 <= rRef.Ref2.nTab && + rRef.Ref2.nTab <= nTab1 + nDz ) + rRef.Ref2.SetTabDeleted( FALSE ); + } + else + { + if ( bRef1TabDel ) + rRef.Ref1.SetTabDeleted( TRUE ); + if ( bRef2TabDel ) + rRef.Ref2.SetTabDeleted( TRUE ); + } + } + if ( bExp ) + { + Expand( rRef.Ref1.nTab, rRef.Ref2.nTab, nTab1, nDz ); + eRet = UR_UPDATED; + } + } + if ( eRet == UR_NOTHING ) + { + if (oldCol1 != rRef.Ref1.nCol + || oldRow1 != rRef.Ref1.nRow + || oldTab1 != rRef.Ref1.nTab + || oldCol2 != rRef.Ref2.nCol + || oldRow2 != rRef.Ref2.nRow + || oldTab2 != rRef.Ref2.nTab + ) + eRet = UR_UPDATED; + } + if (eWhat != ScRefUpdate::ABSOLUTE) + rRef.CalcRelFromAbs( rPos ); + } + else + { + if( eMode == URM_MOVE ) + { + if ( rRef.Ref1.nCol >= nCol1-nDx + && rRef.Ref1.nRow >= nRow1-nDy + && rRef.Ref1.nTab >= nTab1-nDz + && rRef.Ref2.nCol <= nCol2-nDx + && rRef.Ref2.nRow <= nRow2-nDy + && rRef.Ref2.nTab <= nTab2-nDz ) + { + eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, TRUE ); // immer verschieben + } + else if ( nDz && r.In( rPos ) ) + { + rRef.Ref1.SetFlag3D( TRUE ); + rRef.Ref2.SetFlag3D( TRUE ); + eRet = UR_UPDATED; + if (eWhat != ScRefUpdate::ABSOLUTE) + rRef.CalcRelFromAbs( rPos ); + } + else if (eWhat != ScRefUpdate::ABSOLUTE) + rRef.CalcRelFromAbs( rPos ); + } + else if( eMode == URM_COPY && r.In( rPos ) ) + eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, FALSE ); // nur relative + // sollte nicht mehr verwendet werden muessen + else if (eWhat != ScRefUpdate::ABSOLUTE) + rRef.CalcRelFromAbs( rPos ); + } + return eRet; +} + + +ScRefUpdateRes ScRefUpdate::Move( ScDocument* pDoc, const ScAddress& rPos, + SCsCOL nDx, SCsROW nDy, SCsTAB nDz, + ScComplexRefData& rRef, BOOL bWrap, BOOL bAbsolute ) +{ + ScRefUpdateRes eRet = UR_NOTHING; + + SCCOL oldCol1 = rRef.Ref1.nCol; + SCROW oldRow1 = rRef.Ref1.nRow; + SCTAB oldTab1 = rRef.Ref1.nTab; + SCCOL oldCol2 = rRef.Ref2.nCol; + SCROW oldRow2 = rRef.Ref2.nRow; + SCTAB oldTab2 = rRef.Ref2.nTab; + + BOOL bCut1, bCut2; + if ( nDx ) + { + bCut1 = bCut2 = FALSE; + if( bAbsolute || rRef.Ref1.IsColRel() ) + { + if( bWrap ) + lcl_MoveItWrap( rRef.Ref1.nCol, nDx, MAXCOL ); + else + bCut1 = lcl_MoveItCut( rRef.Ref1.nCol, nDx, MAXCOL ); + } + if( bAbsolute || rRef.Ref2.IsColRel() ) + { + if( bWrap ) + lcl_MoveItWrap( rRef.Ref2.nCol, nDx, MAXCOL ); + else + bCut2 = lcl_MoveItCut( rRef.Ref2.nCol, nDx, MAXCOL ); + } + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + if ( bCut1 && bCut2 ) + { + rRef.Ref1.SetColDeleted( TRUE ); + rRef.Ref2.SetColDeleted( TRUE ); + } + } + if ( nDy ) + { + bCut1 = bCut2 = FALSE; + if( bAbsolute || rRef.Ref1.IsRowRel() ) + { + if( bWrap ) + lcl_MoveItWrap( rRef.Ref1.nRow, nDy, MAXROW ); + else + bCut1 = lcl_MoveItCut( rRef.Ref1.nRow, nDy, MAXROW ); + } + if( bAbsolute || rRef.Ref2.IsRowRel() ) + { + if( bWrap ) + lcl_MoveItWrap( rRef.Ref2.nRow, nDy, MAXROW ); + else + bCut2 = lcl_MoveItCut( rRef.Ref2.nRow, nDy, MAXROW ); + } + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + if ( bCut1 && bCut2 ) + { + rRef.Ref1.SetRowDeleted( TRUE ); + rRef.Ref2.SetRowDeleted( TRUE ); + } + } + if ( nDz ) + { + bCut1 = bCut2 = FALSE; + SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1; + if( bAbsolute || rRef.Ref1.IsTabRel() ) + { + if( bWrap ) + lcl_MoveItWrap( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); + else + bCut1 = lcl_MoveItCut( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); + rRef.Ref1.SetFlag3D( rPos.Tab() != rRef.Ref1.nTab ); + } + if( bAbsolute || rRef.Ref2.IsTabRel() ) + { + if( bWrap ) + lcl_MoveItWrap( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); + else + bCut2 = lcl_MoveItCut( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); + rRef.Ref2.SetFlag3D( rPos.Tab() != rRef.Ref2.nTab ); + } + if ( bCut1 || bCut2 ) + eRet = UR_UPDATED; + if ( bCut1 && bCut2 ) + { + rRef.Ref1.SetTabDeleted( TRUE ); + rRef.Ref2.SetTabDeleted( TRUE ); + } + } + + if ( eRet == UR_NOTHING ) + { + if (oldCol1 != rRef.Ref1.nCol + || oldRow1 != rRef.Ref1.nRow + || oldTab1 != rRef.Ref1.nTab + || oldCol2 != rRef.Ref2.nCol + || oldRow2 != rRef.Ref2.nRow + || oldTab2 != rRef.Ref2.nTab + ) + eRet = UR_UPDATED; + } + if ( bWrap && eRet != UR_NOTHING ) + rRef.PutInOrder(); + rRef.CalcRelFromAbs( rPos ); + return eRet; +} + +void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos, + SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef ) +{ + if( rRef.Ref1.IsColRel() ) + { + rRef.Ref1.nCol = rRef.Ref1.nRelCol + rPos.Col(); + lcl_MoveItWrap( rRef.Ref1.nCol, static_cast<SCsCOL>(0), nMaxCol ); + } + if( rRef.Ref2.IsColRel() ) + { + rRef.Ref2.nCol = rRef.Ref2.nRelCol + rPos.Col(); + lcl_MoveItWrap( rRef.Ref2.nCol, static_cast<SCsCOL>(0), nMaxCol ); + } + if( rRef.Ref1.IsRowRel() ) + { + rRef.Ref1.nRow = rRef.Ref1.nRelRow + rPos.Row(); + lcl_MoveItWrap( rRef.Ref1.nRow, static_cast<SCsROW>(0), nMaxRow ); + } + if( rRef.Ref2.IsRowRel() ) + { + rRef.Ref2.nRow = rRef.Ref2.nRelRow + rPos.Row(); + lcl_MoveItWrap( rRef.Ref2.nRow, static_cast<SCsROW>(0), nMaxRow ); + } + SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1; + if( rRef.Ref1.IsTabRel() ) + { + rRef.Ref1.nTab = rRef.Ref1.nRelTab + rPos.Tab(); + lcl_MoveItWrap( rRef.Ref1.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) ); + } + if( rRef.Ref2.IsTabRel() ) + { + rRef.Ref2.nTab = rRef.Ref2.nRelTab + rPos.Tab(); + lcl_MoveItWrap( rRef.Ref2.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) ); + } + rRef.PutInOrder(); + rRef.CalcRelFromAbs( rPos ); +} + +//------------------------------------------------------------------ + +void ScRefUpdate::DoTranspose( SCsCOL& rCol, SCsROW& rRow, SCsTAB& rTab, + ScDocument* pDoc, const ScRange& rSource, const ScAddress& rDest ) +{ + SCsTAB nDz = ((SCsTAB)rDest.Tab())-(SCsTAB)rSource.aStart.Tab(); + if (nDz) + { + SCsTAB nNewTab = rTab+nDz; + SCsTAB nCount = pDoc->GetTableCount(); + while (nNewTab<0) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab + nCount ); + while (nNewTab>=nCount) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab - nCount ); + rTab = nNewTab; + } + DBG_ASSERT( rCol>=rSource.aStart.Col() && rRow>=rSource.aStart.Row(), + "UpdateTranspose: Pos. falsch" ); + + SCsCOL nRelX = rCol - (SCsCOL)rSource.aStart.Col(); + SCsROW nRelY = rRow - (SCsROW)rSource.aStart.Row(); + + rCol = static_cast<SCsCOL>(static_cast<SCsCOLROW>(rDest.Col()) + + static_cast<SCsCOLROW>(nRelY)); + rRow = static_cast<SCsROW>(static_cast<SCsCOLROW>(rDest.Row()) + + static_cast<SCsCOLROW>(nRelX)); +} + + +ScRefUpdateRes ScRefUpdate::UpdateTranspose( ScDocument* pDoc, + const ScRange& rSource, const ScAddress& rDest, + ScComplexRefData& rRef ) +{ + ScRefUpdateRes eRet = UR_NOTHING; + if ( rRef.Ref1.nCol >= rSource.aStart.Col() && rRef.Ref2.nCol <= rSource.aEnd.Col() && + rRef.Ref1.nRow >= rSource.aStart.Row() && rRef.Ref2.nRow <= rSource.aEnd.Row() && + rRef.Ref1.nTab >= rSource.aStart.Tab() && rRef.Ref2.nTab <= rSource.aEnd.Tab() ) + { + DoTranspose( rRef.Ref1.nCol, rRef.Ref1.nRow, rRef.Ref1.nTab, pDoc, rSource, rDest ); + DoTranspose( rRef.Ref2.nCol, rRef.Ref2.nRow, rRef.Ref2.nTab, pDoc, rSource, rDest ); + eRet = UR_UPDATED; + } + return eRet; +} + +//------------------------------------------------------------------ + +// UpdateGrow - erweitert Referenzen, die genau auf den Bereich zeigen +// kommt ohne Dokument aus + + +ScRefUpdateRes ScRefUpdate::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY, + ScComplexRefData& rRef ) +{ + ScRefUpdateRes eRet = UR_NOTHING; + + // in Y-Richtung darf die Ref auch eine Zeile weiter unten anfangen, + // falls ein Bereich Spaltenkoepfe enthaelt + + BOOL bUpdateX = ( nGrowX && + rRef.Ref1.nCol == rArea.aStart.Col() && rRef.Ref2.nCol == rArea.aEnd.Col() && + rRef.Ref1.nRow >= rArea.aStart.Row() && rRef.Ref2.nRow <= rArea.aEnd.Row() && + rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() ); + BOOL bUpdateY = ( nGrowY && + rRef.Ref1.nCol >= rArea.aStart.Col() && rRef.Ref2.nCol <= rArea.aEnd.Col() && + ( rRef.Ref1.nRow == rArea.aStart.Row() || rRef.Ref1.nRow == rArea.aStart.Row()+1 ) && + rRef.Ref2.nRow == rArea.aEnd.Row() && + rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() ); + + if ( bUpdateX ) + { + rRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( rRef.Ref2.nCol + nGrowX ); + eRet = UR_UPDATED; + } + if ( bUpdateY ) + { + rRef.Ref2.nRow = sal::static_int_cast<SCsROW>( rRef.Ref2.nRow + nGrowY ); + eRet = UR_UPDATED; + } + + return eRet; +} + + |