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 >
lcl_MoveStart(R & rRef,U nStart,S nDelta,U nMask)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 >
lcl_MoveEnd(R & rRef,U nStart,S nDelta,U nMask)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 >
lcl_MoveReorder(R & rRef,U nStart,U nEnd,S nDelta)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 >
lcl_MoveItCut(R & rRef,S nDelta,U nMask)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 >
lcl_MoveItWrap(R & rRef,S nDelta,U nMask)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 >
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)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 >
IsExpand(R n1,R n2,U nStart,S nD)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 >
Expand(R & n1,R & n2,U nStart,S nD)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
lcl_IsWrapBig(sal_Int32 nRef,sal_Int32 nDelta)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
lcl_MoveBig(sal_Int32 & rRef,sal_Int32 nStart,sal_Int32 nDelta)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
lcl_MoveItCutBig(sal_Int32 & rRef,sal_Int32 nDelta)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
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)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!
Update(UpdateRefMode eUpdateRefMode,const ScBigRange & rWhere,sal_Int32 nDx,sal_Int32 nDy,sal_Int32 nDz,ScBigRange & rWhat)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
Update(ScDocument * pDoc,UpdateRefMode eMode,const ScAddress & rPos,const ScRange & r,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,ScComplexRefData & rRef,WhatType eWhat)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
Move(ScDocument * pDoc,const ScAddress & rPos,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,ScComplexRefData & rRef,sal_Bool bWrap,sal_Bool bAbsolute)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
MoveRelWrap(ScDocument * pDoc,const ScAddress & rPos,SCCOL nMaxCol,SCROW nMaxRow,ScComplexRefData & rRef)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
DoTranspose(SCsCOL & rCol,SCsROW & rRow,SCsTAB & rTab,ScDocument * pDoc,const ScRange & rSource,const ScAddress & rDest)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
UpdateTranspose(ScDocument * pDoc,const ScRange & rSource,const ScAddress & rDest,ScComplexRefData & rRef)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
UpdateGrow(const ScRange & rArea,SCCOL nGrowX,SCROW nGrowY,ScComplexRefData & rRef)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