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 : template< typename R, typename S, typename U >
27 0 : static bool lcl_MoveStart( R& rRef, U nStart, S nDelta, U nMask )
28 : {
29 0 : bool bCut = false;
30 0 : if ( rRef >= nStart )
31 0 : rRef = sal::static_int_cast<R>( rRef + nDelta );
32 0 : else if ( nDelta < 0 && rRef >= nStart + nDelta )
33 0 : rRef = nStart + nDelta; //! begrenzen ???
34 0 : if ( rRef < 0 )
35 : {
36 0 : rRef = 0;
37 0 : bCut = true;
38 : }
39 0 : else if ( rRef > nMask )
40 : {
41 0 : rRef = nMask;
42 0 : bCut = true;
43 : }
44 0 : return bCut;
45 : }
46 :
47 : template< typename R, typename S, typename U >
48 0 : static bool lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask )
49 : {
50 0 : bool bCut = false;
51 0 : if ( rRef >= nStart )
52 0 : rRef = sal::static_int_cast<R>( rRef + nDelta );
53 0 : else if ( nDelta < 0 && rRef >= nStart + nDelta )
54 0 : rRef = nStart + nDelta - 1; //! begrenzen ???
55 0 : if ( rRef < 0 )
56 : {
57 0 : rRef = 0;
58 0 : bCut = true;
59 : }
60 0 : else if ( rRef > nMask )
61 : {
62 0 : rRef = nMask;
63 0 : bCut = true;
64 : }
65 0 : return bCut;
66 : }
67 :
68 : template< typename R, typename S, typename U >
69 0 : static bool lcl_MoveReorder( R& rRef, U nStart, U nEnd, S nDelta )
70 : {
71 0 : if ( rRef >= nStart && rRef <= nEnd )
72 : {
73 0 : rRef = sal::static_int_cast<R>( rRef + nDelta );
74 0 : return true;
75 : }
76 :
77 0 : if ( nDelta > 0 ) // nach hinten schieben
78 : {
79 0 : if ( rRef >= nStart && rRef <= nEnd + nDelta )
80 : {
81 0 : if ( rRef <= nEnd )
82 0 : rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range
83 : else
84 0 : rRef -= nEnd - nStart + 1; // nachruecken
85 0 : return true;
86 : }
87 : }
88 : else // nach vorne schieben
89 : {
90 0 : if ( rRef >= nStart + nDelta && rRef <= nEnd )
91 : {
92 0 : if ( rRef >= nStart )
93 0 : rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range
94 : else
95 0 : rRef += nEnd - nStart + 1; // nachruecken
96 0 : return true;
97 : }
98 : }
99 :
100 0 : return false;
101 : }
102 :
103 : template< typename R, typename S, typename U >
104 0 : static bool lcl_MoveItCut( R& rRef, S nDelta, U nMask )
105 : {
106 0 : bool bCut = false;
107 0 : rRef = sal::static_int_cast<R>( rRef + nDelta );
108 0 : if ( rRef < 0 )
109 : {
110 0 : rRef = 0;
111 0 : bCut = true;
112 : }
113 0 : else if ( rRef > nMask )
114 : {
115 0 : rRef = nMask;
116 0 : bCut = true;
117 : }
118 0 : return bCut;
119 : }
120 :
121 : template< typename R, typename S, typename U >
122 0 : static void lcl_MoveItWrap( R& rRef, S nDelta, U nMask )
123 : {
124 0 : rRef = sal::static_int_cast<R>( rRef + nDelta );
125 0 : if ( rRef < 0 )
126 0 : rRef += nMask+1;
127 0 : else if ( rRef > nMask )
128 0 : rRef -= nMask+1;
129 0 : }
130 :
131 : template< typename R, typename S, typename U >
132 : static bool lcl_MoveRefPart( R& rRef1Val, bool& rRef1Del, bool bDo1,
133 : R& rRef2Val, bool& rRef2Del, bool bDo2,
134 : U nStart, U nEnd, S nDelta, U nMask )
135 : {
136 : if ( nDelta )
137 : {
138 : bool bDel, bCut1, bCut2;
139 : bDel = bCut1 = bCut2 = false;
140 : S n;
141 : if (bDo1 && bDo2)
142 : {
143 : if ( nDelta < 0 )
144 : {
145 : n = nStart + nDelta;
146 : if ( n <= rRef1Val && rRef1Val < nStart
147 : && n <= rRef2Val && rRef2Val < nStart )
148 : bDel = true;
149 : }
150 : else
151 : {
152 : n = nEnd + nDelta;
153 : if ( nEnd < rRef1Val && rRef1Val <= n
154 : && nEnd < rRef2Val && rRef2Val <= n )
155 : bDel = true;
156 : }
157 : }
158 : if ( bDel )
159 : { // move deleted along
160 : rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta );
161 : rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta );
162 : }
163 : else
164 : {
165 : if (bDo1)
166 : {
167 : if ( rRef1Del )
168 : rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta );
169 : else
170 : bCut1 = lcl_MoveStart( rRef1Val, nStart, nDelta, nMask );
171 : }
172 : if (bDo2)
173 : {
174 : if ( rRef2Del )
175 : rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta );
176 : else
177 : bCut2 = lcl_MoveEnd( rRef2Val, nStart, nDelta, nMask );
178 : }
179 : }
180 : if ( bDel || (bCut1 && bCut2) )
181 : rRef1Del = rRef2Del = true;
182 : return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del;
183 : }
184 : else
185 : return false;
186 : }
187 :
188 : template< typename R, typename S, typename U >
189 0 : bool IsExpand( R n1, R n2, U nStart, S nD )
190 : { //! vor normalem Move...
191 : return
192 : nD > 0 // Insert
193 : && n1 < n2 // mindestens zwei Cols/Rows/Tabs in Ref
194 : && (
195 : (nStart <= n1 && n1 < nStart + nD) // n1 innerhalb des Insert
196 : || (n2 + 1 == nStart) // n2 direkt vor Insert
197 0 : ); // n1 < nStart <= n2 wird sowieso expanded!
198 : }
199 :
200 : template< typename R, typename S, typename U >
201 0 : void Expand( R& n1, R& n2, U nStart, S nD )
202 : { //! nach normalem Move..., nur wenn IsExpand vorher true war!
203 : //! erst das Ende
204 0 : if ( n2 + 1 == nStart )
205 : { // am Ende
206 0 : n2 = sal::static_int_cast<R>( n2 + nD );
207 0 : return;
208 : }
209 : // am Anfang
210 0 : n1 = sal::static_int_cast<R>( n1 - nD );
211 : }
212 :
213 0 : static bool lcl_IsWrapBig( sal_Int32 nRef, sal_Int32 nDelta )
214 : {
215 0 : if ( nRef > 0 && nDelta > 0 )
216 0 : return nRef + nDelta <= 0;
217 0 : else if ( nRef < 0 && nDelta < 0 )
218 0 : return nRef + nDelta >= 0;
219 0 : return false;
220 : }
221 :
222 0 : static bool lcl_MoveBig( sal_Int32& rRef, sal_Int32 nStart, sal_Int32 nDelta )
223 : {
224 0 : bool bCut = false;
225 0 : if ( rRef >= nStart )
226 : {
227 0 : if ( nDelta > 0 )
228 0 : bCut = lcl_IsWrapBig( rRef, nDelta );
229 0 : if ( bCut )
230 0 : rRef = nInt32Max;
231 : else
232 0 : rRef += nDelta;
233 : }
234 0 : return bCut;
235 : }
236 :
237 0 : static bool lcl_MoveItCutBig( sal_Int32& rRef, sal_Int32 nDelta )
238 : {
239 0 : bool bCut = lcl_IsWrapBig( rRef, nDelta );
240 0 : rRef += nDelta;
241 0 : return bCut;
242 : }
243 :
244 0 : ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
245 : SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
246 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
247 : SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
248 : SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1,
249 : SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 )
250 : {
251 0 : ScRefUpdateRes eRet = UR_NOTHING;
252 :
253 0 : SCCOL oldCol1 = theCol1;
254 0 : SCROW oldRow1 = theRow1;
255 0 : SCTAB oldTab1 = theTab1;
256 0 : SCCOL oldCol2 = theCol2;
257 0 : SCROW oldRow2 = theRow2;
258 0 : SCTAB oldTab2 = theTab2;
259 :
260 : bool bCut1, bCut2;
261 :
262 0 : if (eUpdateRefMode == URM_INSDEL)
263 : {
264 0 : bool bExpand = pDoc->IsExpandRefs();
265 0 : if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
266 0 : (theTab1 >= nTab1) && (theTab2 <= nTab2) )
267 : {
268 0 : bool bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx ));
269 0 : bCut1 = lcl_MoveStart( theCol1, nCol1, nDx, MAXCOL );
270 0 : bCut2 = lcl_MoveEnd( theCol2, nCol1, nDx, MAXCOL );
271 0 : if ( theCol2 < theCol1 )
272 : {
273 0 : eRet = UR_INVALID;
274 0 : theCol2 = theCol1;
275 : }
276 0 : else if ( bCut1 || bCut2 )
277 0 : eRet = UR_UPDATED;
278 0 : if ( bExp )
279 : {
280 0 : Expand( theCol1, theCol2, nCol1, nDx );
281 0 : eRet = UR_UPDATED;
282 : }
283 : }
284 0 : if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
285 0 : (theTab1 >= nTab1) && (theTab2 <= nTab2) )
286 : {
287 0 : bool bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy ));
288 0 : bCut1 = lcl_MoveStart( theRow1, nRow1, nDy, MAXROW );
289 0 : bCut2 = lcl_MoveEnd( theRow2, nRow1, nDy, MAXROW );
290 0 : if ( theRow2 < theRow1 )
291 : {
292 0 : eRet = UR_INVALID;
293 0 : theRow2 = theRow1;
294 : }
295 0 : else if ( bCut1 || bCut2 )
296 0 : eRet = UR_UPDATED;
297 0 : if ( bExp )
298 : {
299 0 : Expand( theRow1, theRow2, nRow1, nDy );
300 0 : eRet = UR_UPDATED;
301 : }
302 : }
303 0 : if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
304 0 : (theRow1 >= nRow1) && (theRow2 <= nRow2) )
305 : {
306 0 : SCsTAB nMaxTab = pDoc->GetTableCount() - 1;
307 0 : nMaxTab = sal::static_int_cast<SCsTAB>(nMaxTab + nDz); // adjust to new count
308 0 : bool bExp = (bExpand && IsExpand( theTab1, theTab2, nTab1, nDz ));
309 0 : bCut1 = lcl_MoveStart( theTab1, nTab1, nDz, static_cast<SCTAB>(nMaxTab) );
310 0 : bCut2 = lcl_MoveEnd( theTab2, nTab1, nDz, static_cast<SCTAB>(nMaxTab) );
311 0 : if ( theTab2 < theTab1 )
312 : {
313 0 : eRet = UR_INVALID;
314 0 : theTab2 = theTab1;
315 : }
316 0 : else if ( bCut1 || bCut2 )
317 0 : eRet = UR_UPDATED;
318 0 : if ( bExp )
319 : {
320 0 : Expand( theTab1, theTab2, nTab1, nDz );
321 0 : eRet = UR_UPDATED;
322 : }
323 : }
324 : }
325 0 : else if (eUpdateRefMode == URM_MOVE)
326 : {
327 0 : if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) &&
328 0 : (theCol2 <= nCol2-nDx) && (theRow2 <= nRow2-nDy) && (theTab2 <= nTab2-nDz))
329 : {
330 0 : if ( nDx )
331 : {
332 0 : bCut1 = lcl_MoveItCut( theCol1, nDx, MAXCOL );
333 0 : bCut2 = lcl_MoveItCut( theCol2, nDx, MAXCOL );
334 0 : if ( bCut1 || bCut2 )
335 0 : eRet = UR_UPDATED;
336 : }
337 0 : if ( nDy )
338 : {
339 0 : bCut1 = lcl_MoveItCut( theRow1, nDy, MAXROW );
340 0 : bCut2 = lcl_MoveItCut( theRow2, nDy, MAXROW );
341 0 : if ( bCut1 || bCut2 )
342 0 : eRet = UR_UPDATED;
343 : }
344 0 : if ( nDz )
345 : {
346 0 : SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
347 0 : bCut1 = lcl_MoveItCut( theTab1, nDz, static_cast<SCTAB>(nMaxTab) );
348 0 : bCut2 = lcl_MoveItCut( theTab2, nDz, static_cast<SCTAB>(nMaxTab) );
349 0 : if ( bCut1 || bCut2 )
350 0 : eRet = UR_UPDATED;
351 : }
352 : }
353 : }
354 0 : else if (eUpdateRefMode == URM_REORDER)
355 : {
356 : // bisher nur fuer nDz (MoveTab)
357 : OSL_ENSURE ( !nDx && !nDy, "URM_REORDER for x and y not yet implemented" );
358 :
359 0 : if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
360 0 : (theRow1 >= nRow1) && (theRow2 <= nRow2) )
361 : {
362 0 : bCut1 = lcl_MoveReorder( theTab1, nTab1, nTab2, nDz );
363 0 : bCut2 = lcl_MoveReorder( theTab2, nTab1, nTab2, nDz );
364 0 : if ( bCut1 || bCut2 )
365 0 : eRet = UR_UPDATED;
366 : }
367 : }
368 :
369 0 : if ( eRet == UR_NOTHING )
370 : {
371 0 : if (oldCol1 != theCol1
372 0 : || oldRow1 != theRow1
373 0 : || oldTab1 != theTab1
374 0 : || oldCol2 != theCol2
375 0 : || oldRow2 != theRow2
376 0 : || oldTab2 != theTab2
377 : )
378 0 : eRet = UR_UPDATED;
379 : }
380 0 : return eRet;
381 : }
382 :
383 : // simples UpdateReference fuer ScBigRange (ScChangeAction/ScChangeTrack)
384 : // Referenzen koennen auch ausserhalb des Dokuments liegen!
385 : // Ganze Spalten/Zeilen (nInt32Min..nInt32Max) bleiben immer solche!
386 0 : ScRefUpdateRes ScRefUpdate::Update( UpdateRefMode eUpdateRefMode,
387 : const ScBigRange& rWhere, sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz,
388 : ScBigRange& rWhat )
389 : {
390 0 : ScRefUpdateRes eRet = UR_NOTHING;
391 0 : const ScBigRange aOldRange( rWhat );
392 :
393 : sal_Int32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2;
394 : sal_Int32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2;
395 0 : rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
396 0 : rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
397 :
398 : bool bCut1, bCut2;
399 :
400 0 : if (eUpdateRefMode == URM_INSDEL)
401 : {
402 0 : if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
403 0 : (theTab1 >= nTab1) && (theTab2 <= nTab2) &&
404 0 : !(theCol1 == nInt32Min && theCol2 == nInt32Max) )
405 : {
406 0 : bCut1 = lcl_MoveBig( theCol1, nCol1, nDx );
407 0 : bCut2 = lcl_MoveBig( theCol2, nCol1, nDx );
408 0 : if ( bCut1 || bCut2 )
409 0 : eRet = UR_UPDATED;
410 0 : rWhat.aStart.SetCol( theCol1 );
411 0 : rWhat.aEnd.SetCol( theCol2 );
412 : }
413 0 : if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
414 0 : (theTab1 >= nTab1) && (theTab2 <= nTab2) &&
415 0 : !(theRow1 == nInt32Min && theRow2 == nInt32Max) )
416 : {
417 0 : bCut1 = lcl_MoveBig( theRow1, nRow1, nDy );
418 0 : bCut2 = lcl_MoveBig( theRow2, nRow1, nDy );
419 0 : if ( bCut1 || bCut2 )
420 0 : eRet = UR_UPDATED;
421 0 : rWhat.aStart.SetRow( theRow1 );
422 0 : rWhat.aEnd.SetRow( theRow2 );
423 : }
424 0 : if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
425 0 : (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
426 0 : !(theTab1 == nInt32Min && theTab2 == nInt32Max) )
427 : {
428 0 : bCut1 = lcl_MoveBig( theTab1, nTab1, nDz );
429 0 : bCut2 = lcl_MoveBig( theTab2, nTab1, nDz );
430 0 : if ( bCut1 || bCut2 )
431 0 : eRet = UR_UPDATED;
432 0 : rWhat.aStart.SetTab( theTab1 );
433 0 : rWhat.aEnd.SetTab( theTab2 );
434 : }
435 : }
436 0 : else if (eUpdateRefMode == URM_MOVE)
437 : {
438 0 : if ( rWhere.In( rWhat ) )
439 : {
440 0 : if ( nDx && !(theCol1 == nInt32Min && theCol2 == nInt32Max) )
441 : {
442 0 : bCut1 = lcl_MoveItCutBig( theCol1, nDx );
443 0 : bCut2 = lcl_MoveItCutBig( theCol2, nDx );
444 0 : if ( bCut1 || bCut2 )
445 0 : eRet = UR_UPDATED;
446 0 : rWhat.aStart.SetCol( theCol1 );
447 0 : rWhat.aEnd.SetCol( theCol2 );
448 : }
449 0 : if ( nDy && !(theRow1 == nInt32Min && theRow2 == nInt32Max) )
450 : {
451 0 : bCut1 = lcl_MoveItCutBig( theRow1, nDy );
452 0 : bCut2 = lcl_MoveItCutBig( theRow2, nDy );
453 0 : if ( bCut1 || bCut2 )
454 0 : eRet = UR_UPDATED;
455 0 : rWhat.aStart.SetRow( theRow1 );
456 0 : rWhat.aEnd.SetRow( theRow2 );
457 : }
458 0 : if ( nDz && !(theTab1 == nInt32Min && theTab2 == nInt32Max) )
459 : {
460 0 : bCut1 = lcl_MoveItCutBig( theTab1, nDz );
461 0 : bCut2 = lcl_MoveItCutBig( theTab2, nDz );
462 0 : if ( bCut1 || bCut2 )
463 0 : eRet = UR_UPDATED;
464 0 : rWhat.aStart.SetTab( theTab1 );
465 0 : rWhat.aEnd.SetTab( theTab2 );
466 : }
467 : }
468 : }
469 :
470 0 : if ( eRet == UR_NOTHING && rWhat != aOldRange )
471 0 : eRet = UR_UPDATED;
472 :
473 0 : return eRet;
474 : }
475 :
476 0 : void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos,
477 : SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef )
478 : {
479 0 : ScRange aAbsRange = rRef.toAbs(rPos);
480 0 : if( rRef.Ref1.IsColRel() )
481 : {
482 0 : SCCOL nCol = aAbsRange.aStart.Col();
483 0 : lcl_MoveItWrap(nCol, static_cast<SCsCOL>(0), nMaxCol);
484 0 : aAbsRange.aStart.SetCol(nCol);
485 : }
486 0 : if( rRef.Ref2.IsColRel() )
487 : {
488 0 : SCCOL nCol = aAbsRange.aEnd.Col();
489 0 : lcl_MoveItWrap(nCol, static_cast<SCsCOL>(0), nMaxCol);
490 0 : aAbsRange.aEnd.SetCol(nCol);
491 : }
492 0 : if( rRef.Ref1.IsRowRel() )
493 : {
494 0 : SCROW nRow = aAbsRange.aStart.Row();
495 0 : lcl_MoveItWrap(nRow, static_cast<SCsROW>(0), nMaxRow);
496 0 : aAbsRange.aStart.SetRow(nRow);
497 : }
498 0 : if( rRef.Ref2.IsRowRel() )
499 : {
500 0 : SCROW nRow = aAbsRange.aEnd.Row();
501 0 : lcl_MoveItWrap(nRow, static_cast<SCsROW>(0), nMaxRow);
502 0 : aAbsRange.aEnd.SetRow(nRow);
503 : }
504 0 : SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
505 0 : if( rRef.Ref1.IsTabRel() )
506 : {
507 0 : SCTAB nTab = aAbsRange.aStart.Tab();
508 0 : lcl_MoveItWrap(nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab));
509 0 : aAbsRange.aStart.SetTab(nTab);
510 : }
511 0 : if( rRef.Ref2.IsTabRel() )
512 : {
513 0 : SCTAB nTab = aAbsRange.aEnd.Tab();
514 0 : lcl_MoveItWrap(nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab));
515 0 : aAbsRange.aEnd.SetTab(nTab);
516 : }
517 :
518 0 : aAbsRange.PutInOrder();
519 0 : rRef.SetRange(aAbsRange, rPos);
520 0 : }
521 :
522 0 : void ScRefUpdate::DoTranspose( SCsCOL& rCol, SCsROW& rRow, SCsTAB& rTab,
523 : ScDocument* pDoc, const ScRange& rSource, const ScAddress& rDest )
524 : {
525 0 : SCsTAB nDz = ((SCsTAB)rDest.Tab())-(SCsTAB)rSource.aStart.Tab();
526 0 : if (nDz)
527 : {
528 0 : SCsTAB nNewTab = rTab+nDz;
529 0 : SCsTAB nCount = pDoc->GetTableCount();
530 0 : while (nNewTab<0) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab + nCount );
531 0 : while (nNewTab>=nCount) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab - nCount );
532 0 : rTab = nNewTab;
533 : }
534 : OSL_ENSURE( rCol>=rSource.aStart.Col() && rRow>=rSource.aStart.Row(),
535 : "UpdateTranspose: Pos. falsch" );
536 :
537 0 : SCsCOL nRelX = rCol - (SCsCOL)rSource.aStart.Col();
538 0 : SCsROW nRelY = rRow - (SCsROW)rSource.aStart.Row();
539 :
540 0 : rCol = static_cast<SCsCOL>(static_cast<SCsCOLROW>(rDest.Col()) +
541 0 : static_cast<SCsCOLROW>(nRelY));
542 0 : rRow = static_cast<SCsROW>(static_cast<SCsCOLROW>(rDest.Row()) +
543 0 : static_cast<SCsCOLROW>(nRelX));
544 0 : }
545 :
546 0 : ScRefUpdateRes ScRefUpdate::UpdateTranspose(
547 : ScDocument* pDoc, const ScRange& rSource, const ScAddress& rDest, ScRange& rRef )
548 : {
549 0 : ScRefUpdateRes eRet = UR_NOTHING;
550 0 : if (rRef.aStart.Col() >= rSource.aStart.Col() && rRef.aEnd.Col() <= rSource.aEnd.Col() &&
551 0 : rRef.aStart.Row() >= rSource.aStart.Row() && rRef.aEnd.Row() <= rSource.aEnd.Row() &&
552 0 : rRef.aStart.Tab() >= rSource.aStart.Tab() && rRef.aEnd.Tab() <= rSource.aEnd.Tab())
553 : {
554 : // Source range contains the reference range.
555 0 : SCCOL nCol1 = rRef.aStart.Col(), nCol2 = rRef.aEnd.Col();
556 0 : SCROW nRow1 = rRef.aStart.Row(), nRow2 = rRef.aEnd.Row();
557 0 : SCTAB nTab1 = rRef.aStart.Tab(), nTab2 = rRef.aEnd.Tab();
558 0 : DoTranspose(nCol1, nRow1, nTab1, pDoc, rSource, rDest);
559 0 : DoTranspose(nCol2, nRow2, nTab2, pDoc, rSource, rDest);
560 0 : rRef.aStart = ScAddress(nCol1, nRow1, nTab1);
561 0 : rRef.aEnd = ScAddress(nCol2, nRow2, nTab2);
562 0 : eRet = UR_UPDATED;
563 : }
564 0 : return eRet;
565 : }
566 :
567 : // UpdateGrow - erweitert Referenzen, die genau auf den Bereich zeigen
568 : // kommt ohne Dokument aus
569 :
570 0 : ScRefUpdateRes ScRefUpdate::UpdateGrow(
571 : const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY, ScRange& rRef )
572 : {
573 0 : ScRefUpdateRes eRet = UR_NOTHING;
574 :
575 : // in Y-Richtung darf die Ref auch eine Zeile weiter unten anfangen,
576 : // falls ein Bereich Spaltenkoepfe enthaelt
577 :
578 0 : bool bUpdateX = ( nGrowX &&
579 0 : rRef.aStart.Col() == rArea.aStart.Col() && rRef.aEnd.Col() == rArea.aEnd.Col() &&
580 0 : rRef.aStart.Row() >= rArea.aStart.Row() && rRef.aEnd.Row() <= rArea.aEnd.Row() &&
581 0 : rRef.aStart.Tab() >= rArea.aStart.Tab() && rRef.aEnd.Tab() <= rArea.aEnd.Tab() );
582 0 : bool bUpdateY = ( nGrowY &&
583 0 : rRef.aStart.Col() >= rArea.aStart.Col() && rRef.aEnd.Col() <= rArea.aEnd.Col() &&
584 0 : (rRef.aStart.Row() == rArea.aStart.Row() || rRef.aStart.Row() == rArea.aStart.Row()+1) &&
585 0 : rRef.aEnd.Row() == rArea.aEnd.Row() &&
586 0 : rRef.aStart.Tab() >= rArea.aStart.Tab() && rRef.aEnd.Tab() <= rArea.aEnd.Tab() );
587 :
588 0 : if ( bUpdateX )
589 : {
590 0 : rRef.aEnd.SetCol(sal::static_int_cast<SCsCOL>(rRef.aEnd.Col() + nGrowX));
591 0 : eRet = UR_UPDATED;
592 : }
593 0 : if ( bUpdateY )
594 : {
595 0 : rRef.aEnd.SetRow(sal::static_int_cast<SCsROW>(rRef.aEnd.Row() + nGrowY));
596 0 : eRet = UR_UPDATED;
597 : }
598 :
599 0 : return eRet;
600 : }
601 :
602 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|