1 | /* This file is part of the KDE project |
2 | Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com> |
3 | Copyright (C) 2000 Torben Weis <weis@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | // Local |
22 | #include "Cluster.h" |
23 | |
24 | #include <stdlib.h> |
25 | |
26 | #include <kdebug.h> |
27 | |
28 | #include "Cell.h" |
29 | #include "RowColumnFormat.h" |
30 | |
31 | using namespace Calligra::Sheets; |
32 | |
33 | #if 0 |
34 | /**************************************************** |
35 | * |
36 | * Cluster |
37 | * |
38 | ****************************************************/ |
39 | |
40 | /* Generate a matrix LEVEL1 with the size LEVEL1*LEVEL1 */ |
41 | Cluster::Cluster() |
42 | : m_first(0), m_autoDelete(false), m_biggestX(0), m_biggestY(0) |
43 | { |
44 | m_cluster = (Cell***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(Cell**)); |
45 | |
46 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) |
47 | for (int y = 0; y < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++y) |
48 | m_cluster[ y * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + x ] = 0; |
49 | } |
50 | |
51 | /* Delete the matrix LEVEL1 and all existing LEVEL2 matrizes */ |
52 | Cluster::~Cluster() |
53 | { |
54 | // Can't we use clear(), to remove double code - Philipp? |
55 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) |
56 | for (int y = 0; y < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++y) { |
57 | Cell** cl = m_cluster[ y * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + x ]; |
58 | if (cl) { |
59 | free(cl); |
60 | m_cluster[ y * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + x ] = 0; |
61 | } |
62 | } |
63 | |
64 | if (m_autoDelete) { |
65 | Cell* cell = m_first; |
66 | while (cell) { |
67 | Cell* n = cell->nextCell(); |
68 | delete cell; |
69 | cell = n; |
70 | } |
71 | } |
72 | |
73 | free(m_cluster); |
74 | } |
75 | |
76 | void Cluster::clear() |
77 | { |
78 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) |
79 | for (int y = 0; y < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++y) { |
80 | Cell** cl = m_cluster[ y * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + x ]; |
81 | if (cl) { |
82 | free(cl); |
83 | m_cluster[ y * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + x ] = 0; |
84 | } |
85 | } |
86 | |
87 | if (m_autoDelete) { |
88 | Cell* cell = m_first; |
89 | while (cell) { |
90 | Cell* n = cell->nextCell(); |
91 | delete cell; |
92 | cell = n; |
93 | } |
94 | } |
95 | |
96 | m_first = 0; |
97 | m_biggestX = m_biggestY = 0; |
98 | } |
99 | |
100 | Cell* Cluster::lookup(int x, int y) const |
101 | { |
102 | if (x >= CALLIGRA_SHEETS_CLUSTER_MAX || x < 0 || y >= CALLIGRA_SHEETS_CLUSTER_MAX || y < 0) { |
103 | kDebug(36001) << "Cluster::lookup: invalid column or row value (col:" |
104 | << x << " | row: " << y << ")" << endl; |
105 | return 0; |
106 | } |
107 | int cx = x / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
108 | int cy = y / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
109 | int dx = x % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
110 | int dy = y % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
111 | |
112 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
113 | if (!cl) |
114 | return 0; |
115 | |
116 | return cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]; |
117 | } |
118 | |
119 | /* Paste a cell in LEVEL2 (it's more paste than insert) */ |
120 | void Cluster::insert(Cell* cell, int x, int y) |
121 | { |
122 | if (x >= CALLIGRA_SHEETS_CLUSTER_MAX || x < 0 || y >= CALLIGRA_SHEETS_CLUSTER_MAX || y < 0) { |
123 | kDebug(36001) << "Cluster::insert: invalid column or row value (col:" |
124 | << x << " | row: " << y << ")" << endl; |
125 | return; |
126 | } |
127 | |
128 | int cx = x / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
129 | int cy = y / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
130 | int dx = x % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
131 | int dy = y % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
132 | |
133 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
134 | if (!cl) { |
135 | cl = (Cell**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(Cell*)); |
136 | m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] = cl; |
137 | |
138 | for (int a = 0; a < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++a) |
139 | for (int b = 0; b < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++b) |
140 | cl[ b * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + a ] = 0; |
141 | } |
142 | |
143 | if (cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]) |
144 | remove(x, y); |
145 | |
146 | cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ] = cell; |
147 | |
148 | if (m_first) { |
149 | cell->setNextCell(m_first); |
150 | m_first->setPreviousCell(cell); |
151 | } |
152 | m_first = cell; |
153 | |
154 | if (x > m_biggestX) m_biggestX = x; |
155 | if (y > m_biggestY) m_biggestY = y; |
156 | } |
157 | |
158 | /* Removes the cell of a matrix, the matrix itself keeps unchanged */ |
159 | void Cluster::remove(int x, int y) |
160 | { |
161 | if (x >= CALLIGRA_SHEETS_CLUSTER_MAX || x < 0 || y >= CALLIGRA_SHEETS_CLUSTER_MAX || y < 0) { |
162 | kDebug(36001) << "Cluster::remove: invalid column or row value (col:" |
163 | << x << " | row: " << y << ")" << endl; |
164 | return; |
165 | } |
166 | |
167 | int cx = x / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
168 | int cy = y / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
169 | int dx = x % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
170 | int dy = y % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
171 | |
172 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
173 | if (!cl) |
174 | return; |
175 | |
176 | Cell* c = cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]; |
177 | if (!c) |
178 | return; |
179 | |
180 | cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ] = 0; |
181 | |
182 | if (m_autoDelete) { |
183 | if (m_first == c) |
184 | m_first = c->nextCell(); |
185 | if (c->doesMergeCells()) { |
186 | c->mergeCells(c->column(), c->row(), 0, 0); |
187 | } |
188 | delete c; |
189 | } else { |
190 | if (m_first == c) |
191 | m_first = c->nextCell(); |
192 | if (c->previousCell()) |
193 | c->previousCell()->setNextCell(c->nextCell()); |
194 | if (c->nextCell()) |
195 | c->nextCell()->setPreviousCell(c->previousCell()); |
196 | c->setNextCell(0); |
197 | c->setPreviousCell(0); |
198 | } |
199 | } |
200 | |
201 | bool Cluster::insertShiftRight(const QPoint& marker) |
202 | { |
203 | bool dummy; |
204 | return insertShiftRight(marker, dummy); |
205 | } |
206 | |
207 | bool Cluster::insertShiftDown(const QPoint& marker) |
208 | { |
209 | bool dummy; |
210 | return insertShiftDown(marker, dummy); |
211 | } |
212 | |
213 | void Cluster::removeShiftUp(const QPoint& marker) |
214 | { |
215 | bool dummy; |
216 | removeShiftUp(marker, dummy); |
217 | } |
218 | |
219 | void Cluster::removeShiftLeft(const QPoint& marker) |
220 | { |
221 | bool dummy; |
222 | removeShiftLeft(marker, dummy); |
223 | } |
224 | |
225 | void Cluster::setAutoDelete(bool b) |
226 | { |
227 | m_autoDelete = b; |
228 | } |
229 | |
230 | bool Cluster::autoDelete() const |
231 | { |
232 | return m_autoDelete; |
233 | } |
234 | |
235 | Cell* Cluster::firstCell() const |
236 | { |
237 | return m_first; |
238 | } |
239 | |
240 | bool Cluster::insertShiftRight(const QPoint& marker, bool& work) |
241 | { |
242 | work = false; |
243 | |
244 | if (marker.x() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.x() < 0 || |
245 | marker.y() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.y() < 0) { |
246 | kDebug(36001) << "Cluster::insertShiftRight: invalid column or row value (col:" |
247 | << marker.x() << " | row: " << marker.y() << ")" << endl; |
248 | return false; |
249 | } |
250 | |
251 | int cx = marker.x() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
252 | int cy = marker.y() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
253 | int dx = marker.x() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
254 | int dy = marker.y() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
255 | |
256 | // Is there a cell at the bottom most position ? |
257 | // In this case the shift is impossible. |
258 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1 ]; |
259 | if (cl && cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1 ]) |
260 | return false; |
261 | |
262 | bool a = autoDelete(); |
263 | setAutoDelete(false); |
264 | |
265 | // Move cells in this row one down. |
266 | for (int i = CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1; i >= cx ; --i) { |
267 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + i ]; |
268 | if (cl) { |
269 | work = true; |
270 | int left = 0; |
271 | if (i == cx) |
272 | left = dx; |
273 | int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
274 | if (i == CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) |
275 | right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 2; |
276 | for (int k = right; k >= left; --k) { |
277 | Cell* c = cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + k ]; |
278 | if (c) { |
279 | remove(c->column(), c->row()); |
280 | c->move(c->column() + 1, c->row()); |
281 | insert(c, c->column(), c->row()); |
282 | } |
283 | } |
284 | } |
285 | } |
286 | |
287 | setAutoDelete(a); |
288 | |
289 | return true; |
290 | } |
291 | |
292 | bool Cluster::insertShiftDown(const QPoint& marker, bool& work) |
293 | { |
294 | work = false; |
295 | |
296 | if (marker.x() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.x() < 0 || |
297 | marker.y() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.y() < 0) { |
298 | kDebug(36001) << "Cluster::insertShiftDown: invalid column or row value (col:" |
299 | << marker.x() << " | row: " << marker.y() << ")" << endl; |
300 | return false; |
301 | } |
302 | |
303 | int cx = marker.x() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
304 | int cy = marker.y() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
305 | int dx = marker.x() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
306 | int dy = marker.y() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
307 | |
308 | // Is there a cell at the right most position ? |
309 | // In this case the shift is impossible. |
310 | Cell** cl = m_cluster[ CALLIGRA_SHEETS_CLUSTER_LEVEL1 * (CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) + cx ]; |
311 | if (cl && cl[ CALLIGRA_SHEETS_CLUSTER_LEVEL2 *(CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1) + dx ]) |
312 | return false; |
313 | |
314 | bool a = autoDelete(); |
315 | setAutoDelete(false); |
316 | |
317 | // Move cells in this column one right. |
318 | for (int i = CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1; i >= cy ; --i) { |
319 | Cell** cl = m_cluster[ i * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
320 | if (cl) { |
321 | work = true; |
322 | |
323 | int top = 0; |
324 | if (i == cy) |
325 | top = dy; |
326 | int bottom = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
327 | if (i == CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) |
328 | bottom = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 2; |
329 | for (int k = bottom; k >= top; --k) { |
330 | Cell* c = cl[ k * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]; |
331 | if (c) { |
332 | remove(c->column(), c->row()); |
333 | c->move(c->column(), c->row() + 1); |
334 | insert(c, c->column(), c->row()); |
335 | } |
336 | } |
337 | } |
338 | } |
339 | |
340 | setAutoDelete(a); |
341 | |
342 | return true; |
343 | } |
344 | |
345 | bool Cluster::insertColumn(int col) |
346 | { |
347 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
348 | kDebug(36001) << "Cluster::insertColumn: invalid column value (col:" |
349 | << col << ")" << endl; |
350 | return false; |
351 | } |
352 | |
353 | // Is there a cell at the right most position ? |
354 | // In this case the shift is impossible. |
355 | for (int t1 = 0; t1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++t1) { |
356 | Cell** cl = m_cluster[ t1 * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1 ]; |
357 | if (cl) |
358 | for (int t2 = 0; t2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++t2) |
359 | if (cl[ t2 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1 ]) |
360 | return false; |
361 | } |
362 | |
363 | for (int t1 = 0; t1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++t1) { |
364 | bool work = true; |
365 | for (int t2 = 0; work && t2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++t2) |
366 | insertShiftRight(QPoint(col, t1 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + t2), work); |
367 | } |
368 | |
369 | return true; |
370 | } |
371 | |
372 | bool Cluster::insertRow(int row) |
373 | { |
374 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
375 | kDebug(36001) << "Cluster::insertRow: invalid row value (row:" |
376 | << row << ")" << endl; |
377 | return false; |
378 | } |
379 | |
380 | // Is there a cell at the bottom most position ? |
381 | // In this case the shift is impossible. |
382 | for (int t1 = 0; t1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++t1) { |
383 | Cell** cl = m_cluster[ CALLIGRA_SHEETS_CLUSTER_LEVEL1 * (CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) + t1 ]; |
384 | if (cl) |
385 | for (int t2 = 0; t2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++t2) |
386 | if (cl[ CALLIGRA_SHEETS_CLUSTER_LEVEL2 *(CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1) + t2 ]) |
387 | return false; |
388 | } |
389 | |
390 | for (int t1 = 0; t1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++t1) { |
391 | bool work = true; |
392 | for (int t2 = 0; work && t2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++t2) |
393 | insertShiftDown(QPoint(t1 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + t2, row), work); |
394 | } |
395 | |
396 | return true; |
397 | } |
398 | |
399 | void Cluster::removeShiftUp(const QPoint& marker, bool& work) |
400 | { |
401 | work = false; |
402 | |
403 | if (marker.x() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.x() < 0 || |
404 | marker.y() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.y() < 0) { |
405 | kDebug(36001) << "Cluster::removeShiftUp: invalid column or row value (col:" |
406 | << marker.x() << " | row: " << marker.y() << ")" << endl; |
407 | return; |
408 | } |
409 | |
410 | int cx = marker.x() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
411 | int cy = marker.y() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
412 | int dx = marker.x() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
413 | int dy = marker.y() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
414 | |
415 | bool a = autoDelete(); |
416 | setAutoDelete(false); |
417 | |
418 | // Move cells in this column one column to the left. |
419 | for (int i = cy; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { |
420 | Cell** cl = m_cluster[ i * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
421 | if (cl) { |
422 | work = true; |
423 | |
424 | int top = 0; |
425 | if (i == cy) |
426 | top = dy + 1; |
427 | int bottom = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
428 | for (int k = top; k <= bottom; ++k) { |
429 | Cell* c = cl[ k * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]; |
430 | if (c) { |
431 | remove(c->column(), c->row()); |
432 | c->move(c->column(), c->row() - 1); |
433 | insert(c, c->column(), c->row()); |
434 | } |
435 | } |
436 | } |
437 | } |
438 | |
439 | setAutoDelete(a); |
440 | } |
441 | |
442 | void Cluster::removeShiftLeft(const QPoint& marker, bool& work) |
443 | { |
444 | work = false; |
445 | |
446 | if (marker.x() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.x() < 0 || |
447 | marker.y() >= CALLIGRA_SHEETS_CLUSTER_MAX || marker.y() < 0) { |
448 | kDebug(36001) << "Cluster::removeShiftLeft: invalid column or row value (col:" |
449 | << marker.x() << " | row: " << marker.y() << ")" << endl; |
450 | return; |
451 | } |
452 | |
453 | int cx = marker.x() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
454 | int cy = marker.y() / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
455 | int dx = marker.x() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
456 | int dy = marker.y() % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
457 | |
458 | bool a = autoDelete(); |
459 | setAutoDelete(false); |
460 | |
461 | // Move cells in this row one row up. |
462 | for (int i = cx; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { |
463 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + i ]; |
464 | if (cl) { |
465 | work = true; |
466 | |
467 | int left = 0; |
468 | if (i == cx) |
469 | left = dx + 1; |
470 | int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
471 | for (int k = left; k <= right; ++k) { |
472 | Cell* c = cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + k ]; |
473 | if (c) { |
474 | remove(c->column(), c->row()); |
475 | c->move(c->column() - 1, c->row()); |
476 | insert(c, c->column(), c->row()); |
477 | } |
478 | } |
479 | } |
480 | } |
481 | |
482 | setAutoDelete(a); |
483 | } |
484 | |
485 | void Cluster::removeColumn(int col) |
486 | { |
487 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
488 | kDebug(36001) << "Cluster::removeColumn: invalid column value (col:" |
489 | << col << ")" << endl; |
490 | return; |
491 | } |
492 | |
493 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
494 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
495 | |
496 | for (int y1 = 0; y1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++y1) { |
497 | Cell** cl = m_cluster[ y1 * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
498 | if (cl) |
499 | for (int y2 = 0; y2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++y2) |
500 | if (cl[ y2 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]) |
501 | remove(col, y1 * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + y2); |
502 | } |
503 | |
504 | for (int t1 = 0; t1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++t1) { |
505 | bool work = true; |
506 | for (int t2 = 0; work && t2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++t2) |
507 | removeShiftLeft(QPoint(col, t1 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + t2), work); |
508 | } |
509 | } |
510 | |
511 | void Cluster::removeRow(int row) |
512 | { |
513 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
514 | kDebug(36001) << "Cluster::removeRow: invalid row value (row:" |
515 | << row << ")" << endl; |
516 | return; |
517 | } |
518 | |
519 | int cy = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
520 | int dy = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
521 | |
522 | for (int x1 = 0; x1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x1) { |
523 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + x1 ]; |
524 | if (cl) |
525 | for (int x2 = 0; x2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++x2) |
526 | if (cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + x2 ]) |
527 | remove(x1 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + x2, row); |
528 | } |
529 | |
530 | for (int t1 = 0; t1 < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++t1) { |
531 | bool work = true; |
532 | for (int t2 = 0; work && t2 < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++t2) |
533 | removeShiftUp(QPoint(t1 * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + t2, row), work); |
534 | } |
535 | } |
536 | |
537 | void Cluster::clearColumn(int col) |
538 | { |
539 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
540 | kDebug(36001) << "Cluster::clearColumn: invalid column value (col:" |
541 | << col << ")" << endl; |
542 | return; |
543 | } |
544 | |
545 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
546 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
547 | |
548 | for (int cy = 0; cy < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++cy) { |
549 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ]; |
550 | if (cl) |
551 | for (int dy = 0; dy < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++dy) |
552 | if (cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]) { |
553 | int row = cy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dy ; |
554 | remove(col, row); |
555 | } |
556 | } |
557 | } |
558 | |
559 | void Cluster::clearRow(int row) |
560 | { |
561 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
562 | kDebug(36001) << "Cluster::clearRow: invalid row value (row:" |
563 | << row << ")" << endl; |
564 | return; |
565 | } |
566 | |
567 | int cy = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
568 | int dy = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
569 | |
570 | for (int cx = 0; cx < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++cx) { |
571 | Cell** cl = m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + cx ]; |
572 | if (cl) |
573 | for (int dx = 0; dx < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++dx) |
574 | if (cl[ dy * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ]) { |
575 | int column = cx * CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx ; |
576 | remove(column, row); |
577 | } |
578 | } |
579 | } |
580 | |
581 | Value Cluster::valueRange(int col1, int row1, |
582 | int col2, int row2) const |
583 | { |
584 | Value empty; |
585 | |
586 | //swap first/second values if needed |
587 | if (col1 > col2) { |
588 | int p = col1; col1 = col2; col2 = p; |
589 | } |
590 | if (row1 > row2) { |
591 | int p = row1; row1 = col2; row2 = p; |
592 | } |
593 | if ((row1 < 0) || (col1 < 0) || (row2 > CALLIGRA_SHEETS_CLUSTER_MAX) || |
594 | (col2 > CALLIGRA_SHEETS_CLUSTER_MAX)) |
595 | return empty; |
596 | |
597 | // if we are out of range occupied by cells, we return an empty |
598 | // array of the requested size |
599 | if ((row1 > m_biggestY) || (col1 > m_biggestX)) |
600 | return Value(Value::Array); |
601 | |
602 | return makeArray(col1, row1, col2, row2); |
603 | } |
604 | |
605 | Value Cluster::makeArray(int col1, int row1, int col2, int row2) const |
606 | { |
607 | // this generates an array of values |
608 | Value array(Value::Array); |
609 | for (int row = row1; row <= row2; ++row) { |
610 | for (Cell* cell = getFirstCellRow(row); cell; cell = getNextCellRight(cell->column(), row)) { |
611 | if (cell->column() >= col1 && cell->column() <= col2) |
612 | array.setElement(cell->column() - col1, row - row1, cell->value()); |
613 | } |
614 | } |
615 | //return the result |
616 | return array; |
617 | } |
618 | |
619 | Cell* Cluster::getFirstCellColumn(int col) const |
620 | { |
621 | Cell* cell = lookup(col, 1); |
622 | |
623 | if (cell == 0) { |
624 | cell = getNextCellDown(col, 1); |
625 | } |
626 | return cell; |
627 | } |
628 | |
629 | Cell* Cluster::getLastCellColumn(int col) const |
630 | { |
631 | Cell* cell = lookup(col, KS_rowMax); |
632 | |
633 | if (cell == 0) { |
634 | cell = getNextCellUp(col, KS_rowMax); |
635 | } |
636 | return cell; |
637 | } |
638 | |
639 | Cell* Cluster::getFirstCellRow(int row) const |
640 | { |
641 | Cell* cell = lookup(1, row); |
642 | |
643 | if (cell == 0) { |
644 | cell = getNextCellRight(1, row); |
645 | } |
646 | return cell; |
647 | } |
648 | |
649 | Cell* Cluster::getLastCellRow(int row) const |
650 | { |
651 | Cell* cell = lookup(KS_colMax, row); |
652 | |
653 | if (cell == 0) { |
654 | cell = getNextCellLeft(KS_colMax, row); |
655 | } |
656 | return cell; |
657 | } |
658 | |
659 | Cell* Cluster::getNextCellUp(int col, int row) const |
660 | { |
661 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
662 | int cy = (row - 1) / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
663 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
664 | int dy = (row - 1) % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
665 | |
666 | while (cy >= 0) { |
667 | if (m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] != 0) { |
668 | while (dy >= 0) { |
669 | |
670 | if (m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx] |
671 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx] != 0) { |
672 | return m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] |
673 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx]; |
674 | } |
675 | dy--; |
676 | } |
677 | } |
678 | cy--; |
679 | dy = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
680 | } |
681 | return 0; |
682 | } |
683 | |
684 | Cell* Cluster::getNextCellDown(int col, int row) const |
685 | { |
686 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
687 | int cy = (row + 1) / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
688 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
689 | int dy = (row + 1) % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
690 | |
691 | while (cy < CALLIGRA_SHEETS_CLUSTER_LEVEL1) { |
692 | if (m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] != 0) { |
693 | while (dy < CALLIGRA_SHEETS_CLUSTER_LEVEL2) { |
694 | |
695 | if (m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx] |
696 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx] != 0) { |
697 | return m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] |
698 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx]; |
699 | } |
700 | dy++; |
701 | } |
702 | } |
703 | cy++; |
704 | dy = 0; |
705 | } |
706 | return 0; |
707 | } |
708 | |
709 | Cell* Cluster::getNextCellLeft(int col, int row) const |
710 | { |
711 | int cx = (col - 1) / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
712 | int cy = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
713 | int dx = (col - 1) % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
714 | int dy = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
715 | |
716 | while (cx >= 0) { |
717 | if (m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] != 0) { |
718 | while (dx >= 0) { |
719 | |
720 | if (m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx] |
721 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx] != 0) { |
722 | return m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] |
723 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx]; |
724 | } |
725 | dx--; |
726 | } |
727 | } |
728 | cx--; |
729 | dx = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
730 | } |
731 | return 0; |
732 | } |
733 | |
734 | Cell* Cluster::getNextCellRight(int col, int row) const |
735 | { |
736 | int cx = (col + 1) / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
737 | int cy = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
738 | int dx = (col + 1) % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
739 | int dy = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
740 | |
741 | while (cx < CALLIGRA_SHEETS_CLUSTER_LEVEL1) { |
742 | if (m_cluster[ cy * CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] != 0) { |
743 | while (dx < CALLIGRA_SHEETS_CLUSTER_LEVEL2) { |
744 | |
745 | if (m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx] |
746 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx] != 0) { |
747 | return m_cluster[ cy*CALLIGRA_SHEETS_CLUSTER_LEVEL1 + cx ] |
748 | [ dy*CALLIGRA_SHEETS_CLUSTER_LEVEL2 + dx]; |
749 | } |
750 | dx++; |
751 | } |
752 | } |
753 | cx++; |
754 | dx = 0; |
755 | } |
756 | return 0; |
757 | } |
758 | #endif |
759 | |
760 | /**************************************************** |
761 | * |
762 | * ColumnCluster |
763 | * |
764 | ****************************************************/ |
765 | |
766 | ColumnCluster::ColumnCluster() |
767 | : m_first(0), m_autoDelete(false) |
768 | { |
769 | m_cluster = (ColumnFormat***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(ColumnFormat**)); |
770 | |
771 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) |
772 | m_cluster[ x ] = 0; |
773 | } |
774 | |
775 | ColumnCluster::~ColumnCluster() |
776 | { |
777 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) { |
778 | ColumnFormat** cl = m_cluster[ x ]; |
779 | if (cl) { |
780 | free(cl); |
781 | m_cluster[ x ] = 0; |
782 | } |
783 | } |
784 | |
785 | if (m_autoDelete) { |
786 | ColumnFormat* cell = m_first; |
787 | while (cell) { |
788 | ColumnFormat* n = cell->next(); |
789 | delete cell; |
790 | cell = n; |
791 | } |
792 | } |
793 | |
794 | |
795 | free(m_cluster); |
796 | } |
797 | |
798 | ColumnFormat* ColumnCluster::lookup(int col) |
799 | { |
800 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
801 | kDebug(36001) << "ColumnCluster::lookup: invalid column value (col:" |
802 | << col << ")" << endl; |
803 | return 0; |
804 | } |
805 | |
806 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
807 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
808 | |
809 | ColumnFormat** cl = m_cluster[ cx ]; |
810 | if (!cl) |
811 | return 0; |
812 | |
813 | return cl[ dx ]; |
814 | } |
815 | |
816 | const ColumnFormat* ColumnCluster::lookup(int col) const |
817 | { |
818 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
819 | kDebug(36001) << "ColumnCluster::lookup: invalid column value (col:" |
820 | << col << ")" << endl; |
821 | return 0; |
822 | } |
823 | |
824 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
825 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
826 | |
827 | ColumnFormat** cl = m_cluster[ cx ]; |
828 | if (!cl) |
829 | return 0; |
830 | |
831 | return cl[ dx ]; |
832 | } |
833 | |
834 | void ColumnCluster::clear() |
835 | { |
836 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) { |
837 | ColumnFormat** cl = m_cluster[ x ]; |
838 | if (cl) { |
839 | free(cl); |
840 | m_cluster[ x ] = 0; |
841 | } |
842 | } |
843 | |
844 | if (m_autoDelete) { |
845 | ColumnFormat* cell = m_first; |
846 | while (cell) { |
847 | ColumnFormat* n = cell->next(); |
848 | delete cell; |
849 | cell = n; |
850 | } |
851 | } |
852 | |
853 | m_first = 0; |
854 | } |
855 | |
856 | void ColumnCluster::insertElement(ColumnFormat* lay, int col) |
857 | { |
858 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
859 | kDebug(36001) << "ColumnCluster::insertElement: invalid column value (col:" |
860 | << col << ")" << endl; |
861 | return; |
862 | } |
863 | |
864 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
865 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
866 | |
867 | ColumnFormat** cl = m_cluster[ cx ]; |
868 | if (!cl) { |
869 | cl = (ColumnFormat**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(ColumnFormat*)); |
870 | m_cluster[ cx ] = cl; |
871 | |
872 | for (int a = 0; a < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++a) |
873 | cl[ a ] = 0; |
874 | } |
875 | |
876 | if (cl[ dx ]) |
877 | removeElement(col); |
878 | |
879 | cl[ dx ] = lay; |
880 | |
881 | if (m_first) { |
882 | lay->setNext(m_first); |
883 | m_first->setPrevious(lay); |
884 | } |
885 | m_first = lay; |
886 | } |
887 | |
888 | void ColumnCluster::removeElement(int col) |
889 | { |
890 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
891 | kDebug(36001) << "ColumnCluster::removeElement: invalid column value (col:" |
892 | << col << ")" << endl; |
893 | return; |
894 | } |
895 | |
896 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
897 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
898 | |
899 | ColumnFormat** cl = m_cluster[ cx ]; |
900 | if (!cl) |
901 | return; |
902 | |
903 | ColumnFormat* c = cl[ dx ]; |
904 | if (!c) |
905 | return; |
906 | |
907 | cl[ dx ] = 0; |
908 | |
909 | if (m_autoDelete) { |
910 | if (m_first == c) |
911 | m_first = c->next(); |
912 | delete c; |
913 | } else { |
914 | if (m_first == c) |
915 | m_first = c->next(); |
916 | if (c->previous()) |
917 | c->previous()->setNext(c->next()); |
918 | if (c->next()) |
919 | c->next()->setPrevious(c->previous()); |
920 | c->setNext(0); |
921 | c->setPrevious(0); |
922 | } |
923 | } |
924 | |
925 | bool ColumnCluster::insertColumn(int col) |
926 | { |
927 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
928 | kDebug(36001) << "ColumnCluster::insertColumn: invalid column value (col:" |
929 | << col << ")" << endl; |
930 | return false; |
931 | } |
932 | |
933 | int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
934 | int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
935 | |
936 | // Is there a column layout at the right most position ? |
937 | // In this case the shift is impossible. |
938 | ColumnFormat** cl = m_cluster[ CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1 ]; |
939 | if (cl && cl[ CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1 ]) |
940 | return false; |
941 | |
942 | bool a = autoDelete(); |
943 | setAutoDelete(false); |
944 | |
945 | for (int i = CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1; i >= cx ; --i) { |
946 | ColumnFormat** cl = m_cluster[ i ]; |
947 | if (cl) { |
948 | int left = 0; |
949 | if (i == cx) |
950 | left = dx; |
951 | int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
952 | if (i == CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) |
953 | right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 2; |
954 | for (int k = right; k >= left; --k) { |
955 | ColumnFormat* c = cl[ k ]; |
956 | if (c) { |
957 | removeElement(c->column()); |
958 | c->setColumn(c->column() + 1); |
959 | insertElement(c, c->column()); |
960 | } |
961 | } |
962 | } |
963 | } |
964 | |
965 | setAutoDelete(a); |
966 | |
967 | return true; |
968 | } |
969 | |
970 | bool ColumnCluster::removeColumn(int column) |
971 | { |
972 | if (column >= CALLIGRA_SHEETS_CLUSTER_MAX || column < 0) { |
973 | kDebug(36001) << "ColumnCluster::removeColumn: invalid column value (col:" |
974 | << column << ")" << endl; |
975 | return false; |
976 | } |
977 | |
978 | int cx = column / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
979 | int dx = column % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
980 | |
981 | removeElement(column); |
982 | |
983 | bool a = autoDelete(); |
984 | setAutoDelete(false); |
985 | |
986 | for (int i = cx; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { |
987 | ColumnFormat** cl = m_cluster[ i ]; |
988 | if (cl) { |
989 | int left = 0; |
990 | if (i == cx) |
991 | left = dx + 1; |
992 | int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
993 | for (int k = left; k <= right; ++k) { |
994 | ColumnFormat* c = cl[ k ]; |
995 | if (c) { |
996 | removeElement(c->column()); |
997 | c->setColumn(c->column() - 1); |
998 | insertElement(c, c->column()); |
999 | } |
1000 | } |
1001 | } |
1002 | } |
1003 | |
1004 | setAutoDelete(a); |
1005 | |
1006 | return true; |
1007 | } |
1008 | |
1009 | void ColumnCluster::setAutoDelete(bool a) |
1010 | { |
1011 | m_autoDelete = a; |
1012 | } |
1013 | |
1014 | bool ColumnCluster::autoDelete() const |
1015 | { |
1016 | return m_autoDelete; |
1017 | } |
1018 | |
1019 | ColumnFormat* ColumnCluster::next(int col) const |
1020 | { |
1021 | if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { |
1022 | kDebug(36001) << "ColumnCluster::next: invalid column value (col:" |
1023 | << col << ")" << endl; |
1024 | return 0; |
1025 | } |
1026 | |
1027 | int cx = (col + 1) / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1028 | int dx = (col + 1) % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1029 | |
1030 | while (cx < CALLIGRA_SHEETS_CLUSTER_LEVEL1) { |
1031 | if (m_cluster[ cx ]) { |
1032 | while (dx < CALLIGRA_SHEETS_CLUSTER_LEVEL2) { |
1033 | |
1034 | if (m_cluster[ cx ][ dx ]) { |
1035 | return m_cluster[ cx ][ dx ]; |
1036 | } |
1037 | ++dx; |
1038 | } |
1039 | } |
1040 | ++cx; |
1041 | dx = 0; |
1042 | } |
1043 | return 0; |
1044 | } |
1045 | |
1046 | void ColumnCluster::operator=(const ColumnCluster & other) |
1047 | { |
1048 | m_first = 0; |
1049 | m_autoDelete = other.m_autoDelete; |
1050 | // TODO Stefan: Optimize! |
1051 | m_cluster = (ColumnFormat***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(ColumnFormat**)); |
1052 | for (int i = 0; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { |
1053 | if (other.m_cluster[i]) { |
1054 | m_cluster[i] = (ColumnFormat**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(ColumnFormat*)); |
1055 | for (int j = 0; j < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++j) { |
1056 | m_cluster[i][j] = 0; |
1057 | if (other.m_cluster[i][j]) { |
1058 | ColumnFormat* columnFormat = new ColumnFormat(*other.m_cluster[i][j]); |
1059 | columnFormat->setNext(0); |
1060 | columnFormat->setPrevious(0); |
1061 | insertElement(columnFormat, columnFormat->column()); |
1062 | } |
1063 | } |
1064 | } else |
1065 | m_cluster[i] = 0; |
1066 | } |
1067 | } |
1068 | |
1069 | /**************************************************** |
1070 | * |
1071 | * RowCluster |
1072 | * |
1073 | ****************************************************/ |
1074 | |
1075 | RowCluster::RowCluster() |
1076 | : m_first(0), m_autoDelete(false) |
1077 | { |
1078 | m_cluster = (RowFormat***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(RowFormat**)); |
1079 | |
1080 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) |
1081 | m_cluster[ x ] = 0; |
1082 | } |
1083 | |
1084 | RowCluster::~RowCluster() |
1085 | { |
1086 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) { |
1087 | RowFormat** cl = m_cluster[ x ]; |
1088 | if (cl) { |
1089 | free(cl); |
1090 | m_cluster[ x ] = 0; |
1091 | } |
1092 | } |
1093 | |
1094 | if (m_autoDelete) { |
1095 | RowFormat* cell = m_first; |
1096 | while (cell) { |
1097 | RowFormat* n = cell->next(); |
1098 | delete cell; |
1099 | cell = n; |
1100 | } |
1101 | } |
1102 | |
1103 | free(m_cluster); |
1104 | } |
1105 | |
1106 | const RowFormat* RowCluster::lookup(int row) const |
1107 | { |
1108 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
1109 | kDebug(36001) << "RowCluster::lookup: invalid row value (row:" |
1110 | << row << ")" << endl; |
1111 | return 0; |
1112 | } |
1113 | |
1114 | int cx = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1115 | int dx = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1116 | |
1117 | RowFormat** cl = m_cluster[ cx ]; |
1118 | if (!cl) |
1119 | return 0; |
1120 | |
1121 | return cl[ dx ]; |
1122 | } |
1123 | |
1124 | RowFormat* RowCluster::lookup(int row) |
1125 | { |
1126 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
1127 | kDebug(36001) << "RowCluster::lookup: invalid row value (row:" |
1128 | << row << ")" << endl; |
1129 | return 0; |
1130 | } |
1131 | |
1132 | int cx = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1133 | int dx = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1134 | |
1135 | RowFormat** cl = m_cluster[ cx ]; |
1136 | if (!cl) |
1137 | return 0; |
1138 | |
1139 | return cl[ dx ]; |
1140 | } |
1141 | |
1142 | void RowCluster::clear() |
1143 | { |
1144 | for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) { |
1145 | RowFormat** cl = m_cluster[ x ]; |
1146 | if (cl) { |
1147 | free(cl); |
1148 | m_cluster[ x ] = 0; |
1149 | } |
1150 | } |
1151 | |
1152 | if (m_autoDelete) { |
1153 | RowFormat* cell = m_first; |
1154 | while (cell) { |
1155 | RowFormat* n = cell->next(); |
1156 | delete cell; |
1157 | cell = n; |
1158 | } |
1159 | } |
1160 | |
1161 | m_first = 0; |
1162 | } |
1163 | |
1164 | void RowCluster::insertElement(RowFormat* lay, int row) |
1165 | { |
1166 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
1167 | kDebug(36001) << "RowCluster::insertElement: invalid row value (row:" |
1168 | << row << ")" << endl; |
1169 | return; |
1170 | } |
1171 | |
1172 | int cx = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1173 | int dx = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1174 | |
1175 | RowFormat** cl = m_cluster[ cx ]; |
1176 | if (!cl) { |
1177 | cl = (RowFormat**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(RowFormat*)); |
1178 | m_cluster[ cx ] = cl; |
1179 | |
1180 | for (int a = 0; a < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++a) |
1181 | cl[ a ] = 0; |
1182 | } |
1183 | |
1184 | if (cl[ dx ]) |
1185 | removeElement(row); |
1186 | |
1187 | cl[ dx ] = lay; |
1188 | |
1189 | if (m_first) { |
1190 | lay->setNext(m_first); |
1191 | m_first->setPrevious(lay); |
1192 | } |
1193 | m_first = lay; |
1194 | } |
1195 | |
1196 | void RowCluster::removeElement(int row) |
1197 | { |
1198 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
1199 | kDebug(36001) << "RowCluster::removeElement: invalid row value (row:" |
1200 | << row << ")" << endl; |
1201 | return; |
1202 | } |
1203 | |
1204 | int cx = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1205 | int dx = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1206 | |
1207 | RowFormat** cl = m_cluster[ cx ]; |
1208 | if (!cl) |
1209 | return; |
1210 | |
1211 | RowFormat* c = cl[ dx ]; |
1212 | if (!c) |
1213 | return; |
1214 | |
1215 | cl[ dx ] = 0; |
1216 | |
1217 | if (m_autoDelete) { |
1218 | if (m_first == c) |
1219 | m_first = c->next(); |
1220 | delete c; |
1221 | } else { |
1222 | if (m_first == c) |
1223 | m_first = c->next(); |
1224 | if (c->previous()) |
1225 | c->previous()->setNext(c->next()); |
1226 | if (c->next()) |
1227 | c->next()->setPrevious(c->previous()); |
1228 | c->setNext(0); |
1229 | c->setPrevious(0); |
1230 | } |
1231 | } |
1232 | |
1233 | bool RowCluster::insertRow(int row) |
1234 | { |
1235 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
1236 | kDebug(36001) << "RowCluster::insertRow: invalid row value (row:" |
1237 | << row << ")" << endl; |
1238 | return false; |
1239 | } |
1240 | |
1241 | int cx = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1242 | int dx = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1243 | |
1244 | // Is there a row layout at the bottom most position ? |
1245 | // In this case the shift is impossible. |
1246 | RowFormat** cl = m_cluster[ CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1 ]; |
1247 | if (cl && cl[ CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1 ]) |
1248 | return false; |
1249 | |
1250 | bool a = autoDelete(); |
1251 | setAutoDelete(false); |
1252 | |
1253 | for (int i = CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1; i >= cx ; --i) { |
1254 | RowFormat** cl = m_cluster[ i ]; |
1255 | if (cl) { |
1256 | int left = 0; |
1257 | if (i == cx) |
1258 | left = dx; |
1259 | int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
1260 | if (i == CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) |
1261 | right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 2; |
1262 | for (int k = right; k >= left; --k) { |
1263 | RowFormat* c = cl[ k ]; |
1264 | if (c) { |
1265 | removeElement(c->row()); |
1266 | c->setRow(c->row() + 1); |
1267 | insertElement(c, c->row()); |
1268 | } |
1269 | } |
1270 | } |
1271 | } |
1272 | |
1273 | setAutoDelete(a); |
1274 | |
1275 | return true; |
1276 | } |
1277 | |
1278 | bool RowCluster::removeRow(int row) |
1279 | { |
1280 | if (row >= CALLIGRA_SHEETS_CLUSTER_MAX || row < 0) { |
1281 | kDebug(36001) << "RowCluster::removeRow: invalid row value (row:" |
1282 | << row << ")" << endl; |
1283 | return false; |
1284 | } |
1285 | |
1286 | int cx = row / CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1287 | int dx = row % CALLIGRA_SHEETS_CLUSTER_LEVEL2; |
1288 | |
1289 | removeElement(row); |
1290 | |
1291 | bool a = autoDelete(); |
1292 | setAutoDelete(false); |
1293 | |
1294 | for (int i = cx; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { |
1295 | RowFormat** cl = m_cluster[ i ]; |
1296 | if (cl) { |
1297 | int left = 0; |
1298 | if (i == cx) |
1299 | left = dx + 1; |
1300 | int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; |
1301 | for (int k = left; k <= right; ++k) { |
1302 | RowFormat* c = cl[ k ]; |
1303 | if (c) { |
1304 | removeElement(c->row()); |
1305 | c->setRow(c->row() - 1); |
1306 | insertElement(c, c->row()); |
1307 | } |
1308 | } |
1309 | } |
1310 | } |
1311 | |
1312 | setAutoDelete(a); |
1313 | |
1314 | return true; |
1315 | } |
1316 | |
1317 | void RowCluster::setAutoDelete(bool a) |
1318 | { |
1319 | m_autoDelete = a; |
1320 | } |
1321 | |
1322 | bool RowCluster::autoDelete() const |
1323 | { |
1324 | return m_autoDelete; |
1325 | } |
1326 | |
1327 | void RowCluster::operator=(const RowCluster & other) |
1328 | { |
1329 | m_first = 0; |
1330 | m_autoDelete = other.m_autoDelete; |
1331 | // TODO Stefan: Optimize! |
1332 | m_cluster = (RowFormat***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(RowFormat**)); |
1333 | for (int i = 0; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { |
1334 | if (other.m_cluster[i]) { |
1335 | m_cluster[i] = (RowFormat**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(RowFormat*)); |
1336 | for (int j = 0; j < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++j) { |
1337 | m_cluster[i][j] = 0; |
1338 | if (other.m_cluster[i][j]) { |
1339 | RowFormat* rowFormat = new RowFormat(*other.m_cluster[i][j]); |
1340 | rowFormat->setNext(0); |
1341 | rowFormat->setPrevious(0); |
1342 | insertElement(rowFormat, rowFormat->row()); |
1343 | } |
1344 | } |
1345 | } else |
1346 | m_cluster[i] = 0; |
1347 | } |
1348 | } |
1349 | |