kspread

kspread_cluster.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
00003    Copyright (C) 2000 Torben Weis <weis@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <stdlib.h>
00022 
00023 #include <kdebug.h>
00024 
00025 #include "kspread_cell.h"
00026 #include "kspread_format.h"
00027 
00028 #include "kspread_cluster.h"
00029 
00030 using namespace KSpread;
00031 
00032 /****************************************************
00033  *
00034  * Cluster
00035  *
00036  ****************************************************/
00037 
00038 /* Generate a matrix LEVEL1 with the size LEVEL1*LEVEL1 */
00039 Cluster::Cluster()
00040     : m_first( 0 ), m_autoDelete( false ), m_biggestX(0), m_biggestY(0)
00041 {
00042     m_cluster = (Cell***)malloc( KSPREAD_CLUSTER_LEVEL1 * KSPREAD_CLUSTER_LEVEL1 * sizeof( Cell** ) );
00043 
00044     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
00045     for( int y = 0; y < KSPREAD_CLUSTER_LEVEL1; ++y )
00046         m_cluster[ y * KSPREAD_CLUSTER_LEVEL1 + x ] = 0;
00047 }
00048 
00049 /* Delete the matrix LEVEL1 and all existing LEVEL2 matrizes */
00050 Cluster::~Cluster()
00051 {
00052 // Can't we use clear(), to remove double code - Philipp?
00053     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
00054     for( int y = 0; y < KSPREAD_CLUSTER_LEVEL1; ++y )
00055         {
00056         Cell** cl = m_cluster[ y * KSPREAD_CLUSTER_LEVEL1 + x ];
00057         if ( cl )
00058         {
00059         free( cl );
00060         m_cluster[ y * KSPREAD_CLUSTER_LEVEL1 + x ] = 0;
00061         }
00062     }
00063 
00064     if ( m_autoDelete )
00065     {
00066     Cell* cell = m_first;
00067     while( cell )
00068         {
00069         Cell* n = cell->nextCell();
00070         delete cell;
00071         cell = n;
00072     }
00073     }
00074 
00075     free( m_cluster );
00076 }
00077 
00078 void Cluster::clear()
00079 {
00080     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
00081     for( int y = 0; y < KSPREAD_CLUSTER_LEVEL1; ++y )
00082         {
00083         Cell** cl = m_cluster[ y * KSPREAD_CLUSTER_LEVEL1 + x ];
00084         if ( cl )
00085         {
00086         free( cl );
00087         m_cluster[ y * KSPREAD_CLUSTER_LEVEL1 + x ] = 0;
00088         }
00089     }
00090 
00091     if ( m_autoDelete )
00092     {
00093     Cell* cell = m_first;
00094     while( cell )
00095         {
00096         Cell* n = cell->nextCell();
00097         delete cell;
00098         cell = n;
00099     }
00100     }
00101 
00102     m_first = 0;
00103     m_biggestX = m_biggestY = 0;
00104 }
00105 
00106 Cell* Cluster::lookup( int x, int y ) const
00107 {
00108     if ( x >= KSPREAD_CLUSTER_MAX || x < 0 || y >= KSPREAD_CLUSTER_MAX || y < 0 )
00109     {
00110     kdDebug(36001) << "Cluster::lookup: invalid column or row value (col: "
00111                << x << "  | row: " << y << ")" << endl;
00112     return 0;
00113     }
00114     int cx = x / KSPREAD_CLUSTER_LEVEL2;
00115     int cy = y / KSPREAD_CLUSTER_LEVEL2;
00116     int dx = x % KSPREAD_CLUSTER_LEVEL2;
00117     int dy = y % KSPREAD_CLUSTER_LEVEL2;
00118 
00119     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ];
00120     if ( !cl )
00121     return 0;
00122 
00123     return cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ];
00124 }
00125 
00126 /* Paste a cell in LEVEL2 (it's more paste than insert) */
00127 void Cluster::insert( Cell* cell, int x, int y )
00128 {
00129     if ( x >= KSPREAD_CLUSTER_MAX || x < 0 || y >= KSPREAD_CLUSTER_MAX || y < 0 )
00130     {
00131     kdDebug(36001) << "Cluster::insert: invalid column or row value (col: "
00132                << x << "  | row: " << y << ")" << endl;
00133     return;
00134     }
00135 
00136     int cx = x / KSPREAD_CLUSTER_LEVEL2;
00137     int cy = y / KSPREAD_CLUSTER_LEVEL2;
00138     int dx = x % KSPREAD_CLUSTER_LEVEL2;
00139     int dy = y % KSPREAD_CLUSTER_LEVEL2;
00140 
00141     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ];
00142     if ( !cl )
00143     {
00144     cl = (Cell**)malloc(  KSPREAD_CLUSTER_LEVEL2 * KSPREAD_CLUSTER_LEVEL2 * sizeof( Cell*  ) );
00145     m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ] = cl;
00146 
00147     for( int a = 0; a < KSPREAD_CLUSTER_LEVEL2; ++a )
00148         for( int b = 0; b < KSPREAD_CLUSTER_LEVEL2; ++b )
00149         cl[ b * KSPREAD_CLUSTER_LEVEL2 + a ] = 0;
00150     }
00151 
00152     if ( cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ] )
00153     remove( x, y );
00154 
00155     cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ] = cell;
00156 
00157     if ( m_first )
00158     {
00159     cell->setNextCell( m_first );
00160     m_first->setPreviousCell( cell );
00161     }
00162     m_first = cell;
00163 
00164     if (x > m_biggestX) m_biggestX = x;
00165     if (y > m_biggestY) m_biggestY = y;
00166 }
00167 
00168 /* Removes the cell of a matrix, the matrix itself keeps unchanged */
00169 void Cluster::remove( int x, int y )
00170 {
00171     if ( x >= KSPREAD_CLUSTER_MAX || x < 0 || y >= KSPREAD_CLUSTER_MAX || y < 0 )
00172     {
00173     kdDebug(36001) << "Cluster::remove: invalid column or row value (col: "
00174                << x << "  | row: " << y << ")" << endl;
00175     return;
00176     }
00177 
00178     int cx = x / KSPREAD_CLUSTER_LEVEL2;
00179     int cy = y / KSPREAD_CLUSTER_LEVEL2;
00180     int dx = x % KSPREAD_CLUSTER_LEVEL2;
00181     int dy = y % KSPREAD_CLUSTER_LEVEL2;
00182 
00183     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ];
00184     if ( !cl )
00185     return;
00186 
00187     Cell* c = cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ];
00188     if ( !c )
00189     return;
00190 
00191     cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ] = 0;
00192 
00193     if ( m_autoDelete )
00194     {
00195     if ( m_first == c )
00196         m_first = c->nextCell();
00197         if(c->doesMergeCells())
00198         {
00199         c->mergeCells(c->column(),c->row(),0,0);
00200         }
00201     delete c;
00202     }
00203     else
00204     {
00205     if ( m_first == c )
00206         m_first = c->nextCell();
00207     if ( c->previousCell() )
00208         c->previousCell()->setNextCell( c->nextCell() );
00209     if ( c->nextCell() )
00210         c->nextCell()->setPreviousCell( c->previousCell() );
00211     c->setNextCell( 0 );
00212     c->setPreviousCell( 0 );
00213     }
00214 }
00215 
00216 bool Cluster::shiftRow( const QPoint& marker )
00217 {
00218     bool dummy;
00219     return shiftRow( marker, dummy );
00220 }
00221 
00222 bool Cluster::shiftColumn( const QPoint& marker )
00223 {
00224     bool dummy;
00225     return shiftColumn( marker, dummy );
00226 }
00227 
00228 void Cluster::unshiftColumn( const QPoint& marker )
00229 {
00230     bool dummy;
00231     unshiftColumn( marker, dummy );
00232 }
00233 
00234 void Cluster::unshiftRow( const QPoint& marker )
00235 {
00236     bool dummy;
00237     unshiftRow( marker, dummy );
00238 }
00239 
00240 void Cluster::setAutoDelete( bool b )
00241 {
00242     m_autoDelete = b;
00243 }
00244 
00245 bool Cluster::autoDelete() const
00246 {
00247     return m_autoDelete;
00248 }
00249 
00250 Cell* Cluster::firstCell() const
00251 {
00252     return m_first;
00253 }
00254 
00255 bool Cluster::shiftRow( const QPoint& marker, bool& work )
00256 {
00257     work = false;
00258 
00259     if ( marker.x() >= KSPREAD_CLUSTER_MAX || marker.x() < 0 ||
00260      marker.y() >= KSPREAD_CLUSTER_MAX || marker.y() < 0 )
00261     {
00262     kdDebug(36001) << "Cluster::shiftRow: invalid column or row value (col: "
00263                << marker.x() << "  | row: " << marker.y() << ")" << endl;
00264     return false;
00265     }
00266 
00267     int cx = marker.x() / KSPREAD_CLUSTER_LEVEL2;
00268     int cy = marker.y() / KSPREAD_CLUSTER_LEVEL2;
00269     int dx = marker.x() % KSPREAD_CLUSTER_LEVEL2;
00270     int dy = marker.y() % KSPREAD_CLUSTER_LEVEL2;
00271 
00272     // Is there a cell at the bottom most position ?
00273     // In this case the shift is impossible.
00274     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + KSPREAD_CLUSTER_LEVEL1 - 1 ];
00275     if ( cl && cl[ dy * KSPREAD_CLUSTER_LEVEL2 + KSPREAD_CLUSTER_LEVEL2 - 1 ] )
00276     return false;
00277 
00278     bool a = autoDelete();
00279     setAutoDelete( false );
00280 
00281     // Move cells in this row one down.
00282     for( int i = KSPREAD_CLUSTER_LEVEL1 - 1; i >= cx ; --i )
00283     {
00284     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + i ];
00285     if ( cl )
00286         {
00287         work = true;
00288         int left = 0;
00289         if ( i == cx )
00290         left = dx;
00291         int right = KSPREAD_CLUSTER_LEVEL2 - 1;
00292         if ( i == KSPREAD_CLUSTER_LEVEL1 - 1 )
00293         right = KSPREAD_CLUSTER_LEVEL2 - 2;
00294         for( int k = right; k >= left; --k )
00295         {
00296         Cell* c = cl[ dy * KSPREAD_CLUSTER_LEVEL2 + k ];
00297         if ( c )
00298             {
00299             remove( c->column(), c->row() );
00300             c->move( c->column() + 1, c->row() );
00301             insert( c, c->column(), c->row() );
00302         }
00303         }
00304     }
00305     }
00306 
00307     setAutoDelete( a );
00308 
00309     return true;
00310 }
00311 
00312 bool Cluster::shiftColumn( const QPoint& marker, bool& work )
00313 {
00314     work = false;
00315 
00316     if ( marker.x() >= KSPREAD_CLUSTER_MAX || marker.x() < 0 ||
00317      marker.y() >= KSPREAD_CLUSTER_MAX || marker.y() < 0 )
00318     {
00319     kdDebug(36001) << "Cluster::shiftColumn: invalid column or row value (col: "
00320                << marker.x() << "  | row: " << marker.y() << ")" << endl;
00321     return false;
00322     }
00323 
00324     int cx = marker.x() / KSPREAD_CLUSTER_LEVEL2;
00325     int cy = marker.y() / KSPREAD_CLUSTER_LEVEL2;
00326     int dx = marker.x() % KSPREAD_CLUSTER_LEVEL2;
00327     int dy = marker.y() % KSPREAD_CLUSTER_LEVEL2;
00328 
00329     // Is there a cell at the right most position ?
00330     // In this case the shift is impossible.
00331     Cell** cl = m_cluster[ KSPREAD_CLUSTER_LEVEL1 * ( KSPREAD_CLUSTER_LEVEL1 - 1 ) + cx ];
00332     if ( cl && cl[ KSPREAD_CLUSTER_LEVEL2 * ( KSPREAD_CLUSTER_LEVEL2 - 1 ) + dx ] )
00333     return false;
00334 
00335     bool a = autoDelete();
00336     setAutoDelete( false );
00337 
00338     // Move cells in this column one right.
00339     for( int i = KSPREAD_CLUSTER_LEVEL1 - 1; i >= cy ; --i )
00340     {
00341     Cell** cl = m_cluster[ i * KSPREAD_CLUSTER_LEVEL1 + cx ];
00342     if ( cl )
00343         {
00344         work = true;
00345 
00346         int top = 0;
00347         if ( i == cy )
00348         top = dy;
00349         int bottom = KSPREAD_CLUSTER_LEVEL2 - 1;
00350         if ( i == KSPREAD_CLUSTER_LEVEL1 - 1 )
00351         bottom = KSPREAD_CLUSTER_LEVEL2 - 2;
00352         for( int k = bottom; k >= top; --k )
00353         {
00354         Cell* c = cl[ k * KSPREAD_CLUSTER_LEVEL2 + dx ];
00355         if ( c )
00356             {
00357             remove( c->column(), c->row() );
00358             c->move( c->column(), c->row() + 1 );
00359             insert( c, c->column(), c->row() );
00360         }
00361         }
00362     }
00363     }
00364 
00365     setAutoDelete( a );
00366 
00367     return true;
00368 }
00369 
00370 bool Cluster::insertColumn( int col )
00371 {
00372     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00373     {
00374     kdDebug(36001) << "Cluster::insertColumn: invalid column value (col: "
00375                << col << ")" << endl;
00376     return false;
00377     }
00378 
00379     // Is there a cell at the right most position ?
00380     // In this case the shift is impossible.
00381     for( int t1 = 0; t1 < KSPREAD_CLUSTER_LEVEL1; ++t1 )
00382     {
00383     Cell** cl = m_cluster[ t1 * KSPREAD_CLUSTER_LEVEL1 + KSPREAD_CLUSTER_LEVEL1 - 1 ];
00384     if ( cl )
00385         for( int t2 = 0; t2 < KSPREAD_CLUSTER_LEVEL2; ++t2 )
00386         if ( cl[ t2 * KSPREAD_CLUSTER_LEVEL2 + KSPREAD_CLUSTER_LEVEL2 - 1 ] )
00387             return false;
00388     }
00389 
00390     for( int t1 = 0; t1 < KSPREAD_CLUSTER_LEVEL1; ++t1 )
00391     {
00392     bool work = true;
00393     for( int t2 = 0; work && t2 < KSPREAD_CLUSTER_LEVEL2; ++t2 )
00394         shiftRow( QPoint( col, t1 * KSPREAD_CLUSTER_LEVEL2 + t2 ), work );
00395     }
00396 
00397     return true;
00398 }
00399 
00400 bool Cluster::insertRow( int row )
00401 {
00402     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
00403     {
00404     kdDebug(36001) << "Cluster::insertRow: invalid row value (row: "
00405                << row << ")" << endl;
00406     return false;
00407     }
00408 
00409     // Is there a cell at the bottom most position ?
00410     // In this case the shift is impossible.
00411     for( int t1 = 0; t1 < KSPREAD_CLUSTER_LEVEL1; ++t1 )
00412     {
00413     Cell** cl = m_cluster[ KSPREAD_CLUSTER_LEVEL1 * ( KSPREAD_CLUSTER_LEVEL1 - 1 ) + t1 ];
00414     if ( cl )
00415         for( int t2 = 0; t2 < KSPREAD_CLUSTER_LEVEL2; ++t2 )
00416         if ( cl[ KSPREAD_CLUSTER_LEVEL2 * ( KSPREAD_CLUSTER_LEVEL2 - 1 ) + t2 ] )
00417             return false;
00418     }
00419 
00420     for( int t1 = 0; t1 < KSPREAD_CLUSTER_LEVEL1; ++t1 )
00421     {
00422     bool work = true;
00423     for( int t2 = 0; work && t2 < KSPREAD_CLUSTER_LEVEL2; ++t2 )
00424         shiftColumn( QPoint( t1 * KSPREAD_CLUSTER_LEVEL2 + t2, row ), work );
00425     }
00426 
00427     return true;
00428 }
00429 
00430 void Cluster::unshiftColumn( const QPoint& marker, bool& work )
00431 {
00432     work = false;
00433 
00434     if ( marker.x() >= KSPREAD_CLUSTER_MAX || marker.x() < 0 ||
00435      marker.y() >= KSPREAD_CLUSTER_MAX || marker.y() < 0 )
00436     {
00437     kdDebug(36001) << "Cluster::unshiftColumn: invalid column or row value (col: "
00438                << marker.x() << "  | row: " << marker.y() << ")" << endl;
00439     return;
00440     }
00441 
00442     int cx = marker.x() / KSPREAD_CLUSTER_LEVEL2;
00443     int cy = marker.y() / KSPREAD_CLUSTER_LEVEL2;
00444     int dx = marker.x() % KSPREAD_CLUSTER_LEVEL2;
00445     int dy = marker.y() % KSPREAD_CLUSTER_LEVEL2;
00446 
00447     bool a = autoDelete();
00448     setAutoDelete( false );
00449 
00450     // Move cells in this column one column to the left.
00451     for( int i = cy; i < KSPREAD_CLUSTER_LEVEL1; ++i )
00452     {
00453     Cell** cl = m_cluster[ i * KSPREAD_CLUSTER_LEVEL1 + cx ];
00454     if ( cl )
00455         {
00456         work = true;
00457 
00458         int top = 0;
00459         if ( i == cy )
00460         top = dy + 1;
00461         int bottom = KSPREAD_CLUSTER_LEVEL2 - 1;
00462         for( int k = top; k <= bottom; ++k )
00463         {
00464         Cell* c = cl[ k * KSPREAD_CLUSTER_LEVEL2 + dx ];
00465         if ( c )
00466             {
00467             remove( c->column(), c->row() );
00468             c->move( c->column(), c->row() - 1 );
00469             insert( c, c->column(), c->row() );
00470         }
00471         }
00472     }
00473     }
00474 
00475     setAutoDelete( a );
00476 }
00477 
00478 void Cluster::unshiftRow( const QPoint& marker, bool& work )
00479 {
00480     work = false;
00481 
00482     if ( marker.x() >= KSPREAD_CLUSTER_MAX || marker.x() < 0 ||
00483      marker.y() >= KSPREAD_CLUSTER_MAX || marker.y() < 0 )
00484     {
00485     kdDebug(36001) << "Cluster::unshiftRow: invalid column or row value (col: "
00486                << marker.x() << "  | row: " << marker.y() << ")" << endl;
00487     return;
00488     }
00489 
00490     int cx = marker.x() / KSPREAD_CLUSTER_LEVEL2;
00491     int cy = marker.y() / KSPREAD_CLUSTER_LEVEL2;
00492     int dx = marker.x() % KSPREAD_CLUSTER_LEVEL2;
00493     int dy = marker.y() % KSPREAD_CLUSTER_LEVEL2;
00494 
00495     bool a = autoDelete();
00496     setAutoDelete( false );
00497 
00498     // Move cells in this row one row up.
00499     for( int i = cx; i < KSPREAD_CLUSTER_LEVEL1; ++i )
00500     {
00501     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + i ];
00502     if ( cl )
00503         {
00504         work = true;
00505 
00506         int left = 0;
00507         if ( i == cx )
00508         left = dx + 1;
00509         int right = KSPREAD_CLUSTER_LEVEL2 - 1;
00510         for( int k = left; k <= right; ++k )
00511         {
00512         Cell* c = cl[ dy * KSPREAD_CLUSTER_LEVEL2 + k ];
00513         if ( c )
00514             {
00515             remove( c->column(), c->row() );
00516             c->move( c->column() - 1, c->row() );
00517             insert( c, c->column(), c->row() );
00518         }
00519         }
00520     }
00521     }
00522 
00523     setAutoDelete( a );
00524 }
00525 
00526 void Cluster::removeColumn( int col )
00527 {
00528     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00529     {
00530     kdDebug(36001) << "Cluster::removeColumn: invalid column value (col: "
00531                << col << ")" << endl;
00532     return;
00533     }
00534 
00535     int cx = col / KSPREAD_CLUSTER_LEVEL2;
00536     int dx = col % KSPREAD_CLUSTER_LEVEL2;
00537 
00538     for( int y1 = 0; y1 < KSPREAD_CLUSTER_LEVEL1; ++y1 )
00539     {
00540     Cell** cl = m_cluster[ y1 * KSPREAD_CLUSTER_LEVEL1 + cx ];
00541     if ( cl )
00542         for( int y2 = 0; y2 < KSPREAD_CLUSTER_LEVEL2; ++y2 )
00543         if ( cl[ y2 * KSPREAD_CLUSTER_LEVEL2 + dx ] )
00544             remove( col, y1 * KSPREAD_CLUSTER_LEVEL1 + y2 );
00545     }
00546 
00547     for( int t1 = 0; t1 < KSPREAD_CLUSTER_LEVEL1; ++t1 )
00548     {
00549     bool work = true;
00550     for( int t2 = 0; work && t2 < KSPREAD_CLUSTER_LEVEL2; ++t2 )
00551         unshiftRow( QPoint( col, t1 * KSPREAD_CLUSTER_LEVEL2 + t2 ), work );
00552     }
00553 }
00554 
00555 void Cluster::removeRow( int row )
00556 {
00557     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
00558     {
00559     kdDebug(36001) << "Cluster::removeRow: invalid row value (row: "
00560                << row << ")" << endl;
00561     return;
00562     }
00563 
00564     int cy = row / KSPREAD_CLUSTER_LEVEL2;
00565     int dy = row % KSPREAD_CLUSTER_LEVEL2;
00566 
00567     for( int x1 = 0; x1 < KSPREAD_CLUSTER_LEVEL1; ++x1 )
00568     {
00569     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + x1 ];
00570     if ( cl )
00571         for( int x2 = 0; x2 < KSPREAD_CLUSTER_LEVEL2; ++x2 )
00572         if ( cl[ dy * KSPREAD_CLUSTER_LEVEL2 + x2 ] )
00573             remove( x1 * KSPREAD_CLUSTER_LEVEL2 + x2, row );
00574     }
00575 
00576     for( int t1 = 0; t1 < KSPREAD_CLUSTER_LEVEL1; ++t1 )
00577     {
00578     bool work = true;
00579     for( int t2 = 0; work && t2 < KSPREAD_CLUSTER_LEVEL2; ++t2 )
00580         unshiftColumn( QPoint( t1 * KSPREAD_CLUSTER_LEVEL2 + t2, row ), work );
00581     }
00582 }
00583 
00584 void Cluster::clearColumn( int col )
00585 {
00586   if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00587   {
00588     kdDebug(36001) << "Cluster::clearColumn: invalid column value (col: "
00589     << col << ")" << endl;
00590     return;
00591   }
00592 
00593   int cx = col / KSPREAD_CLUSTER_LEVEL2;
00594   int dx = col % KSPREAD_CLUSTER_LEVEL2;
00595 
00596   for( int cy = 0; cy < KSPREAD_CLUSTER_LEVEL1; ++cy )
00597   {
00598     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ];
00599     if ( cl )
00600       for( int dy = 0; dy < KSPREAD_CLUSTER_LEVEL2; ++dy )
00601         if ( cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ] )
00602         {
00603           int row = cy * KSPREAD_CLUSTER_LEVEL2 + dy ;
00604           remove( col, row );
00605         }
00606   }
00607 }
00608 
00609 void Cluster::clearRow( int row )
00610 {
00611   if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
00612   {
00613     kdDebug(36001) << "Cluster::clearRow: invalid row value (row: "
00614         << row << ")" << endl;
00615     return;
00616   }
00617 
00618   int cy = row / KSPREAD_CLUSTER_LEVEL2;
00619   int dy = row % KSPREAD_CLUSTER_LEVEL2;
00620 
00621   for( int cx = 0; cx < KSPREAD_CLUSTER_LEVEL1; ++cx )
00622   {
00623     Cell** cl = m_cluster[ cy * KSPREAD_CLUSTER_LEVEL2 + cx ];
00624     if ( cl )
00625       for( int dx = 0; dx < KSPREAD_CLUSTER_LEVEL2; ++dx )
00626         if ( cl[ dy * KSPREAD_CLUSTER_LEVEL2 + dx ] )
00627         {
00628           int column = cx * KSPREAD_CLUSTER_LEVEL2 + dx ;
00629           remove( column, row );
00630         }
00631   }
00632 }
00633 
00634 Value Cluster::valueRange (int col1, int row1,
00635     int col2, int row2) const
00636 {
00637   Value empty;
00638 
00639   //swap first/second values if needed
00640   if (col1 > col2)
00641   {
00642     int p = col1; col1 = col2; col2 = p;
00643   }
00644   if (row1 > row2)
00645   {
00646     int p = row1; row1 = col2; row2 = p;
00647   }
00648   if ((row1 < 0) || (col1 < 0) || (row2 > KSPREAD_CLUSTER_MAX) ||
00649       (col2 > KSPREAD_CLUSTER_MAX))
00650     return empty;
00651 
00652   // if we are out of range occupied by cells, we return an empty
00653   // array of the requested size
00654   if ((row1 > m_biggestY) || (col1 > m_biggestX))
00655   {
00656     int cols = col2 - col1 + 1;
00657     int rows = row2 - row1 + 1;
00658     Value array (cols, rows);
00659     return array;
00660   }
00661 
00662   return makeArray (col1, row1, col2, row2);
00663 }
00664 
00665 Value Cluster::makeArray (int col1, int row1,
00666     int col2, int row2) const
00667 {
00668   // this generates an array of values
00669   // TODO: make this thing faster by skipping empty regions
00670   int cols = col2 - col1 + 1;
00671   int rows = row2 - row1 + 1;
00672   Value array (cols, rows);
00673   for (int row = row1; row <= row2; ++row)
00674     for (int col = col1; col <= col2; ++col)
00675     {
00676       Cell *cell = lookup (col, row);
00677       if (cell)
00678       {
00679         Value val = cell->value();
00680         array.setElement (col-col1, row-row1, val);
00681       }
00682     }
00683 
00684   //return the result
00685   return array;
00686 }
00687 
00688 Cell* Cluster::getFirstCellColumn(int col) const
00689 {
00690   Cell* cell = lookup(col, 1);
00691 
00692   if (cell == NULL)
00693   {
00694     cell = getNextCellDown(col, 1);
00695   }
00696   return cell;
00697 }
00698 
00699 Cell* Cluster::getLastCellColumn(int col) const
00700 {
00701   Cell* cell = lookup(col, KS_rowMax);
00702 
00703   if (cell == NULL)
00704   {
00705     cell = getNextCellUp(col, KS_rowMax);
00706   }
00707   return cell;
00708 }
00709 
00710 Cell* Cluster::getFirstCellRow(int row) const
00711 {
00712   Cell* cell = lookup(1, row);
00713 
00714   if (cell == NULL)
00715   {
00716     cell = getNextCellRight(1, row);
00717   }
00718   return cell;
00719 }
00720 
00721 Cell* Cluster::getLastCellRow(int row) const
00722 {
00723   Cell* cell = lookup(KS_colMax, row);
00724 
00725   if (cell == NULL)
00726   {
00727     cell = getNextCellLeft(KS_colMax, row);
00728   }
00729   return cell;
00730 }
00731 
00732 Cell* Cluster::getNextCellUp(int col, int row) const
00733 {
00734   int cx = col / KSPREAD_CLUSTER_LEVEL2;
00735   int cy = (row - 1) / KSPREAD_CLUSTER_LEVEL2;
00736   int dx = col % KSPREAD_CLUSTER_LEVEL2;
00737   int dy = (row - 1) % KSPREAD_CLUSTER_LEVEL2;
00738 
00739   while (cy >= 0)
00740   {
00741     if ( m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ] != NULL )
00742     {
00743       while (dy >= 0)
00744       {
00745 
00746         if ( m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx]
00747              [ dy*KSPREAD_CLUSTER_LEVEL2 + dx] != NULL )
00748         {
00749           return m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx ]
00750             [ dy*KSPREAD_CLUSTER_LEVEL2 + dx];
00751         }
00752         dy--;
00753       }
00754     }
00755     cy--;
00756     dy = KSPREAD_CLUSTER_LEVEL2 - 1;
00757   }
00758   return NULL;
00759 }
00760 
00761 Cell* Cluster::getNextCellDown(int col, int row) const
00762 {
00763   int cx = col / KSPREAD_CLUSTER_LEVEL2;
00764   int cy = (row + 1) / KSPREAD_CLUSTER_LEVEL2;
00765   int dx = col % KSPREAD_CLUSTER_LEVEL2;
00766   int dy = (row + 1) % KSPREAD_CLUSTER_LEVEL2;
00767 
00768   while (cy < KSPREAD_CLUSTER_LEVEL1)
00769   {
00770     if ( m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ] != NULL )
00771     {
00772       while (dy < KSPREAD_CLUSTER_LEVEL2)
00773       {
00774 
00775         if ( m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx]
00776              [ dy*KSPREAD_CLUSTER_LEVEL2 + dx] != NULL )
00777         {
00778           return m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx ]
00779             [ dy*KSPREAD_CLUSTER_LEVEL2 + dx];
00780         }
00781         dy++;
00782       }
00783     }
00784     cy++;
00785     dy = 0;
00786   }
00787   return NULL;
00788 }
00789 
00790 Cell* Cluster::getNextCellLeft(int col, int row) const
00791 {
00792   int cx = (col - 1) / KSPREAD_CLUSTER_LEVEL2;
00793   int cy = row / KSPREAD_CLUSTER_LEVEL2;
00794   int dx = (col - 1) % KSPREAD_CLUSTER_LEVEL2;
00795   int dy = row % KSPREAD_CLUSTER_LEVEL2;
00796 
00797   while (cx >= 0)
00798   {
00799     if ( m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ] != NULL )
00800     {
00801       while (dx >= 0)
00802       {
00803 
00804         if ( m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx]
00805              [ dy*KSPREAD_CLUSTER_LEVEL2 + dx] != NULL )
00806         {
00807           return m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx ]
00808             [ dy*KSPREAD_CLUSTER_LEVEL2 + dx];
00809         }
00810         dx--;
00811       }
00812     }
00813     cx--;
00814     dx = KSPREAD_CLUSTER_LEVEL2 - 1;
00815   }
00816   return NULL;
00817 }
00818 
00819 Cell* Cluster::getNextCellRight(int col, int row) const
00820 {
00821   int cx = (col + 1) / KSPREAD_CLUSTER_LEVEL2;
00822   int cy = row / KSPREAD_CLUSTER_LEVEL2;
00823   int dx = (col + 1) % KSPREAD_CLUSTER_LEVEL2;
00824   int dy = row % KSPREAD_CLUSTER_LEVEL2;
00825 
00826   while (cx < KSPREAD_CLUSTER_LEVEL1)
00827   {
00828     if ( m_cluster[ cy * KSPREAD_CLUSTER_LEVEL1 + cx ] != NULL )
00829     {
00830       while (dx < KSPREAD_CLUSTER_LEVEL2)
00831       {
00832 
00833         if ( m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx]
00834              [ dy*KSPREAD_CLUSTER_LEVEL2 + dx] != NULL )
00835         {
00836           return m_cluster[ cy*KSPREAD_CLUSTER_LEVEL1 + cx ]
00837             [ dy*KSPREAD_CLUSTER_LEVEL2 + dx];
00838         }
00839         dx++;
00840       }
00841     }
00842     cx++;
00843     dx = 0;
00844   }
00845   return NULL;
00846 }
00847 
00848 /****************************************************
00849  *
00850  * ColumnCluster
00851  *
00852  ****************************************************/
00853 
00854 ColumnCluster::ColumnCluster()
00855     : m_first( 0 ), m_autoDelete( false )
00856 {
00857     m_cluster = (ColumnFormat***)malloc( KSPREAD_CLUSTER_LEVEL1 * sizeof( ColumnFormat** ) );
00858 
00859     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
00860     m_cluster[ x ] = 0;
00861 }
00862 
00863 ColumnCluster::~ColumnCluster()
00864 {
00865     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
00866     {
00867     ColumnFormat** cl = m_cluster[ x ];
00868     if ( cl )
00869         {
00870         free( cl );
00871         m_cluster[ x ] = 0;
00872     }
00873     }
00874 
00875     if ( m_autoDelete )
00876     {
00877     ColumnFormat* cell = m_first;
00878     while( cell )
00879         {
00880         ColumnFormat* n = cell->next();
00881         delete cell;
00882         cell = n;
00883     }
00884     }
00885 
00886 
00887     free( m_cluster );
00888 }
00889 
00890 ColumnFormat* ColumnCluster::lookup( int col )
00891 {
00892     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00893     {
00894     kdDebug(36001) << "ColumnCluster::lookup: invalid column value (col: "
00895                << col << ")" << endl;
00896     return 0;
00897     }
00898 
00899     int cx = col / KSPREAD_CLUSTER_LEVEL2;
00900     int dx = col % KSPREAD_CLUSTER_LEVEL2;
00901 
00902     ColumnFormat** cl = m_cluster[ cx ];
00903     if ( !cl )
00904     return 0;
00905 
00906     return cl[ dx ];
00907 }
00908 
00909 const ColumnFormat* ColumnCluster::lookup( int col ) const
00910 {
00911     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00912     {
00913     kdDebug(36001) << "ColumnCluster::lookup: invalid column value (col: "
00914                << col << ")" << endl;
00915     return 0;
00916     }
00917 
00918     int cx = col / KSPREAD_CLUSTER_LEVEL2;
00919     int dx = col % KSPREAD_CLUSTER_LEVEL2;
00920 
00921     ColumnFormat** cl = m_cluster[ cx ];
00922     if ( !cl )
00923     return 0;
00924 
00925     return cl[ dx ];
00926 }
00927 
00928 void ColumnCluster::clear()
00929 {
00930     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
00931     {
00932     ColumnFormat** cl = m_cluster[ x ];
00933     if ( cl )
00934         {
00935         free( cl );
00936         m_cluster[ x ] = 0;
00937     }
00938     }
00939 
00940     if ( m_autoDelete )
00941     {
00942     ColumnFormat* cell = m_first;
00943     while( cell )
00944         {
00945         ColumnFormat* n = cell->next();
00946         delete cell;
00947         cell = n;
00948     }
00949     }
00950 
00951     m_first = 0;
00952 }
00953 
00954 void ColumnCluster::insertElement( ColumnFormat* lay, int col )
00955 {
00956     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00957     {
00958     kdDebug(36001) << "ColumnCluster::insertElement: invalid column value (col: "
00959                << col << ")" << endl;
00960     return;
00961     }
00962 
00963     int cx = col / KSPREAD_CLUSTER_LEVEL2;
00964     int dx = col % KSPREAD_CLUSTER_LEVEL2;
00965 
00966     ColumnFormat** cl = m_cluster[ cx ];
00967     if ( !cl )
00968     {
00969     cl = (ColumnFormat**)malloc( KSPREAD_CLUSTER_LEVEL2 * sizeof( ColumnFormat*  ) );
00970     m_cluster[ cx ] = cl;
00971 
00972     for( int a = 0; a < KSPREAD_CLUSTER_LEVEL2; ++a )
00973         cl[ a ] = 0;
00974     }
00975 
00976     if ( cl[ dx ] )
00977     removeElement( col );
00978 
00979     cl[ dx ] = lay;
00980 
00981     if ( m_first )
00982     {
00983     lay->setNext( m_first );
00984     m_first->setPrevious( lay );
00985     }
00986     m_first = lay;
00987 }
00988 
00989 void ColumnCluster::removeElement( int col )
00990 {
00991     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
00992     {
00993     kdDebug(36001) << "ColumnCluster::removeElement: invalid column value (col: "
00994                << col << ")" << endl;
00995     return;
00996     }
00997 
00998     int cx = col / KSPREAD_CLUSTER_LEVEL2;
00999     int dx = col % KSPREAD_CLUSTER_LEVEL2;
01000 
01001     ColumnFormat** cl = m_cluster[ cx ];
01002     if ( !cl )
01003     return;
01004 
01005     ColumnFormat* c = cl[ dx ];
01006     if ( !c )
01007     return;
01008 
01009     cl[ dx ] = 0;
01010 
01011     if ( m_autoDelete )
01012     {
01013     if ( m_first == c )
01014         m_first = c->next();
01015     delete c;
01016     }
01017     else
01018     {
01019     if ( m_first == c )
01020         m_first = c->next();
01021     if ( c->previous() )
01022         c->previous()->setNext( c->next() );
01023     if ( c->next() )
01024         c->next()->setPrevious( c->previous() );
01025     c->setNext( 0 );
01026     c->setPrevious( 0 );
01027     }
01028 }
01029 
01030 bool ColumnCluster::insertColumn( int col )
01031 {
01032     if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
01033     {
01034     kdDebug(36001) << "ColumnCluster::insertColumn: invalid column value (col: "
01035                << col << ")" << endl;
01036     return false;
01037     }
01038 
01039     int cx = col / KSPREAD_CLUSTER_LEVEL2;
01040     int dx = col % KSPREAD_CLUSTER_LEVEL2;
01041 
01042     // Is there a column layout at the right most position ?
01043     // In this case the shift is impossible.
01044     ColumnFormat** cl = m_cluster[ KSPREAD_CLUSTER_LEVEL1 - 1 ];
01045     if ( cl && cl[ KSPREAD_CLUSTER_LEVEL2 - 1 ] )
01046     return false;
01047 
01048     bool a = autoDelete();
01049     setAutoDelete( false );
01050 
01051     for( int i = KSPREAD_CLUSTER_LEVEL1 - 1; i >= cx ; --i )
01052     {
01053     ColumnFormat** cl = m_cluster[ i ];
01054     if ( cl )
01055         {
01056         int left = 0;
01057         if ( i == cx )
01058         left = dx;
01059         int right = KSPREAD_CLUSTER_LEVEL2 - 1;
01060         if ( i == KSPREAD_CLUSTER_LEVEL1 - 1 )
01061         right = KSPREAD_CLUSTER_LEVEL2 - 2;
01062         for( int k = right; k >= left; --k )
01063         {
01064         ColumnFormat* c = cl[ k ];
01065         if ( c )
01066             {
01067             removeElement( c->column() );
01068             c->setColumn( c->column() + 1 );
01069             insertElement( c, c->column() );
01070         }
01071         }
01072     }
01073     }
01074 
01075     setAutoDelete( a );
01076 
01077     return true;
01078 }
01079 
01080 bool ColumnCluster::removeColumn( int column )
01081 {
01082     if ( column >= KSPREAD_CLUSTER_MAX || column < 0 )
01083     {
01084     kdDebug(36001) << "ColumnCluster::removeColumn: invalid column value (col: "
01085                << column << ")" << endl;
01086     return false;
01087     }
01088 
01089     int cx = column / KSPREAD_CLUSTER_LEVEL2;
01090     int dx = column % KSPREAD_CLUSTER_LEVEL2;
01091 
01092     removeElement( column );
01093 
01094     bool a = autoDelete();
01095     setAutoDelete( false );
01096 
01097     for( int i = cx; i < KSPREAD_CLUSTER_LEVEL1; ++i )
01098     {
01099     ColumnFormat** cl = m_cluster[ i ];
01100     if ( cl )
01101         {
01102         int left = 0;
01103         if ( i == cx )
01104         left = dx + 1;
01105         int right = KSPREAD_CLUSTER_LEVEL2 - 1;
01106         for( int k = left; k <= right; ++k )
01107         {
01108         ColumnFormat* c = cl[ k ];
01109         if ( c )
01110             {
01111             removeElement( c->column() );
01112             c->setColumn( c->column() - 1 );
01113             insertElement( c, c->column() );
01114         }
01115         }
01116     }
01117     }
01118 
01119     setAutoDelete( a );
01120 
01121     return true;
01122 }
01123 
01124 void ColumnCluster::setAutoDelete( bool a )
01125 {
01126     m_autoDelete = a;
01127 }
01128 
01129 bool ColumnCluster::autoDelete() const
01130 {
01131     return m_autoDelete;
01132 }
01133 
01134 ColumnFormat* ColumnCluster::next( int col ) const
01135 {
01136   if ( col >= KSPREAD_CLUSTER_MAX || col < 0 )
01137   {
01138     kdDebug(36001) << "ColumnCluster::next: invalid column value (col: "
01139         << col << ")" << endl;
01140     return 0;
01141   }
01142 
01143   int cx = (col + 1) / KSPREAD_CLUSTER_LEVEL2;
01144   int dx = (col + 1) % KSPREAD_CLUSTER_LEVEL2;
01145 
01146   while ( cx < KSPREAD_CLUSTER_LEVEL1 )
01147   {
01148     if ( m_cluster[ cx ] )
01149     {
01150       while ( dx < KSPREAD_CLUSTER_LEVEL2 )
01151       {
01152 
01153         if ( m_cluster[ cx ][  dx ] )
01154         {
01155           return m_cluster[ cx ][ dx ];
01156         }
01157         ++dx;
01158       }
01159     }
01160     ++cx;
01161     dx = 0;
01162   }
01163   return 0;
01164 }
01165 
01166 /****************************************************
01167  *
01168  * RowCluster
01169  *
01170  ****************************************************/
01171 
01172 RowCluster::RowCluster()
01173     : m_first( 0 ), m_autoDelete( false )
01174 {
01175     m_cluster = (RowFormat***)malloc( KSPREAD_CLUSTER_LEVEL1 * sizeof( RowFormat** ) );
01176 
01177     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
01178         m_cluster[ x ] = 0;
01179 }
01180 
01181 RowCluster::~RowCluster()
01182 {
01183     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
01184     {
01185     RowFormat** cl = m_cluster[ x ];
01186     if ( cl )
01187         {
01188         free( cl );
01189         m_cluster[ x ] = 0;
01190     }
01191     }
01192 
01193     if ( m_autoDelete )
01194     {
01195     RowFormat* cell = m_first;
01196     while( cell )
01197         {
01198         RowFormat* n = cell->next();
01199         delete cell;
01200         cell = n;
01201     }
01202     }
01203 
01204     free( m_cluster );
01205 }
01206 
01207 const RowFormat* RowCluster::lookup( int row ) const
01208 {
01209     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01210     {
01211     kdDebug(36001) << "RowCluster::lookup: invalid row value (row: "
01212                << row << ")" << endl;
01213     return 0;
01214     }
01215 
01216     int cx = row / KSPREAD_CLUSTER_LEVEL2;
01217     int dx = row % KSPREAD_CLUSTER_LEVEL2;
01218 
01219     RowFormat** cl = m_cluster[ cx ];
01220     if ( !cl )
01221     return 0;
01222 
01223     return cl[ dx ];
01224 }
01225 
01226 RowFormat* RowCluster::lookup( int row )
01227 {
01228     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01229     {
01230     kdDebug(36001) << "RowCluster::lookup: invalid row value (row: "
01231                << row << ")" << endl;
01232     return 0;
01233     }
01234 
01235     int cx = row / KSPREAD_CLUSTER_LEVEL2;
01236     int dx = row % KSPREAD_CLUSTER_LEVEL2;
01237 
01238     RowFormat** cl = m_cluster[ cx ];
01239     if ( !cl )
01240     return 0;
01241 
01242     return cl[ dx ];
01243 }
01244 
01245 void RowCluster::clear()
01246 {
01247     for( int x = 0; x < KSPREAD_CLUSTER_LEVEL1; ++x )
01248     {
01249     RowFormat** cl = m_cluster[ x ];
01250     if ( cl )
01251         {
01252         free( cl );
01253         m_cluster[ x ] = 0;
01254     }
01255     }
01256 
01257     if ( m_autoDelete )
01258     {
01259     RowFormat* cell = m_first;
01260     while( cell )
01261         {
01262         RowFormat* n = cell->next();
01263         delete cell;
01264         cell = n;
01265     }
01266     }
01267 
01268     m_first = 0;
01269 }
01270 
01271 void RowCluster::insertElement( RowFormat* lay, int row )
01272 {
01273     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01274     {
01275     kdDebug(36001) << "RowCluster::insertElement: invalid row value (row: "
01276                << row << ")" << endl;
01277     return;
01278     }
01279 
01280     int cx = row / KSPREAD_CLUSTER_LEVEL2;
01281     int dx = row % KSPREAD_CLUSTER_LEVEL2;
01282 
01283     RowFormat** cl = m_cluster[ cx ];
01284     if ( !cl )
01285     {
01286     cl = (RowFormat**)malloc( KSPREAD_CLUSTER_LEVEL2 * sizeof( RowFormat*  ) );
01287     m_cluster[ cx ] = cl;
01288 
01289     for( int a = 0; a < KSPREAD_CLUSTER_LEVEL2; ++a )
01290         cl[ a ] = 0;
01291     }
01292 
01293     if ( cl[ dx ] )
01294     removeElement( row );
01295 
01296     cl[ dx ] = lay;
01297 
01298     if ( m_first )
01299     {
01300     lay->setNext( m_first );
01301     m_first->setPrevious( lay );
01302     }
01303     m_first = lay;
01304 }
01305 
01306 void RowCluster::removeElement( int row )
01307 {
01308     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01309     {
01310     kdDebug(36001) << "RowCluster::removeElement: invalid row value (row: "
01311                << row << ")" << endl;
01312     return;
01313     }
01314 
01315     int cx = row / KSPREAD_CLUSTER_LEVEL2;
01316     int dx = row % KSPREAD_CLUSTER_LEVEL2;
01317 
01318     RowFormat** cl = m_cluster[ cx ];
01319     if ( !cl )
01320     return;
01321 
01322     RowFormat* c = cl[ dx ];
01323     if ( !c )
01324     return;
01325 
01326     cl[ dx ] = 0;
01327 
01328     if ( m_autoDelete )
01329     {
01330     if ( m_first == c )
01331         m_first = c->next();
01332     delete c;
01333     }
01334     else
01335     {
01336     if ( m_first == c )
01337         m_first = c->next();
01338     if ( c->previous() )
01339         c->previous()->setNext( c->next() );
01340     if ( c->next() )
01341         c->next()->setPrevious( c->previous() );
01342     c->setNext( 0 );
01343     c->setPrevious( 0 );
01344     }
01345 }
01346 
01347 bool RowCluster::insertRow( int row )
01348 {
01349     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01350     {
01351     kdDebug(36001) << "RowCluster::insertRow: invalid row value (row: "
01352                << row << ")" << endl;
01353     return false;
01354     }
01355 
01356     int cx = row / KSPREAD_CLUSTER_LEVEL2;
01357     int dx = row % KSPREAD_CLUSTER_LEVEL2;
01358 
01359     // Is there a row layout at the bottom most position ?
01360     // In this case the shift is impossible.
01361     RowFormat** cl = m_cluster[ KSPREAD_CLUSTER_LEVEL1 - 1 ];
01362     if ( cl && cl[ KSPREAD_CLUSTER_LEVEL2 - 1 ] )
01363     return false;
01364 
01365     bool a = autoDelete();
01366     setAutoDelete( false );
01367 
01368     for( int i = KSPREAD_CLUSTER_LEVEL1 - 1; i >= cx ; --i )
01369     {
01370     RowFormat** cl = m_cluster[ i ];
01371     if ( cl )
01372         {
01373         int left = 0;
01374         if ( i == cx )
01375         left = dx;
01376         int right = KSPREAD_CLUSTER_LEVEL2 - 1;
01377         if ( i == KSPREAD_CLUSTER_LEVEL1 - 1 )
01378         right = KSPREAD_CLUSTER_LEVEL2 - 2;
01379         for( int k = right; k >= left; --k )
01380         {
01381         RowFormat* c = cl[ k ];
01382         if ( c )
01383             {
01384             removeElement( c->row() );
01385             c->setRow( c->row() + 1 );
01386             insertElement( c, c->row() );
01387         }
01388         }
01389     }
01390     }
01391 
01392     setAutoDelete( a );
01393 
01394     return true;
01395 }
01396 
01397 bool RowCluster::removeRow( int row )
01398 {
01399     if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01400     {
01401     kdDebug(36001) << "RowCluster::removeRow: invalid row value (row: "
01402                << row << ")" << endl;
01403     return false;
01404     }
01405 
01406     int cx = row / KSPREAD_CLUSTER_LEVEL2;
01407     int dx = row % KSPREAD_CLUSTER_LEVEL2;
01408 
01409     removeElement( row );
01410 
01411     bool a = autoDelete();
01412     setAutoDelete( false );
01413 
01414     for( int i = cx; i < KSPREAD_CLUSTER_LEVEL1; ++i )
01415     {
01416     RowFormat** cl = m_cluster[ i ];
01417     if ( cl )
01418         {
01419         int left = 0;
01420         if ( i == cx )
01421         left = dx + 1;
01422         int right = KSPREAD_CLUSTER_LEVEL2 - 1;
01423         for( int k = left; k <= right; ++k )
01424         {
01425         RowFormat* c = cl[ k ];
01426         if ( c )
01427             {
01428             removeElement( c->row() );
01429             c->setRow( c->row() - 1 );
01430             insertElement( c, c->row() );
01431         }
01432         }
01433     }
01434     }
01435 
01436     setAutoDelete( a );
01437 
01438     return true;
01439 }
01440 
01441 void RowCluster::setAutoDelete( bool a )
01442 {
01443     m_autoDelete = a;
01444 }
01445 
01446 bool RowCluster::autoDelete() const
01447 {
01448     return m_autoDelete;
01449 }
01450 
01451 RowFormat* RowCluster::next( int row ) const
01452 {
01453   if ( row >= KSPREAD_CLUSTER_MAX || row < 0 )
01454   {
01455     kdDebug(36001) << "RowCluster::removeRow: invalid row value (row: "
01456         << row << ")" << endl;
01457     return false;
01458   }
01459 
01460   int cx = (row + 1) / KSPREAD_CLUSTER_LEVEL2;
01461   int dx = (row + 1) % KSPREAD_CLUSTER_LEVEL2;
01462 
01463   while ( cx < KSPREAD_CLUSTER_LEVEL1 )
01464   {
01465     if ( m_cluster[ cx ] )
01466     {
01467       while ( dx < KSPREAD_CLUSTER_LEVEL2 )
01468       {
01469 
01470         if ( m_cluster[ cx ][  dx ] )
01471         {
01472           return m_cluster[ cx ][ dx ];
01473         }
01474         ++dx;
01475       }
01476     }
01477     ++cx;
01478     dx = 0;
01479   }
01480   return 0;
01481 }
KDE Home | KDE Accessibility Home | Description of Access Keys