update dev300-m57
[ooovba.git] / sc / source / core / tool / refupdat.cxx
blobca415af081d734726c92c20c76a5aaa8765b6880
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: refupdat.cxx,v $
10 * $Revision: 1.8.32.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include <tools/debug.hxx>
38 #include "refupdat.hxx"
39 #include "document.hxx"
40 #include "compiler.hxx"
41 #include "bigrange.hxx"
42 #include "chgtrack.hxx"
44 //------------------------------------------------------------------------
46 template< typename R, typename S, typename U >
47 BOOL lcl_MoveStart( R& rRef, U nStart, S nDelta, U nMask )
49 BOOL bCut = FALSE;
50 if ( rRef >= nStart )
51 rRef = sal::static_int_cast<R>( rRef + nDelta );
52 else if ( nDelta < 0 && rRef >= nStart + nDelta )
53 rRef = nStart + nDelta; //! begrenzen ???
54 if ( rRef < 0 )
56 rRef = 0;
57 bCut = TRUE;
59 else if ( rRef > nMask )
61 rRef = nMask;
62 bCut = TRUE;
64 return bCut;
67 template< typename R, typename S, typename U >
68 BOOL lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask )
70 BOOL bCut = FALSE;
71 if ( rRef >= nStart )
72 rRef = sal::static_int_cast<R>( rRef + nDelta );
73 else if ( nDelta < 0 && rRef >= nStart + nDelta )
74 rRef = nStart + nDelta - 1; //! begrenzen ???
75 if ( rRef < 0 )
77 rRef = 0;
78 bCut = TRUE;
80 else if ( rRef > nMask )
82 rRef = nMask;
83 bCut = TRUE;
85 return bCut;
88 template< typename R, typename S, typename U >
89 BOOL lcl_MoveReorder( R& rRef, U nStart, U nEnd, S nDelta )
91 if ( rRef >= nStart && rRef <= nEnd )
93 rRef = sal::static_int_cast<R>( rRef + nDelta );
94 return TRUE;
97 if ( nDelta > 0 ) // nach hinten schieben
99 if ( rRef >= nStart && rRef <= nEnd + nDelta )
101 if ( rRef <= nEnd )
102 rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range
103 else
104 rRef -= nEnd - nStart + 1; // nachruecken
105 return TRUE;
108 else // nach vorne schieben
110 if ( rRef >= nStart + nDelta && rRef <= nEnd )
112 if ( rRef >= nStart )
113 rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range
114 else
115 rRef += nEnd - nStart + 1; // nachruecken
116 return TRUE;
120 return FALSE;
123 template< typename R, typename S, typename U >
124 BOOL lcl_MoveItCut( R& rRef, S nDelta, U nMask )
126 BOOL bCut = FALSE;
127 rRef = sal::static_int_cast<R>( rRef + nDelta );
128 if ( rRef < 0 )
130 rRef = 0;
131 bCut = TRUE;
133 else if ( rRef > nMask )
135 rRef = nMask;
136 bCut = TRUE;
138 return bCut;
141 template< typename R, typename S, typename U >
142 void lcl_MoveItWrap( R& rRef, S nDelta, U nMask )
144 rRef = sal::static_int_cast<R>( rRef + nDelta );
145 if ( rRef < 0 )
146 rRef += nMask+1;
147 else if ( rRef > nMask )
148 rRef -= nMask+1;
151 template< typename R, typename S, typename U >
152 BOOL lcl_MoveRefPart( R& rRef1Val, BOOL& rRef1Del, BOOL bDo1,
153 R& rRef2Val, BOOL& rRef2Del, BOOL bDo2,
154 U nStart, U nEnd, S nDelta, U nMask )
156 if ( nDelta )
158 BOOL bDel, bCut1, bCut2;
159 bDel = bCut1 = bCut2 = FALSE;
160 S n;
161 if (bDo1 && bDo2)
163 if ( nDelta < 0 )
165 n = nStart + nDelta;
166 if ( n <= rRef1Val && rRef1Val < nStart
167 && n <= rRef2Val && rRef2Val < nStart )
168 bDel = TRUE;
170 else
172 n = nEnd + nDelta;
173 if ( nEnd < rRef1Val && rRef1Val <= n
174 && nEnd < rRef2Val && rRef2Val <= n )
175 bDel = TRUE;
178 if ( bDel )
179 { // move deleted along
180 rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta );
181 rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta );
183 else
185 if (bDo1)
187 if ( rRef1Del )
188 rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta );
189 else
190 bCut1 = lcl_MoveStart( rRef1Val, nStart, nDelta, nMask );
192 if (bDo2)
194 if ( rRef2Del )
195 rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta );
196 else
197 bCut2 = lcl_MoveEnd( rRef2Val, nStart, nDelta, nMask );
200 if ( bDel || (bCut1 && bCut2) )
201 rRef1Del = rRef2Del = TRUE;
202 return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del;
204 else
205 return FALSE;
208 template< typename R, typename S, typename U >
209 BOOL IsExpand( R n1, R n2, U nStart, S nD )
210 { //! vor normalem Move...
211 return
212 nD > 0 // Insert
213 && n1 < n2 // mindestens zwei Cols/Rows/Tabs in Ref
214 && (
215 (nStart <= n1 && n1 < nStart + nD) // n1 innerhalb des Insert
216 || (n2 + 1 == nStart) // n2 direkt vor Insert
217 ); // n1 < nStart <= n2 wird sowieso expanded!
221 template< typename R, typename S, typename U >
222 void Expand( R& n1, R& n2, U nStart, S nD )
223 { //! nach normalem Move..., nur wenn IsExpand vorher TRUE war!
224 //! erst das Ende
225 if ( n2 + 1 == nStart )
226 { // am Ende
227 n2 = sal::static_int_cast<R>( n2 + nD );
228 return;
230 // am Anfang
231 n1 = sal::static_int_cast<R>( n1 - nD );
235 BOOL lcl_IsWrapBig( INT32 nRef, INT32 nDelta )
237 if ( nRef > 0 && nDelta > 0 )
238 return nRef + nDelta <= 0;
239 else if ( nRef < 0 && nDelta < 0 )
240 return nRef + nDelta >= 0;
241 return FALSE;
245 BOOL lcl_MoveBig( INT32& rRef, INT32 nStart, INT32 nDelta )
247 BOOL bCut = FALSE;
248 if ( rRef >= nStart )
250 if ( nDelta > 0 )
251 bCut = lcl_IsWrapBig( rRef, nDelta );
252 if ( bCut )
253 rRef = nInt32Max;
254 else
255 rRef += nDelta;
257 return bCut;
260 BOOL lcl_MoveItCutBig( INT32& rRef, INT32 nDelta )
262 BOOL bCut = lcl_IsWrapBig( rRef, nDelta );
263 rRef += nDelta;
264 return bCut;
268 ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
269 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
270 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
271 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
272 SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1,
273 SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 )
275 ScRefUpdateRes eRet = UR_NOTHING;
277 SCCOL oldCol1 = theCol1;
278 SCROW oldRow1 = theRow1;
279 SCTAB oldTab1 = theTab1;
280 SCCOL oldCol2 = theCol2;
281 SCROW oldRow2 = theRow2;
282 SCTAB oldTab2 = theTab2;
284 BOOL bCut1, bCut2;
286 if (eUpdateRefMode == URM_INSDEL)
288 BOOL bExpand = pDoc->IsExpandRefs();
289 if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
290 (theTab1 >= nTab1) && (theTab2 <= nTab2) )
292 BOOL bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx ));
293 bCut1 = lcl_MoveStart( theCol1, nCol1, nDx, MAXCOL );
294 bCut2 = lcl_MoveEnd( theCol2, nCol1, nDx, MAXCOL );
295 if ( theCol2 < theCol1 )
297 eRet = UR_INVALID;
298 theCol2 = theCol1;
300 else if ( bCut1 || bCut2 )
301 eRet = UR_UPDATED;
302 if ( bExp )
304 Expand( theCol1, theCol2, nCol1, nDx );
305 eRet = UR_UPDATED;
308 if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
309 (theTab1 >= nTab1) && (theTab2 <= nTab2) )
311 BOOL bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy ));
312 bCut1 = lcl_MoveStart( theRow1, nRow1, nDy, MAXROW );
313 bCut2 = lcl_MoveEnd( theRow2, nRow1, nDy, MAXROW );
314 if ( theRow2 < theRow1 )
316 eRet = UR_INVALID;
317 theRow2 = theRow1;
319 else if ( bCut1 || bCut2 )
320 eRet = UR_UPDATED;
321 if ( bExp )
323 Expand( theRow1, theRow2, nRow1, nDy );
324 eRet = UR_UPDATED;
327 if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
328 (theRow1 >= nRow1) && (theRow2 <= nRow2) )
330 SCsTAB nMaxTab = pDoc->GetTableCount() - 1;
331 nMaxTab = sal::static_int_cast<SCsTAB>(nMaxTab + nDz); // adjust to new count
332 BOOL bExp = (bExpand && IsExpand( theTab1, theTab2, nTab1, nDz ));
333 bCut1 = lcl_MoveStart( theTab1, nTab1, nDz, static_cast<SCTAB>(nMaxTab) );
334 bCut2 = lcl_MoveEnd( theTab2, nTab1, nDz, static_cast<SCTAB>(nMaxTab) );
335 if ( theTab2 < theTab1 )
337 eRet = UR_INVALID;
338 theTab2 = theTab1;
340 else if ( bCut1 || bCut2 )
341 eRet = UR_UPDATED;
342 if ( bExp )
344 Expand( theTab1, theTab2, nTab1, nDz );
345 eRet = UR_UPDATED;
349 else if (eUpdateRefMode == URM_MOVE)
351 if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) &&
352 (theCol2 <= nCol2-nDx) && (theRow2 <= nRow2-nDy) && (theTab2 <= nTab2-nDz))
354 if ( nDx )
356 bCut1 = lcl_MoveItCut( theCol1, nDx, MAXCOL );
357 bCut2 = lcl_MoveItCut( theCol2, nDx, MAXCOL );
358 if ( bCut1 || bCut2 )
359 eRet = UR_UPDATED;
361 if ( nDy )
363 bCut1 = lcl_MoveItCut( theRow1, nDy, MAXROW );
364 bCut2 = lcl_MoveItCut( theRow2, nDy, MAXROW );
365 if ( bCut1 || bCut2 )
366 eRet = UR_UPDATED;
368 if ( nDz )
370 SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
371 bCut1 = lcl_MoveItCut( theTab1, nDz, static_cast<SCTAB>(nMaxTab) );
372 bCut2 = lcl_MoveItCut( theTab2, nDz, static_cast<SCTAB>(nMaxTab) );
373 if ( bCut1 || bCut2 )
374 eRet = UR_UPDATED;
378 else if (eUpdateRefMode == URM_REORDER)
380 // bisher nur fuer nDz (MoveTab)
381 DBG_ASSERT ( !nDx && !nDy, "URM_REORDER fuer x und y noch nicht implementiert" );
383 if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
384 (theRow1 >= nRow1) && (theRow2 <= nRow2) )
386 bCut1 = lcl_MoveReorder( theTab1, nTab1, nTab2, nDz );
387 bCut2 = lcl_MoveReorder( theTab2, nTab1, nTab2, nDz );
388 if ( bCut1 || bCut2 )
389 eRet = UR_UPDATED;
393 if ( eRet == UR_NOTHING )
395 if (oldCol1 != theCol1
396 || oldRow1 != theRow1
397 || oldTab1 != theTab1
398 || oldCol2 != theCol2
399 || oldRow2 != theRow2
400 || oldTab2 != theTab2
402 eRet = UR_UPDATED;
404 return eRet;
408 // simples UpdateReference fuer ScBigRange (ScChangeAction/ScChangeTrack)
409 // Referenzen koennen auch ausserhalb des Dokuments liegen!
410 // Ganze Spalten/Zeilen (nInt32Min..nInt32Max) bleiben immer solche!
411 ScRefUpdateRes ScRefUpdate::Update( UpdateRefMode eUpdateRefMode,
412 const ScBigRange& rWhere, INT32 nDx, INT32 nDy, INT32 nDz,
413 ScBigRange& rWhat )
415 ScRefUpdateRes eRet = UR_NOTHING;
416 const ScBigRange aOldRange( rWhat );
418 INT32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2;
419 INT32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2;
420 rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
421 rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
423 BOOL bCut1, bCut2;
425 if (eUpdateRefMode == URM_INSDEL)
427 if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
428 (theTab1 >= nTab1) && (theTab2 <= nTab2) &&
429 !(theCol1 == nInt32Min && theCol2 == nInt32Max) )
431 bCut1 = lcl_MoveBig( theCol1, nCol1, nDx );
432 bCut2 = lcl_MoveBig( theCol2, nCol1, nDx );
433 if ( bCut1 || bCut2 )
434 eRet = UR_UPDATED;
435 rWhat.aStart.SetCol( theCol1 );
436 rWhat.aEnd.SetCol( theCol2 );
438 if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
439 (theTab1 >= nTab1) && (theTab2 <= nTab2) &&
440 !(theRow1 == nInt32Min && theRow2 == nInt32Max) )
442 bCut1 = lcl_MoveBig( theRow1, nRow1, nDy );
443 bCut2 = lcl_MoveBig( theRow2, nRow1, nDy );
444 if ( bCut1 || bCut2 )
445 eRet = UR_UPDATED;
446 rWhat.aStart.SetRow( theRow1 );
447 rWhat.aEnd.SetRow( theRow2 );
449 if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
450 (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
451 !(theTab1 == nInt32Min && theTab2 == nInt32Max) )
453 bCut1 = lcl_MoveBig( theTab1, nTab1, nDz );
454 bCut2 = lcl_MoveBig( theTab2, nTab1, nDz );
455 if ( bCut1 || bCut2 )
456 eRet = UR_UPDATED;
457 rWhat.aStart.SetTab( theTab1 );
458 rWhat.aEnd.SetTab( theTab2 );
461 else if (eUpdateRefMode == URM_MOVE)
463 if ( rWhere.In( rWhat ) )
465 if ( nDx && !(theCol1 == nInt32Min && theCol2 == nInt32Max) )
467 bCut1 = lcl_MoveItCutBig( theCol1, nDx );
468 bCut2 = lcl_MoveItCutBig( theCol2, nDx );
469 if ( bCut1 || bCut2 )
470 eRet = UR_UPDATED;
471 rWhat.aStart.SetCol( theCol1 );
472 rWhat.aEnd.SetCol( theCol2 );
474 if ( nDy && !(theRow1 == nInt32Min && theRow2 == nInt32Max) )
476 bCut1 = lcl_MoveItCutBig( theRow1, nDy );
477 bCut2 = lcl_MoveItCutBig( theRow2, nDy );
478 if ( bCut1 || bCut2 )
479 eRet = UR_UPDATED;
480 rWhat.aStart.SetRow( theRow1 );
481 rWhat.aEnd.SetRow( theRow2 );
483 if ( nDz && !(theTab1 == nInt32Min && theTab2 == nInt32Max) )
485 bCut1 = lcl_MoveItCutBig( theTab1, nDz );
486 bCut2 = lcl_MoveItCutBig( theTab2, nDz );
487 if ( bCut1 || bCut2 )
488 eRet = UR_UPDATED;
489 rWhat.aStart.SetTab( theTab1 );
490 rWhat.aEnd.SetTab( theTab2 );
495 if ( eRet == UR_NOTHING && rWhat != aOldRange )
496 eRet = UR_UPDATED;
498 return eRet;
502 ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eMode,
503 const ScAddress& rPos, const ScRange& r,
504 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
505 ScComplexRefData& rRef, WhatType eWhat )
507 ScRefUpdateRes eRet = UR_NOTHING;
509 SCCOL nCol1 = r.aStart.Col();
510 SCROW nRow1 = r.aStart.Row();
511 SCTAB nTab1 = r.aStart.Tab();
512 SCCOL nCol2 = r.aEnd.Col();
513 SCROW nRow2 = r.aEnd.Row();
514 SCTAB nTab2 = r.aEnd.Tab();
516 if( eMode == URM_INSDEL )
518 BOOL bExpand = pDoc->IsExpandRefs();
520 const ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
521 BOOL bInDeleteUndo =
522 ( pChangeTrack ? pChangeTrack->IsInDeleteUndo() : FALSE );
524 SCCOL oldCol1 = rRef.Ref1.nCol;
525 SCROW oldRow1 = rRef.Ref1.nRow;
526 SCTAB oldTab1 = rRef.Ref1.nTab;
527 SCCOL oldCol2 = rRef.Ref2.nCol;
528 SCROW oldRow2 = rRef.Ref2.nRow;
529 SCTAB oldTab2 = rRef.Ref2.nTab;
531 BOOL bRef1ColDel = rRef.Ref1.IsColDeleted();
532 BOOL bRef2ColDel = rRef.Ref2.IsColDeleted();
533 BOOL bRef1RowDel = rRef.Ref1.IsRowDeleted();
534 BOOL bRef2RowDel = rRef.Ref2.IsRowDeleted();
535 BOOL bRef1TabDel = rRef.Ref1.IsTabDeleted();
536 BOOL bRef2TabDel = rRef.Ref2.IsTabDeleted();
538 if( nDx &&
539 ((rRef.Ref1.nRow >= nRow1
540 && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel))
542 ((rRef.Ref1.nTab >= nTab1
543 && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel))
546 BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nCol,
547 rRef.Ref2.nCol, nCol1, nDx ));
548 BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat ==
549 ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsColRel()));
550 BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat ==
551 ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsColRel()));
552 if ( lcl_MoveRefPart( rRef.Ref1.nCol, bRef1ColDel, bDo1,
553 rRef.Ref2.nCol, bRef2ColDel, bDo2,
554 nCol1, nCol2, nDx, MAXCOL ) )
556 eRet = UR_UPDATED;
557 if ( bInDeleteUndo && (bRef1ColDel || bRef2ColDel) )
559 if ( bRef1ColDel && nCol1 <= rRef.Ref1.nCol &&
560 rRef.Ref1.nCol <= nCol1 + nDx )
561 rRef.Ref1.SetColDeleted( FALSE );
562 if ( bRef2ColDel && nCol1 <= rRef.Ref2.nCol &&
563 rRef.Ref2.nCol <= nCol1 + nDx )
564 rRef.Ref2.SetColDeleted( FALSE );
566 else
568 if ( bRef1ColDel )
569 rRef.Ref1.SetColDeleted( TRUE );
570 if ( bRef2ColDel )
571 rRef.Ref2.SetColDeleted( TRUE );
574 if ( bExp )
576 Expand( rRef.Ref1.nCol, rRef.Ref2.nCol, nCol1, nDx );
577 eRet = UR_UPDATED;
580 if( nDy &&
581 ((rRef.Ref1.nCol >= nCol1
582 && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel))
584 ((rRef.Ref1.nTab >= nTab1
585 && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel))
588 BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nRow,
589 rRef.Ref2.nRow, nRow1, nDy ));
590 BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat ==
591 ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsRowRel()));
592 BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat ==
593 ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsRowRel()));
594 if ( lcl_MoveRefPart( rRef.Ref1.nRow, bRef1RowDel, bDo1,
595 rRef.Ref2.nRow, bRef2RowDel, bDo2,
596 nRow1, nRow2, nDy, MAXROW ) )
598 eRet = UR_UPDATED;
599 if ( bInDeleteUndo && (bRef1RowDel || bRef2RowDel) )
601 if ( bRef1RowDel && nRow1 <= rRef.Ref1.nRow &&
602 rRef.Ref1.nRow <= nRow1 + nDy )
603 rRef.Ref1.SetRowDeleted( FALSE );
604 if ( bRef2RowDel && nRow1 <= rRef.Ref2.nRow &&
605 rRef.Ref2.nRow <= nRow1 + nDy )
606 rRef.Ref2.SetRowDeleted( FALSE );
608 else
610 if ( bRef1RowDel )
611 rRef.Ref1.SetRowDeleted( TRUE );
612 if ( bRef2RowDel )
613 rRef.Ref2.SetRowDeleted( TRUE );
616 if ( bExp )
618 Expand( rRef.Ref1.nRow, rRef.Ref2.nRow, nRow1, nDy );
619 eRet = UR_UPDATED;
622 if( nDz &&
623 ((rRef.Ref1.nCol >= nCol1
624 && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel))
626 ((rRef.Ref1.nRow >= nRow1
627 && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel))
630 BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nTab,
631 rRef.Ref2.nTab, nTab1, nDz ));
632 SCTAB nMaxTab = pDoc->GetTableCount() - 1;
633 BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat ==
634 ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsTabRel()));
635 BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat ==
636 ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsTabRel()));
637 if ( lcl_MoveRefPart( rRef.Ref1.nTab, bRef1TabDel, bDo1,
638 rRef.Ref2.nTab, bRef2TabDel, bDo2,
639 nTab1, nTab2, nDz, nMaxTab ) )
641 eRet = UR_UPDATED;
642 if ( bInDeleteUndo && (bRef1TabDel || bRef2TabDel) )
644 if ( bRef1TabDel && nTab1 <= rRef.Ref1.nTab &&
645 rRef.Ref1.nTab <= nTab1 + nDz )
646 rRef.Ref1.SetTabDeleted( FALSE );
647 if ( bRef2TabDel && nTab1 <= rRef.Ref2.nTab &&
648 rRef.Ref2.nTab <= nTab1 + nDz )
649 rRef.Ref2.SetTabDeleted( FALSE );
651 else
653 if ( bRef1TabDel )
654 rRef.Ref1.SetTabDeleted( TRUE );
655 if ( bRef2TabDel )
656 rRef.Ref2.SetTabDeleted( TRUE );
659 if ( bExp )
661 Expand( rRef.Ref1.nTab, rRef.Ref2.nTab, nTab1, nDz );
662 eRet = UR_UPDATED;
665 if ( eRet == UR_NOTHING )
667 if (oldCol1 != rRef.Ref1.nCol
668 || oldRow1 != rRef.Ref1.nRow
669 || oldTab1 != rRef.Ref1.nTab
670 || oldCol2 != rRef.Ref2.nCol
671 || oldRow2 != rRef.Ref2.nRow
672 || oldTab2 != rRef.Ref2.nTab
674 eRet = UR_UPDATED;
676 if (eWhat != ScRefUpdate::ABSOLUTE)
677 rRef.CalcRelFromAbs( rPos );
679 else
681 if( eMode == URM_MOVE )
683 if ( rRef.Ref1.nCol >= nCol1-nDx
684 && rRef.Ref1.nRow >= nRow1-nDy
685 && rRef.Ref1.nTab >= nTab1-nDz
686 && rRef.Ref2.nCol <= nCol2-nDx
687 && rRef.Ref2.nRow <= nRow2-nDy
688 && rRef.Ref2.nTab <= nTab2-nDz )
690 eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, TRUE ); // immer verschieben
692 else if ( nDz && r.In( rPos ) )
694 rRef.Ref1.SetFlag3D( TRUE );
695 rRef.Ref2.SetFlag3D( TRUE );
696 eRet = UR_UPDATED;
697 if (eWhat != ScRefUpdate::ABSOLUTE)
698 rRef.CalcRelFromAbs( rPos );
700 else if (eWhat != ScRefUpdate::ABSOLUTE)
701 rRef.CalcRelFromAbs( rPos );
703 else if( eMode == URM_COPY && r.In( rPos ) )
704 eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, FALSE ); // nur relative
705 // sollte nicht mehr verwendet werden muessen
706 else if (eWhat != ScRefUpdate::ABSOLUTE)
707 rRef.CalcRelFromAbs( rPos );
709 return eRet;
713 ScRefUpdateRes ScRefUpdate::Move( ScDocument* pDoc, const ScAddress& rPos,
714 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
715 ScComplexRefData& rRef, BOOL bWrap, BOOL bAbsolute )
717 ScRefUpdateRes eRet = UR_NOTHING;
719 SCCOL oldCol1 = rRef.Ref1.nCol;
720 SCROW oldRow1 = rRef.Ref1.nRow;
721 SCTAB oldTab1 = rRef.Ref1.nTab;
722 SCCOL oldCol2 = rRef.Ref2.nCol;
723 SCROW oldRow2 = rRef.Ref2.nRow;
724 SCTAB oldTab2 = rRef.Ref2.nTab;
726 BOOL bCut1, bCut2;
727 if ( nDx )
729 bCut1 = bCut2 = FALSE;
730 if( bAbsolute || rRef.Ref1.IsColRel() )
732 if( bWrap )
733 lcl_MoveItWrap( rRef.Ref1.nCol, nDx, MAXCOL );
734 else
735 bCut1 = lcl_MoveItCut( rRef.Ref1.nCol, nDx, MAXCOL );
737 if( bAbsolute || rRef.Ref2.IsColRel() )
739 if( bWrap )
740 lcl_MoveItWrap( rRef.Ref2.nCol, nDx, MAXCOL );
741 else
742 bCut2 = lcl_MoveItCut( rRef.Ref2.nCol, nDx, MAXCOL );
744 if ( bCut1 || bCut2 )
745 eRet = UR_UPDATED;
746 if ( bCut1 && bCut2 )
748 rRef.Ref1.SetColDeleted( TRUE );
749 rRef.Ref2.SetColDeleted( TRUE );
752 if ( nDy )
754 bCut1 = bCut2 = FALSE;
755 if( bAbsolute || rRef.Ref1.IsRowRel() )
757 if( bWrap )
758 lcl_MoveItWrap( rRef.Ref1.nRow, nDy, MAXROW );
759 else
760 bCut1 = lcl_MoveItCut( rRef.Ref1.nRow, nDy, MAXROW );
762 if( bAbsolute || rRef.Ref2.IsRowRel() )
764 if( bWrap )
765 lcl_MoveItWrap( rRef.Ref2.nRow, nDy, MAXROW );
766 else
767 bCut2 = lcl_MoveItCut( rRef.Ref2.nRow, nDy, MAXROW );
769 if ( bCut1 || bCut2 )
770 eRet = UR_UPDATED;
771 if ( bCut1 && bCut2 )
773 rRef.Ref1.SetRowDeleted( TRUE );
774 rRef.Ref2.SetRowDeleted( TRUE );
777 if ( nDz )
779 bCut1 = bCut2 = FALSE;
780 SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
781 if( bAbsolute || rRef.Ref1.IsTabRel() )
783 if( bWrap )
784 lcl_MoveItWrap( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
785 else
786 bCut1 = lcl_MoveItCut( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
787 rRef.Ref1.SetFlag3D( rPos.Tab() != rRef.Ref1.nTab );
789 if( bAbsolute || rRef.Ref2.IsTabRel() )
791 if( bWrap )
792 lcl_MoveItWrap( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
793 else
794 bCut2 = lcl_MoveItCut( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
795 rRef.Ref2.SetFlag3D( rPos.Tab() != rRef.Ref2.nTab );
797 if ( bCut1 || bCut2 )
798 eRet = UR_UPDATED;
799 if ( bCut1 && bCut2 )
801 rRef.Ref1.SetTabDeleted( TRUE );
802 rRef.Ref2.SetTabDeleted( TRUE );
806 if ( eRet == UR_NOTHING )
808 if (oldCol1 != rRef.Ref1.nCol
809 || oldRow1 != rRef.Ref1.nRow
810 || oldTab1 != rRef.Ref1.nTab
811 || oldCol2 != rRef.Ref2.nCol
812 || oldRow2 != rRef.Ref2.nRow
813 || oldTab2 != rRef.Ref2.nTab
815 eRet = UR_UPDATED;
817 if ( bWrap && eRet != UR_NOTHING )
818 rRef.PutInOrder();
819 rRef.CalcRelFromAbs( rPos );
820 return eRet;
823 void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos,
824 SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef )
826 if( rRef.Ref1.IsColRel() )
828 rRef.Ref1.nCol = rRef.Ref1.nRelCol + rPos.Col();
829 lcl_MoveItWrap( rRef.Ref1.nCol, static_cast<SCsCOL>(0), nMaxCol );
831 if( rRef.Ref2.IsColRel() )
833 rRef.Ref2.nCol = rRef.Ref2.nRelCol + rPos.Col();
834 lcl_MoveItWrap( rRef.Ref2.nCol, static_cast<SCsCOL>(0), nMaxCol );
836 if( rRef.Ref1.IsRowRel() )
838 rRef.Ref1.nRow = rRef.Ref1.nRelRow + rPos.Row();
839 lcl_MoveItWrap( rRef.Ref1.nRow, static_cast<SCsROW>(0), nMaxRow );
841 if( rRef.Ref2.IsRowRel() )
843 rRef.Ref2.nRow = rRef.Ref2.nRelRow + rPos.Row();
844 lcl_MoveItWrap( rRef.Ref2.nRow, static_cast<SCsROW>(0), nMaxRow );
846 SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
847 if( rRef.Ref1.IsTabRel() )
849 rRef.Ref1.nTab = rRef.Ref1.nRelTab + rPos.Tab();
850 lcl_MoveItWrap( rRef.Ref1.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) );
852 if( rRef.Ref2.IsTabRel() )
854 rRef.Ref2.nTab = rRef.Ref2.nRelTab + rPos.Tab();
855 lcl_MoveItWrap( rRef.Ref2.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) );
857 rRef.PutInOrder();
858 rRef.CalcRelFromAbs( rPos );
861 //------------------------------------------------------------------
863 void ScRefUpdate::DoTranspose( SCsCOL& rCol, SCsROW& rRow, SCsTAB& rTab,
864 ScDocument* pDoc, const ScRange& rSource, const ScAddress& rDest )
866 SCsTAB nDz = ((SCsTAB)rDest.Tab())-(SCsTAB)rSource.aStart.Tab();
867 if (nDz)
869 SCsTAB nNewTab = rTab+nDz;
870 SCsTAB nCount = pDoc->GetTableCount();
871 while (nNewTab<0) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab + nCount );
872 while (nNewTab>=nCount) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab - nCount );
873 rTab = nNewTab;
875 DBG_ASSERT( rCol>=rSource.aStart.Col() && rRow>=rSource.aStart.Row(),
876 "UpdateTranspose: Pos. falsch" );
878 SCsCOL nRelX = rCol - (SCsCOL)rSource.aStart.Col();
879 SCsROW nRelY = rRow - (SCsROW)rSource.aStart.Row();
881 rCol = static_cast<SCsCOL>(static_cast<SCsCOLROW>(rDest.Col()) +
882 static_cast<SCsCOLROW>(nRelY));
883 rRow = static_cast<SCsROW>(static_cast<SCsCOLROW>(rDest.Row()) +
884 static_cast<SCsCOLROW>(nRelX));
888 ScRefUpdateRes ScRefUpdate::UpdateTranspose( ScDocument* pDoc,
889 const ScRange& rSource, const ScAddress& rDest,
890 ScComplexRefData& rRef )
892 ScRefUpdateRes eRet = UR_NOTHING;
893 if ( rRef.Ref1.nCol >= rSource.aStart.Col() && rRef.Ref2.nCol <= rSource.aEnd.Col() &&
894 rRef.Ref1.nRow >= rSource.aStart.Row() && rRef.Ref2.nRow <= rSource.aEnd.Row() &&
895 rRef.Ref1.nTab >= rSource.aStart.Tab() && rRef.Ref2.nTab <= rSource.aEnd.Tab() )
897 DoTranspose( rRef.Ref1.nCol, rRef.Ref1.nRow, rRef.Ref1.nTab, pDoc, rSource, rDest );
898 DoTranspose( rRef.Ref2.nCol, rRef.Ref2.nRow, rRef.Ref2.nTab, pDoc, rSource, rDest );
899 eRet = UR_UPDATED;
901 return eRet;
904 //------------------------------------------------------------------
906 // UpdateGrow - erweitert Referenzen, die genau auf den Bereich zeigen
907 // kommt ohne Dokument aus
910 ScRefUpdateRes ScRefUpdate::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY,
911 ScComplexRefData& rRef )
913 ScRefUpdateRes eRet = UR_NOTHING;
915 // in Y-Richtung darf die Ref auch eine Zeile weiter unten anfangen,
916 // falls ein Bereich Spaltenkoepfe enthaelt
918 BOOL bUpdateX = ( nGrowX &&
919 rRef.Ref1.nCol == rArea.aStart.Col() && rRef.Ref2.nCol == rArea.aEnd.Col() &&
920 rRef.Ref1.nRow >= rArea.aStart.Row() && rRef.Ref2.nRow <= rArea.aEnd.Row() &&
921 rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() );
922 BOOL bUpdateY = ( nGrowY &&
923 rRef.Ref1.nCol >= rArea.aStart.Col() && rRef.Ref2.nCol <= rArea.aEnd.Col() &&
924 ( rRef.Ref1.nRow == rArea.aStart.Row() || rRef.Ref1.nRow == rArea.aStart.Row()+1 ) &&
925 rRef.Ref2.nRow == rArea.aEnd.Row() &&
926 rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() );
928 if ( bUpdateX )
930 rRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( rRef.Ref2.nCol + nGrowX );
931 eRet = UR_UPDATED;
933 if ( bUpdateY )
935 rRef.Ref2.nRow = sal::static_int_cast<SCsROW>( rRef.Ref2.nRow + nGrowY );
936 eRet = UR_UPDATED;
939 return eRet;