1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 // INCLUDE --------------------------------------------------------------- 28 29 #include <tools/debug.hxx> 30 31 #include "refupdat.hxx" 32 #include "document.hxx" 33 #include "compiler.hxx" 34 #include "bigrange.hxx" 35 #include "chgtrack.hxx" 36 37 //------------------------------------------------------------------------ 38 39 template< typename R, typename S, typename U > 40 sal_Bool lcl_MoveStart( R& rRef, U nStart, S nDelta, U nMask ) 41 { 42 sal_Bool bCut = sal_False; 43 if ( rRef >= nStart ) 44 rRef = sal::static_int_cast<R>( rRef + nDelta ); 45 else if ( nDelta < 0 && rRef >= nStart + nDelta ) 46 rRef = nStart + nDelta; //! begrenzen ??? 47 if ( rRef < 0 ) 48 { 49 rRef = 0; 50 bCut = sal_True; 51 } 52 else if ( rRef > nMask ) 53 { 54 rRef = nMask; 55 bCut = sal_True; 56 } 57 return bCut; 58 } 59 60 template< typename R, typename S, typename U > 61 sal_Bool lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask ) 62 { 63 sal_Bool bCut = sal_False; 64 if ( rRef >= nStart ) 65 rRef = sal::static_int_cast<R>( rRef + nDelta ); 66 else if ( nDelta < 0 && rRef >= nStart + nDelta ) 67 rRef = nStart + nDelta - 1; //! begrenzen ??? 68 if ( rRef < 0 ) 69 { 70 rRef = 0; 71 bCut = sal_True; 72 } 73 else if ( rRef > nMask ) 74 { 75 rRef = nMask; 76 bCut = sal_True; 77 } 78 return bCut; 79 } 80 81 template< typename R, typename S, typename U > 82 sal_Bool lcl_MoveReorder( R& rRef, U nStart, U nEnd, S nDelta ) 83 { 84 if ( rRef >= nStart && rRef <= nEnd ) 85 { 86 rRef = sal::static_int_cast<R>( rRef + nDelta ); 87 return sal_True; 88 } 89 90 if ( nDelta > 0 ) // nach hinten schieben 91 { 92 if ( rRef >= nStart && rRef <= nEnd + nDelta ) 93 { 94 if ( rRef <= nEnd ) 95 rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range 96 else 97 rRef -= nEnd - nStart + 1; // nachruecken 98 return sal_True; 99 } 100 } 101 else // nach vorne schieben 102 { 103 if ( rRef >= nStart + nDelta && rRef <= nEnd ) 104 { 105 if ( rRef >= nStart ) 106 rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range 107 else 108 rRef += nEnd - nStart + 1; // nachruecken 109 return sal_True; 110 } 111 } 112 113 return sal_False; 114 } 115 116 template< typename R, typename S, typename U > 117 sal_Bool lcl_MoveItCut( R& rRef, S nDelta, U nMask ) 118 { 119 sal_Bool bCut = sal_False; 120 rRef = sal::static_int_cast<R>( rRef + nDelta ); 121 if ( rRef < 0 ) 122 { 123 rRef = 0; 124 bCut = sal_True; 125 } 126 else if ( rRef > nMask ) 127 { 128 rRef = nMask; 129 bCut = sal_True; 130 } 131 return bCut; 132 } 133 134 template< typename R, typename S, typename U > 135 void lcl_MoveItWrap( R& rRef, S nDelta, U nMask ) 136 { 137 rRef = sal::static_int_cast<R>( rRef + nDelta ); 138 if ( rRef < 0 ) 139 rRef += nMask+1; 140 else if ( rRef > nMask ) 141 rRef -= nMask+1; 142 } 143 144 template< typename R, typename S, typename U > 145 sal_Bool lcl_MoveRefPart( R& rRef1Val, sal_Bool& rRef1Del, sal_Bool bDo1, 146 R& rRef2Val, sal_Bool& rRef2Del, sal_Bool bDo2, 147 U nStart, U nEnd, S nDelta, U nMask ) 148 { 149 if ( nDelta ) 150 { 151 sal_Bool bDel, bCut1, bCut2; 152 bDel = bCut1 = bCut2 = sal_False; 153 S n; 154 if (bDo1 && bDo2) 155 { 156 if ( nDelta < 0 ) 157 { 158 n = nStart + nDelta; 159 if ( n <= rRef1Val && rRef1Val < nStart 160 && n <= rRef2Val && rRef2Val < nStart ) 161 bDel = sal_True; 162 } 163 else 164 { 165 n = nEnd + nDelta; 166 if ( nEnd < rRef1Val && rRef1Val <= n 167 && nEnd < rRef2Val && rRef2Val <= n ) 168 bDel = sal_True; 169 } 170 } 171 if ( bDel ) 172 { // move deleted along 173 rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta ); 174 rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta ); 175 } 176 else 177 { 178 if (bDo1) 179 { 180 if ( rRef1Del ) 181 rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta ); 182 else 183 bCut1 = lcl_MoveStart( rRef1Val, nStart, nDelta, nMask ); 184 } 185 if (bDo2) 186 { 187 if ( rRef2Del ) 188 rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta ); 189 else 190 bCut2 = lcl_MoveEnd( rRef2Val, nStart, nDelta, nMask ); 191 } 192 } 193 if ( bDel || (bCut1 && bCut2) ) 194 rRef1Del = rRef2Del = sal_True; 195 return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del; 196 } 197 else 198 return sal_False; 199 } 200 201 template< typename R, typename S, typename U > 202 sal_Bool IsExpand( R n1, R n2, U nStart, S nD ) 203 { //! vor normalem Move... 204 return 205 nD > 0 // Insert 206 && n1 < n2 // mindestens zwei Cols/Rows/Tabs in Ref 207 && ( 208 (nStart <= n1 && n1 < nStart + nD) // n1 innerhalb des Insert 209 || (n2 + 1 == nStart) // n2 direkt vor Insert 210 ); // n1 < nStart <= n2 wird sowieso expanded! 211 } 212 213 214 template< typename R, typename S, typename U > 215 void Expand( R& n1, R& n2, U nStart, S nD ) 216 { //! nach normalem Move..., nur wenn IsExpand vorher sal_True war! 217 //! erst das Ende 218 if ( n2 + 1 == nStart ) 219 { // am Ende 220 n2 = sal::static_int_cast<R>( n2 + nD ); 221 return; 222 } 223 // am Anfang 224 n1 = sal::static_int_cast<R>( n1 - nD ); 225 } 226 227 228 sal_Bool lcl_IsWrapBig( sal_Int32 nRef, sal_Int32 nDelta ) 229 { 230 if ( nRef > 0 && nDelta > 0 ) 231 return nRef + nDelta <= 0; 232 else if ( nRef < 0 && nDelta < 0 ) 233 return nRef + nDelta >= 0; 234 return sal_False; 235 } 236 237 238 sal_Bool lcl_MoveBig( sal_Int32& rRef, sal_Int32 nStart, sal_Int32 nDelta ) 239 { 240 sal_Bool bCut = sal_False; 241 if ( rRef >= nStart ) 242 { 243 if ( nDelta > 0 ) 244 bCut = lcl_IsWrapBig( rRef, nDelta ); 245 if ( bCut ) 246 rRef = nInt32Max; 247 else 248 rRef += nDelta; 249 } 250 return bCut; 251 } 252 253 sal_Bool lcl_MoveItCutBig( sal_Int32& rRef, sal_Int32 nDelta ) 254 { 255 sal_Bool bCut = lcl_IsWrapBig( rRef, nDelta ); 256 rRef += nDelta; 257 return bCut; 258 } 259 260 261 ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMode, 262 SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 263 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, 264 SCsCOL nDx, SCsROW nDy, SCsTAB nDz, 265 SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1, 266 SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 ) 267 { 268 ScRefUpdateRes eRet = UR_NOTHING; 269 270 SCCOL oldCol1 = theCol1; 271 SCROW oldRow1 = theRow1; 272 SCTAB oldTab1 = theTab1; 273 SCCOL oldCol2 = theCol2; 274 SCROW oldRow2 = theRow2; 275 SCTAB oldTab2 = theTab2; 276 277 sal_Bool bCut1, bCut2; 278 279 if (eUpdateRefMode == URM_INSDEL) 280 { 281 sal_Bool bExpand = pDoc->IsExpandRefs(); 282 if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && 283 (theTab1 >= nTab1) && (theTab2 <= nTab2) ) 284 { 285 sal_Bool bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx )); 286 bCut1 = lcl_MoveStart( theCol1, nCol1, nDx, MAXCOL ); 287 bCut2 = lcl_MoveEnd( theCol2, nCol1, nDx, MAXCOL ); 288 if ( theCol2 < theCol1 ) 289 { 290 eRet = UR_INVALID; 291 theCol2 = theCol1; 292 } 293 else if ( bCut1 || bCut2 ) 294 eRet = UR_UPDATED; 295 if ( bExp ) 296 { 297 Expand( theCol1, theCol2, nCol1, nDx ); 298 eRet = UR_UPDATED; 299 } 300 } 301 if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && 302 (theTab1 >= nTab1) && (theTab2 <= nTab2) ) 303 { 304 sal_Bool bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy )); 305 bCut1 = lcl_MoveStart( theRow1, nRow1, nDy, MAXROW ); 306 bCut2 = lcl_MoveEnd( theRow2, nRow1, nDy, MAXROW ); 307 if ( theRow2 < theRow1 ) 308 { 309 eRet = UR_INVALID; 310 theRow2 = theRow1; 311 } 312 else if ( bCut1 || bCut2 ) 313 eRet = UR_UPDATED; 314 if ( bExp ) 315 { 316 Expand( theRow1, theRow2, nRow1, nDy ); 317 eRet = UR_UPDATED; 318 } 319 } 320 if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && 321 (theRow1 >= nRow1) && (theRow2 <= nRow2) ) 322 { 323 SCsTAB nMaxTab = pDoc->GetTableCount() - 1; 324 nMaxTab = sal::static_int_cast<SCsTAB>(nMaxTab + nDz); // adjust to new count 325 sal_Bool bExp = (bExpand && IsExpand( theTab1, theTab2, nTab1, nDz )); 326 bCut1 = lcl_MoveStart( theTab1, nTab1, nDz, static_cast<SCTAB>(nMaxTab) ); 327 bCut2 = lcl_MoveEnd( theTab2, nTab1, nDz, static_cast<SCTAB>(nMaxTab) ); 328 if ( theTab2 < theTab1 ) 329 { 330 eRet = UR_INVALID; 331 theTab2 = theTab1; 332 } 333 else if ( bCut1 || bCut2 ) 334 eRet = UR_UPDATED; 335 if ( bExp ) 336 { 337 Expand( theTab1, theTab2, nTab1, nDz ); 338 eRet = UR_UPDATED; 339 } 340 } 341 } 342 else if (eUpdateRefMode == URM_MOVE) 343 { 344 if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) && 345 (theCol2 <= nCol2-nDx) && (theRow2 <= nRow2-nDy) && (theTab2 <= nTab2-nDz)) 346 { 347 if ( nDx ) 348 { 349 bCut1 = lcl_MoveItCut( theCol1, nDx, MAXCOL ); 350 bCut2 = lcl_MoveItCut( theCol2, nDx, MAXCOL ); 351 if ( bCut1 || bCut2 ) 352 eRet = UR_UPDATED; 353 } 354 if ( nDy ) 355 { 356 bCut1 = lcl_MoveItCut( theRow1, nDy, MAXROW ); 357 bCut2 = lcl_MoveItCut( theRow2, nDy, MAXROW ); 358 if ( bCut1 || bCut2 ) 359 eRet = UR_UPDATED; 360 } 361 if ( nDz ) 362 { 363 SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1; 364 bCut1 = lcl_MoveItCut( theTab1, nDz, static_cast<SCTAB>(nMaxTab) ); 365 bCut2 = lcl_MoveItCut( theTab2, nDz, static_cast<SCTAB>(nMaxTab) ); 366 if ( bCut1 || bCut2 ) 367 eRet = UR_UPDATED; 368 } 369 } 370 } 371 else if (eUpdateRefMode == URM_REORDER) 372 { 373 // bisher nur fuer nDz (MoveTab) 374 DBG_ASSERT ( !nDx && !nDy, "URM_REORDER fuer x und y noch nicht implementiert" ); 375 376 if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && 377 (theRow1 >= nRow1) && (theRow2 <= nRow2) ) 378 { 379 bCut1 = lcl_MoveReorder( theTab1, nTab1, nTab2, nDz ); 380 bCut2 = lcl_MoveReorder( theTab2, nTab1, nTab2, nDz ); 381 if ( bCut1 || bCut2 ) 382 eRet = UR_UPDATED; 383 } 384 } 385 386 if ( eRet == UR_NOTHING ) 387 { 388 if (oldCol1 != theCol1 389 || oldRow1 != theRow1 390 || oldTab1 != theTab1 391 || oldCol2 != theCol2 392 || oldRow2 != theRow2 393 || oldTab2 != theTab2 394 ) 395 eRet = UR_UPDATED; 396 } 397 return eRet; 398 } 399 400 401 // simples UpdateReference fuer ScBigRange (ScChangeAction/ScChangeTrack) 402 // Referenzen koennen auch ausserhalb des Dokuments liegen! 403 // Ganze Spalten/Zeilen (nInt32Min..nInt32Max) bleiben immer solche! 404 ScRefUpdateRes ScRefUpdate::Update( UpdateRefMode eUpdateRefMode, 405 const ScBigRange& rWhere, sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz, 406 ScBigRange& rWhat ) 407 { 408 ScRefUpdateRes eRet = UR_NOTHING; 409 const ScBigRange aOldRange( rWhat ); 410 411 sal_Int32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; 412 sal_Int32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; 413 rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); 414 rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); 415 416 sal_Bool bCut1, bCut2; 417 418 if (eUpdateRefMode == URM_INSDEL) 419 { 420 if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && 421 (theTab1 >= nTab1) && (theTab2 <= nTab2) && 422 !(theCol1 == nInt32Min && theCol2 == nInt32Max) ) 423 { 424 bCut1 = lcl_MoveBig( theCol1, nCol1, nDx ); 425 bCut2 = lcl_MoveBig( theCol2, nCol1, nDx ); 426 if ( bCut1 || bCut2 ) 427 eRet = UR_UPDATED; 428 rWhat.aStart.SetCol( theCol1 ); 429 rWhat.aEnd.SetCol( theCol2 ); 430 } 431 if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && 432 (theTab1 >= nTab1) && (theTab2 <= nTab2) && 433 !(theRow1 == nInt32Min && theRow2 == nInt32Max) ) 434 { 435 bCut1 = lcl_MoveBig( theRow1, nRow1, nDy ); 436 bCut2 = lcl_MoveBig( theRow2, nRow1, nDy ); 437 if ( bCut1 || bCut2 ) 438 eRet = UR_UPDATED; 439 rWhat.aStart.SetRow( theRow1 ); 440 rWhat.aEnd.SetRow( theRow2 ); 441 } 442 if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && 443 (theRow1 >= nRow1) && (theRow2 <= nRow2) && 444 !(theTab1 == nInt32Min && theTab2 == nInt32Max) ) 445 { 446 bCut1 = lcl_MoveBig( theTab1, nTab1, nDz ); 447 bCut2 = lcl_MoveBig( theTab2, nTab1, nDz ); 448 if ( bCut1 || bCut2 ) 449 eRet = UR_UPDATED; 450 rWhat.aStart.SetTab( theTab1 ); 451 rWhat.aEnd.SetTab( theTab2 ); 452 } 453 } 454 else if (eUpdateRefMode == URM_MOVE) 455 { 456 if ( rWhere.In( rWhat ) ) 457 { 458 if ( nDx && !(theCol1 == nInt32Min && theCol2 == nInt32Max) ) 459 { 460 bCut1 = lcl_MoveItCutBig( theCol1, nDx ); 461 bCut2 = lcl_MoveItCutBig( theCol2, nDx ); 462 if ( bCut1 || bCut2 ) 463 eRet = UR_UPDATED; 464 rWhat.aStart.SetCol( theCol1 ); 465 rWhat.aEnd.SetCol( theCol2 ); 466 } 467 if ( nDy && !(theRow1 == nInt32Min && theRow2 == nInt32Max) ) 468 { 469 bCut1 = lcl_MoveItCutBig( theRow1, nDy ); 470 bCut2 = lcl_MoveItCutBig( theRow2, nDy ); 471 if ( bCut1 || bCut2 ) 472 eRet = UR_UPDATED; 473 rWhat.aStart.SetRow( theRow1 ); 474 rWhat.aEnd.SetRow( theRow2 ); 475 } 476 if ( nDz && !(theTab1 == nInt32Min && theTab2 == nInt32Max) ) 477 { 478 bCut1 = lcl_MoveItCutBig( theTab1, nDz ); 479 bCut2 = lcl_MoveItCutBig( theTab2, nDz ); 480 if ( bCut1 || bCut2 ) 481 eRet = UR_UPDATED; 482 rWhat.aStart.SetTab( theTab1 ); 483 rWhat.aEnd.SetTab( theTab2 ); 484 } 485 } 486 } 487 488 if ( eRet == UR_NOTHING && rWhat != aOldRange ) 489 eRet = UR_UPDATED; 490 491 return eRet; 492 } 493 494 495 ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eMode, 496 const ScAddress& rPos, const ScRange& r, 497 SCsCOL nDx, SCsROW nDy, SCsTAB nDz, 498 ScComplexRefData& rRef, WhatType eWhat ) 499 { 500 ScRefUpdateRes eRet = UR_NOTHING; 501 502 SCCOL nCol1 = r.aStart.Col(); 503 SCROW nRow1 = r.aStart.Row(); 504 SCTAB nTab1 = r.aStart.Tab(); 505 SCCOL nCol2 = r.aEnd.Col(); 506 SCROW nRow2 = r.aEnd.Row(); 507 SCTAB nTab2 = r.aEnd.Tab(); 508 509 if( eMode == URM_INSDEL ) 510 { 511 sal_Bool bExpand = pDoc->IsExpandRefs(); 512 513 const ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 514 sal_Bool bInDeleteUndo = 515 ( pChangeTrack ? pChangeTrack->IsInDeleteUndo() : sal_False ); 516 517 SCCOL oldCol1 = rRef.Ref1.nCol; 518 SCROW oldRow1 = rRef.Ref1.nRow; 519 SCTAB oldTab1 = rRef.Ref1.nTab; 520 SCCOL oldCol2 = rRef.Ref2.nCol; 521 SCROW oldRow2 = rRef.Ref2.nRow; 522 SCTAB oldTab2 = rRef.Ref2.nTab; 523 524 sal_Bool bRef1ColDel = rRef.Ref1.IsColDeleted(); 525 sal_Bool bRef2ColDel = rRef.Ref2.IsColDeleted(); 526 sal_Bool bRef1RowDel = rRef.Ref1.IsRowDeleted(); 527 sal_Bool bRef2RowDel = rRef.Ref2.IsRowDeleted(); 528 sal_Bool bRef1TabDel = rRef.Ref1.IsTabDeleted(); 529 sal_Bool bRef2TabDel = rRef.Ref2.IsTabDeleted(); 530 531 if( nDx && 532 ((rRef.Ref1.nRow >= nRow1 533 && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel)) 534 && 535 ((rRef.Ref1.nTab >= nTab1 536 && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel)) 537 ) 538 { 539 sal_Bool bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nCol, 540 rRef.Ref2.nCol, nCol1, nDx )); 541 sal_Bool bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == 542 ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsColRel())); 543 sal_Bool bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat == 544 ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsColRel())); 545 if ( lcl_MoveRefPart( rRef.Ref1.nCol, bRef1ColDel, bDo1, 546 rRef.Ref2.nCol, bRef2ColDel, bDo2, 547 nCol1, nCol2, nDx, MAXCOL ) ) 548 { 549 eRet = UR_UPDATED; 550 if ( bInDeleteUndo && (bRef1ColDel || bRef2ColDel) ) 551 { 552 if ( bRef1ColDel && nCol1 <= rRef.Ref1.nCol && 553 rRef.Ref1.nCol <= nCol1 + nDx ) 554 rRef.Ref1.SetColDeleted( sal_False ); 555 if ( bRef2ColDel && nCol1 <= rRef.Ref2.nCol && 556 rRef.Ref2.nCol <= nCol1 + nDx ) 557 rRef.Ref2.SetColDeleted( sal_False ); 558 } 559 else 560 { 561 if ( bRef1ColDel ) 562 rRef.Ref1.SetColDeleted( sal_True ); 563 if ( bRef2ColDel ) 564 rRef.Ref2.SetColDeleted( sal_True ); 565 } 566 } 567 if ( bExp ) 568 { 569 Expand( rRef.Ref1.nCol, rRef.Ref2.nCol, nCol1, nDx ); 570 eRet = UR_UPDATED; 571 } 572 } 573 if( nDy && 574 ((rRef.Ref1.nCol >= nCol1 575 && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel)) 576 && 577 ((rRef.Ref1.nTab >= nTab1 578 && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel)) 579 ) 580 { 581 sal_Bool bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nRow, 582 rRef.Ref2.nRow, nRow1, nDy )); 583 sal_Bool bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == 584 ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsRowRel())); 585 sal_Bool bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat == 586 ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsRowRel())); 587 if ( lcl_MoveRefPart( rRef.Ref1.nRow, bRef1RowDel, bDo1, 588 rRef.Ref2.nRow, bRef2RowDel, bDo2, 589 nRow1, nRow2, nDy, MAXROW ) ) 590 { 591 eRet = UR_UPDATED; 592 if ( bInDeleteUndo && (bRef1RowDel || bRef2RowDel) ) 593 { 594 if ( bRef1RowDel && nRow1 <= rRef.Ref1.nRow && 595 rRef.Ref1.nRow <= nRow1 + nDy ) 596 rRef.Ref1.SetRowDeleted( sal_False ); 597 if ( bRef2RowDel && nRow1 <= rRef.Ref2.nRow && 598 rRef.Ref2.nRow <= nRow1 + nDy ) 599 rRef.Ref2.SetRowDeleted( sal_False ); 600 } 601 else 602 { 603 if ( bRef1RowDel ) 604 rRef.Ref1.SetRowDeleted( sal_True ); 605 if ( bRef2RowDel ) 606 rRef.Ref2.SetRowDeleted( sal_True ); 607 } 608 } 609 if ( bExp ) 610 { 611 Expand( rRef.Ref1.nRow, rRef.Ref2.nRow, nRow1, nDy ); 612 eRet = UR_UPDATED; 613 } 614 } 615 if( nDz && 616 ((rRef.Ref1.nCol >= nCol1 617 && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel)) 618 && 619 ((rRef.Ref1.nRow >= nRow1 620 && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel)) 621 ) 622 { 623 sal_Bool bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nTab, 624 rRef.Ref2.nTab, nTab1, nDz )); 625 SCTAB nMaxTab = pDoc->GetTableCount() - 1; 626 sal_Bool bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat == 627 ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsTabRel())); 628 sal_Bool bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat == 629 ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsTabRel())); 630 if ( lcl_MoveRefPart( rRef.Ref1.nTab, bRef1TabDel, bDo1, 631 rRef.Ref2.nTab, bRef2TabDel, bDo2, 632 nTab1, nTab2, nDz, nMaxTab ) ) 633 { 634 eRet = UR_UPDATED; 635 if ( bInDeleteUndo && (bRef1TabDel || bRef2TabDel) ) 636 { 637 if ( bRef1TabDel && nTab1 <= rRef.Ref1.nTab && 638 rRef.Ref1.nTab <= nTab1 + nDz ) 639 rRef.Ref1.SetTabDeleted( sal_False ); 640 if ( bRef2TabDel && nTab1 <= rRef.Ref2.nTab && 641 rRef.Ref2.nTab <= nTab1 + nDz ) 642 rRef.Ref2.SetTabDeleted( sal_False ); 643 } 644 else 645 { 646 if ( bRef1TabDel ) 647 rRef.Ref1.SetTabDeleted( sal_True ); 648 if ( bRef2TabDel ) 649 rRef.Ref2.SetTabDeleted( sal_True ); 650 } 651 } 652 if ( bExp ) 653 { 654 Expand( rRef.Ref1.nTab, rRef.Ref2.nTab, nTab1, nDz ); 655 eRet = UR_UPDATED; 656 } 657 } 658 if ( eRet == UR_NOTHING ) 659 { 660 if (oldCol1 != rRef.Ref1.nCol 661 || oldRow1 != rRef.Ref1.nRow 662 || oldTab1 != rRef.Ref1.nTab 663 || oldCol2 != rRef.Ref2.nCol 664 || oldRow2 != rRef.Ref2.nRow 665 || oldTab2 != rRef.Ref2.nTab 666 ) 667 eRet = UR_UPDATED; 668 } 669 if (eWhat != ScRefUpdate::ABSOLUTE) 670 rRef.CalcRelFromAbs( rPos ); 671 } 672 else 673 { 674 if( eMode == URM_MOVE ) 675 { 676 if ( rRef.Ref1.nCol >= nCol1-nDx 677 && rRef.Ref1.nRow >= nRow1-nDy 678 && rRef.Ref1.nTab >= nTab1-nDz 679 && rRef.Ref2.nCol <= nCol2-nDx 680 && rRef.Ref2.nRow <= nRow2-nDy 681 && rRef.Ref2.nTab <= nTab2-nDz ) 682 { 683 eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, sal_False, sal_True ); // immer verschieben 684 } 685 else if ( nDz && r.In( rPos ) ) 686 { 687 rRef.Ref1.SetFlag3D( sal_True ); 688 rRef.Ref2.SetFlag3D( sal_True ); 689 eRet = UR_UPDATED; 690 if (eWhat != ScRefUpdate::ABSOLUTE) 691 rRef.CalcRelFromAbs( rPos ); 692 } 693 else if (eWhat != ScRefUpdate::ABSOLUTE) 694 rRef.CalcRelFromAbs( rPos ); 695 } 696 else if( eMode == URM_COPY && r.In( rPos ) ) 697 eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, sal_False, sal_False ); // nur relative 698 // sollte nicht mehr verwendet werden muessen 699 else if (eWhat != ScRefUpdate::ABSOLUTE) 700 rRef.CalcRelFromAbs( rPos ); 701 } 702 return eRet; 703 } 704 705 706 ScRefUpdateRes ScRefUpdate::Move( ScDocument* pDoc, const ScAddress& rPos, 707 SCsCOL nDx, SCsROW nDy, SCsTAB nDz, 708 ScComplexRefData& rRef, sal_Bool bWrap, sal_Bool bAbsolute ) 709 { 710 ScRefUpdateRes eRet = UR_NOTHING; 711 712 SCCOL oldCol1 = rRef.Ref1.nCol; 713 SCROW oldRow1 = rRef.Ref1.nRow; 714 SCTAB oldTab1 = rRef.Ref1.nTab; 715 SCCOL oldCol2 = rRef.Ref2.nCol; 716 SCROW oldRow2 = rRef.Ref2.nRow; 717 SCTAB oldTab2 = rRef.Ref2.nTab; 718 719 sal_Bool bCut1, bCut2; 720 if ( nDx ) 721 { 722 bCut1 = bCut2 = sal_False; 723 if( bAbsolute || rRef.Ref1.IsColRel() ) 724 { 725 if( bWrap ) 726 lcl_MoveItWrap( rRef.Ref1.nCol, nDx, MAXCOL ); 727 else 728 bCut1 = lcl_MoveItCut( rRef.Ref1.nCol, nDx, MAXCOL ); 729 } 730 if( bAbsolute || rRef.Ref2.IsColRel() ) 731 { 732 if( bWrap ) 733 lcl_MoveItWrap( rRef.Ref2.nCol, nDx, MAXCOL ); 734 else 735 bCut2 = lcl_MoveItCut( rRef.Ref2.nCol, nDx, MAXCOL ); 736 } 737 if ( bCut1 || bCut2 ) 738 eRet = UR_UPDATED; 739 if ( bCut1 && bCut2 ) 740 { 741 rRef.Ref1.SetColDeleted( sal_True ); 742 rRef.Ref2.SetColDeleted( sal_True ); 743 } 744 } 745 if ( nDy ) 746 { 747 bCut1 = bCut2 = sal_False; 748 if( bAbsolute || rRef.Ref1.IsRowRel() ) 749 { 750 if( bWrap ) 751 lcl_MoveItWrap( rRef.Ref1.nRow, nDy, MAXROW ); 752 else 753 bCut1 = lcl_MoveItCut( rRef.Ref1.nRow, nDy, MAXROW ); 754 } 755 if( bAbsolute || rRef.Ref2.IsRowRel() ) 756 { 757 if( bWrap ) 758 lcl_MoveItWrap( rRef.Ref2.nRow, nDy, MAXROW ); 759 else 760 bCut2 = lcl_MoveItCut( rRef.Ref2.nRow, nDy, MAXROW ); 761 } 762 if ( bCut1 || bCut2 ) 763 eRet = UR_UPDATED; 764 if ( bCut1 && bCut2 ) 765 { 766 rRef.Ref1.SetRowDeleted( sal_True ); 767 rRef.Ref2.SetRowDeleted( sal_True ); 768 } 769 } 770 if ( nDz ) 771 { 772 bCut1 = bCut2 = sal_False; 773 SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1; 774 if( bAbsolute || rRef.Ref1.IsTabRel() ) 775 { 776 if( bWrap ) 777 lcl_MoveItWrap( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); 778 else 779 bCut1 = lcl_MoveItCut( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); 780 rRef.Ref1.SetFlag3D( rPos.Tab() != rRef.Ref1.nTab ); 781 } 782 if( bAbsolute || rRef.Ref2.IsTabRel() ) 783 { 784 if( bWrap ) 785 lcl_MoveItWrap( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); 786 else 787 bCut2 = lcl_MoveItCut( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) ); 788 rRef.Ref2.SetFlag3D( rPos.Tab() != rRef.Ref2.nTab ); 789 } 790 if ( bCut1 || bCut2 ) 791 eRet = UR_UPDATED; 792 if ( bCut1 && bCut2 ) 793 { 794 rRef.Ref1.SetTabDeleted( sal_True ); 795 rRef.Ref2.SetTabDeleted( sal_True ); 796 } 797 } 798 799 if ( eRet == UR_NOTHING ) 800 { 801 if (oldCol1 != rRef.Ref1.nCol 802 || oldRow1 != rRef.Ref1.nRow 803 || oldTab1 != rRef.Ref1.nTab 804 || oldCol2 != rRef.Ref2.nCol 805 || oldRow2 != rRef.Ref2.nRow 806 || oldTab2 != rRef.Ref2.nTab 807 ) 808 eRet = UR_UPDATED; 809 } 810 if ( bWrap && eRet != UR_NOTHING ) 811 rRef.PutInOrder(); 812 rRef.CalcRelFromAbs( rPos ); 813 return eRet; 814 } 815 816 void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos, 817 SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef ) 818 { 819 if( rRef.Ref1.IsColRel() ) 820 { 821 rRef.Ref1.nCol = rRef.Ref1.nRelCol + rPos.Col(); 822 lcl_MoveItWrap( rRef.Ref1.nCol, static_cast<SCsCOL>(0), nMaxCol ); 823 } 824 if( rRef.Ref2.IsColRel() ) 825 { 826 rRef.Ref2.nCol = rRef.Ref2.nRelCol + rPos.Col(); 827 lcl_MoveItWrap( rRef.Ref2.nCol, static_cast<SCsCOL>(0), nMaxCol ); 828 } 829 if( rRef.Ref1.IsRowRel() ) 830 { 831 rRef.Ref1.nRow = rRef.Ref1.nRelRow + rPos.Row(); 832 lcl_MoveItWrap( rRef.Ref1.nRow, static_cast<SCsROW>(0), nMaxRow ); 833 } 834 if( rRef.Ref2.IsRowRel() ) 835 { 836 rRef.Ref2.nRow = rRef.Ref2.nRelRow + rPos.Row(); 837 lcl_MoveItWrap( rRef.Ref2.nRow, static_cast<SCsROW>(0), nMaxRow ); 838 } 839 SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1; 840 if( rRef.Ref1.IsTabRel() ) 841 { 842 rRef.Ref1.nTab = rRef.Ref1.nRelTab + rPos.Tab(); 843 lcl_MoveItWrap( rRef.Ref1.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) ); 844 } 845 if( rRef.Ref2.IsTabRel() ) 846 { 847 rRef.Ref2.nTab = rRef.Ref2.nRelTab + rPos.Tab(); 848 lcl_MoveItWrap( rRef.Ref2.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) ); 849 } 850 rRef.PutInOrder(); 851 rRef.CalcRelFromAbs( rPos ); 852 } 853 854 //------------------------------------------------------------------ 855 856 void ScRefUpdate::DoTranspose( SCsCOL& rCol, SCsROW& rRow, SCsTAB& rTab, 857 ScDocument* pDoc, const ScRange& rSource, const ScAddress& rDest ) 858 { 859 SCsTAB nDz = ((SCsTAB)rDest.Tab())-(SCsTAB)rSource.aStart.Tab(); 860 if (nDz) 861 { 862 SCsTAB nNewTab = rTab+nDz; 863 SCsTAB nCount = pDoc->GetTableCount(); 864 while (nNewTab<0) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab + nCount ); 865 while (nNewTab>=nCount) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab - nCount ); 866 rTab = nNewTab; 867 } 868 DBG_ASSERT( rCol>=rSource.aStart.Col() && rRow>=rSource.aStart.Row(), 869 "UpdateTranspose: Pos. falsch" ); 870 871 SCsCOL nRelX = rCol - (SCsCOL)rSource.aStart.Col(); 872 SCsROW nRelY = rRow - (SCsROW)rSource.aStart.Row(); 873 874 rCol = static_cast<SCsCOL>(static_cast<SCsCOLROW>(rDest.Col()) + 875 static_cast<SCsCOLROW>(nRelY)); 876 rRow = static_cast<SCsROW>(static_cast<SCsCOLROW>(rDest.Row()) + 877 static_cast<SCsCOLROW>(nRelX)); 878 } 879 880 881 ScRefUpdateRes ScRefUpdate::UpdateTranspose( ScDocument* pDoc, 882 const ScRange& rSource, const ScAddress& rDest, 883 ScComplexRefData& rRef ) 884 { 885 ScRefUpdateRes eRet = UR_NOTHING; 886 if ( rRef.Ref1.nCol >= rSource.aStart.Col() && rRef.Ref2.nCol <= rSource.aEnd.Col() && 887 rRef.Ref1.nRow >= rSource.aStart.Row() && rRef.Ref2.nRow <= rSource.aEnd.Row() && 888 rRef.Ref1.nTab >= rSource.aStart.Tab() && rRef.Ref2.nTab <= rSource.aEnd.Tab() ) 889 { 890 DoTranspose( rRef.Ref1.nCol, rRef.Ref1.nRow, rRef.Ref1.nTab, pDoc, rSource, rDest ); 891 DoTranspose( rRef.Ref2.nCol, rRef.Ref2.nRow, rRef.Ref2.nTab, pDoc, rSource, rDest ); 892 eRet = UR_UPDATED; 893 } 894 return eRet; 895 } 896 897 //------------------------------------------------------------------ 898 899 // UpdateGrow - erweitert Referenzen, die genau auf den Bereich zeigen 900 // kommt ohne Dokument aus 901 902 903 ScRefUpdateRes ScRefUpdate::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY, 904 ScComplexRefData& rRef ) 905 { 906 ScRefUpdateRes eRet = UR_NOTHING; 907 908 // in Y-Richtung darf die Ref auch eine Zeile weiter unten anfangen, 909 // falls ein Bereich Spaltenkoepfe enthaelt 910 911 sal_Bool bUpdateX = ( nGrowX && 912 rRef.Ref1.nCol == rArea.aStart.Col() && rRef.Ref2.nCol == rArea.aEnd.Col() && 913 rRef.Ref1.nRow >= rArea.aStart.Row() && rRef.Ref2.nRow <= rArea.aEnd.Row() && 914 rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() ); 915 sal_Bool bUpdateY = ( nGrowY && 916 rRef.Ref1.nCol >= rArea.aStart.Col() && rRef.Ref2.nCol <= rArea.aEnd.Col() && 917 ( rRef.Ref1.nRow == rArea.aStart.Row() || rRef.Ref1.nRow == rArea.aStart.Row()+1 ) && 918 rRef.Ref2.nRow == rArea.aEnd.Row() && 919 rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() ); 920 921 if ( bUpdateX ) 922 { 923 rRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( rRef.Ref2.nCol + nGrowX ); 924 eRet = UR_UPDATED; 925 } 926 if ( bUpdateY ) 927 { 928 rRef.Ref2.nRow = sal::static_int_cast<SCsROW>( rRef.Ref2.nRow + nGrowY ); 929 eRet = UR_UPDATED; 930 } 931 932 return eRet; 933 } 934 935 936