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