kspread

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