| /************************************************************** |
| * |
| * 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" |
| |
| // 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 > |
| sal_Bool lcl_MoveStart( R& rRef, U nStart, S nDelta, U nMask ) |
| { |
| sal_Bool bCut = sal_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 = sal_True; |
| } |
| else if ( rRef > nMask ) |
| { |
| rRef = nMask; |
| bCut = sal_True; |
| } |
| return bCut; |
| } |
| |
| template< typename R, typename S, typename U > |
| sal_Bool lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask ) |
| { |
| sal_Bool bCut = sal_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 = sal_True; |
| } |
| else if ( rRef > nMask ) |
| { |
| rRef = nMask; |
| bCut = sal_True; |
| } |
| return bCut; |
| } |
| |
| template< typename R, typename S, typename U > |
| sal_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 sal_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 sal_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 sal_True; |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| template< typename R, typename S, typename U > |
| sal_Bool lcl_MoveItCut( R& rRef, S nDelta, U nMask ) |
| { |
| sal_Bool bCut = sal_False; |
| rRef = sal::static_int_cast<R>( rRef + nDelta ); |
| if ( rRef < 0 ) |
| { |
| rRef = 0; |
| bCut = sal_True; |
| } |
| else if ( rRef > nMask ) |
| { |
| rRef = nMask; |
| bCut = sal_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 > |
| sal_Bool lcl_MoveRefPart( R& rRef1Val, sal_Bool& rRef1Del, sal_Bool bDo1, |
| R& rRef2Val, sal_Bool& rRef2Del, sal_Bool bDo2, |
| U nStart, U nEnd, S nDelta, U nMask ) |
| { |
| if ( nDelta ) |
| { |
| sal_Bool bDel, bCut1, bCut2; |
| bDel = bCut1 = bCut2 = sal_False; |
| S n; |
| if (bDo1 && bDo2) |
| { |
| if ( nDelta < 0 ) |
| { |
| n = nStart + nDelta; |
| if ( n <= rRef1Val && rRef1Val < nStart |
| && n <= rRef2Val && rRef2Val < nStart ) |
| bDel = sal_True; |
| } |
| else |
| { |
| n = nEnd + nDelta; |
| if ( nEnd < rRef1Val && rRef1Val <= n |
| && nEnd < rRef2Val && rRef2Val <= n ) |
| bDel = sal_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 = sal_True; |
| return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del; |
| } |
| else |
| return sal_False; |
| } |
| |
| template< typename R, typename S, typename U > |
| sal_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 sal_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 ); |
| } |
| |
| |
| sal_Bool lcl_IsWrapBig( sal_Int32 nRef, sal_Int32 nDelta ) |
| { |
| if ( nRef > 0 && nDelta > 0 ) |
| return nRef + nDelta <= 0; |
| else if ( nRef < 0 && nDelta < 0 ) |
| return nRef + nDelta >= 0; |
| return sal_False; |
| } |
| |
| |
| sal_Bool lcl_MoveBig( sal_Int32& rRef, sal_Int32 nStart, sal_Int32 nDelta ) |
| { |
| sal_Bool bCut = sal_False; |
| if ( rRef >= nStart ) |
| { |
| if ( nDelta > 0 ) |
| bCut = lcl_IsWrapBig( rRef, nDelta ); |
| if ( bCut ) |
| rRef = nInt32Max; |
| else |
| rRef += nDelta; |
| } |
| return bCut; |
| } |
| |
| sal_Bool lcl_MoveItCutBig( sal_Int32& rRef, sal_Int32 nDelta ) |
| { |
| sal_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; |
| |
| sal_Bool bCut1, bCut2; |
| |
| if (eUpdateRefMode == URM_INSDEL) |
| { |
| sal_Bool bExpand = pDoc->IsExpandRefs(); |
| if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && |
| (theTab1 >= nTab1) && (theTab2 <= nTab2) ) |
| { |
| sal_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) ) |
| { |
| sal_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 |
| sal_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, sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz, |
| ScBigRange& rWhat ) |
| { |
| ScRefUpdateRes eRet = UR_NOTHING; |
| const ScBigRange aOldRange( rWhat ); |
| |
| sal_Int32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; |
| sal_Int32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; |
| rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); |
| rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); |
| |
| sal_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 ) |
| { |
| sal_Bool bExpand = pDoc->IsExpandRefs(); |
| |
| const ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); |
| sal_Bool bInDeleteUndo = |
| ( pChangeTrack ? pChangeTrack->IsInDeleteUndo() : sal_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; |
| |
| sal_Bool bRef1ColDel = rRef.Ref1.IsColDeleted(); |
| sal_Bool bRef2ColDel = rRef.Ref2.IsColDeleted(); |
| sal_Bool bRef1RowDel = rRef.Ref1.IsRowDeleted(); |
| sal_Bool bRef2RowDel = rRef.Ref2.IsRowDeleted(); |
| sal_Bool bRef1TabDel = rRef.Ref1.IsTabDeleted(); |
| sal_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)) |
| ) |
| { |
| sal_Bool bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nCol, |
| rRef.Ref2.nCol, nCol1, nDx )); |
| sal_Bool bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == |
| ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsColRel())); |
| sal_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( sal_False ); |
| if ( bRef2ColDel && nCol1 <= rRef.Ref2.nCol && |
| rRef.Ref2.nCol <= nCol1 + nDx ) |
| rRef.Ref2.SetColDeleted( sal_False ); |
| } |
| else |
| { |
| if ( bRef1ColDel ) |
| rRef.Ref1.SetColDeleted( sal_True ); |
| if ( bRef2ColDel ) |
| rRef.Ref2.SetColDeleted( sal_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)) |
| ) |
| { |
| sal_Bool bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nRow, |
| rRef.Ref2.nRow, nRow1, nDy )); |
| sal_Bool bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == |
| ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsRowRel())); |
| sal_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( sal_False ); |
| if ( bRef2RowDel && nRow1 <= rRef.Ref2.nRow && |
| rRef.Ref2.nRow <= nRow1 + nDy ) |
| rRef.Ref2.SetRowDeleted( sal_False ); |
| } |
| else |
| { |
| if ( bRef1RowDel ) |
| rRef.Ref1.SetRowDeleted( sal_True ); |
| if ( bRef2RowDel ) |
| rRef.Ref2.SetRowDeleted( sal_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)) |
| ) |
| { |
| sal_Bool bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nTab, |
| rRef.Ref2.nTab, nTab1, nDz )); |
| SCTAB nMaxTab = pDoc->GetTableCount() - 1; |
| sal_Bool bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == |
| ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsTabRel())); |
| sal_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( sal_False ); |
| if ( bRef2TabDel && nTab1 <= rRef.Ref2.nTab && |
| rRef.Ref2.nTab <= nTab1 + nDz ) |
| rRef.Ref2.SetTabDeleted( sal_False ); |
| } |
| else |
| { |
| if ( bRef1TabDel ) |
| rRef.Ref1.SetTabDeleted( sal_True ); |
| if ( bRef2TabDel ) |
| rRef.Ref2.SetTabDeleted( sal_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, sal_False, sal_True ); // immer verschieben |
| } |
| else if ( nDz && r.In( rPos ) ) |
| { |
| rRef.Ref1.SetFlag3D( sal_True ); |
| rRef.Ref2.SetFlag3D( sal_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, sal_False, sal_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, sal_Bool bWrap, sal_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; |
| |
| sal_Bool bCut1, bCut2; |
| if ( nDx ) |
| { |
| bCut1 = bCut2 = sal_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( sal_True ); |
| rRef.Ref2.SetColDeleted( sal_True ); |
| } |
| } |
| if ( nDy ) |
| { |
| bCut1 = bCut2 = sal_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( sal_True ); |
| rRef.Ref2.SetRowDeleted( sal_True ); |
| } |
| } |
| if ( nDz ) |
| { |
| bCut1 = bCut2 = sal_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( sal_True ); |
| rRef.Ref2.SetTabDeleted( sal_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 |
| |
| sal_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() ); |
| sal_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; |
| } |
| |
| |