File indexing completed on 2024-04-28 16:21:20
0001 /* This file is part of the KDE project 0002 Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com> 0003 Copyright (C) 2000 Torben Weis <weis@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 // Local 0022 #include "Cluster.h" 0023 0024 #include <stdlib.h> 0025 0026 #include "SheetsDebug.h" 0027 #include "Cell.h" 0028 #include "RowColumnFormat.h" 0029 0030 using namespace Calligra::Sheets; 0031 0032 /**************************************************** 0033 * 0034 * ColumnCluster 0035 * 0036 ****************************************************/ 0037 0038 ColumnCluster::ColumnCluster() 0039 : m_first(0), m_autoDelete(false) 0040 { 0041 m_cluster = (ColumnFormat***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(ColumnFormat**)); 0042 0043 for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) 0044 m_cluster[ x ] = 0; 0045 } 0046 0047 ColumnCluster::~ColumnCluster() 0048 { 0049 for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) { 0050 ColumnFormat** cl = m_cluster[ x ]; 0051 if (cl) { 0052 free(cl); 0053 m_cluster[ x ] = 0; 0054 } 0055 } 0056 0057 if (m_autoDelete) { 0058 ColumnFormat* cell = m_first; 0059 while (cell) { 0060 ColumnFormat* n = cell->next(); 0061 delete cell; 0062 cell = n; 0063 } 0064 } 0065 0066 0067 free(m_cluster); 0068 } 0069 0070 ColumnFormat* ColumnCluster::lookup(int col) 0071 { 0072 if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { 0073 debugSheets << "ColumnCluster::lookup: invalid column value (col:" 0074 << col << ")" << endl; 0075 return 0; 0076 } 0077 0078 int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0079 int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0080 0081 ColumnFormat** cl = m_cluster[ cx ]; 0082 if (!cl) 0083 return 0; 0084 0085 return cl[ dx ]; 0086 } 0087 0088 const ColumnFormat* ColumnCluster::lookup(int col) const 0089 { 0090 if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { 0091 debugSheets << "ColumnCluster::lookup: invalid column value (col:" 0092 << col << ")" << endl; 0093 return 0; 0094 } 0095 0096 int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0097 int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0098 0099 ColumnFormat** cl = m_cluster[ cx ]; 0100 if (!cl) 0101 return 0; 0102 0103 return cl[ dx ]; 0104 } 0105 0106 void ColumnCluster::clear() 0107 { 0108 for (int x = 0; x < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++x) { 0109 ColumnFormat** cl = m_cluster[ x ]; 0110 if (cl) { 0111 free(cl); 0112 m_cluster[ x ] = 0; 0113 } 0114 } 0115 0116 if (m_autoDelete) { 0117 ColumnFormat* cell = m_first; 0118 while (cell) { 0119 ColumnFormat* n = cell->next(); 0120 delete cell; 0121 cell = n; 0122 } 0123 } 0124 0125 m_first = 0; 0126 } 0127 0128 void ColumnCluster::insertElement(ColumnFormat* lay, int col) 0129 { 0130 if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { 0131 debugSheets << "ColumnCluster::insertElement: invalid column value (col:" 0132 << col << ")" << endl; 0133 return; 0134 } 0135 0136 int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0137 int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0138 0139 ColumnFormat** cl = m_cluster[ cx ]; 0140 if (!cl) { 0141 cl = (ColumnFormat**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(ColumnFormat*)); 0142 m_cluster[ cx ] = cl; 0143 0144 for (int a = 0; a < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++a) 0145 cl[ a ] = 0; 0146 } 0147 0148 if (cl[ dx ]) 0149 removeElement(col); 0150 0151 cl[ dx ] = lay; 0152 0153 if (m_first) { 0154 lay->setNext(m_first); 0155 m_first->setPrevious(lay); 0156 } 0157 m_first = lay; 0158 } 0159 0160 void ColumnCluster::removeElement(int col) 0161 { 0162 if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { 0163 debugSheets << "ColumnCluster::removeElement: invalid column value (col:" 0164 << col << ")" << endl; 0165 return; 0166 } 0167 0168 int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0169 int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0170 0171 ColumnFormat** cl = m_cluster[ cx ]; 0172 if (!cl) 0173 return; 0174 0175 ColumnFormat* c = cl[ dx ]; 0176 if (!c) 0177 return; 0178 0179 cl[ dx ] = 0; 0180 0181 if (m_autoDelete) { 0182 if (m_first == c) 0183 m_first = c->next(); 0184 delete c; 0185 } else { 0186 if (m_first == c) 0187 m_first = c->next(); 0188 if (c->previous()) 0189 c->previous()->setNext(c->next()); 0190 if (c->next()) 0191 c->next()->setPrevious(c->previous()); 0192 c->setNext(0); 0193 c->setPrevious(0); 0194 } 0195 } 0196 0197 bool ColumnCluster::insertColumn(int col) 0198 { 0199 if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { 0200 debugSheets << "ColumnCluster::insertColumn: invalid column value (col:" 0201 << col << ")" << endl; 0202 return false; 0203 } 0204 0205 int cx = col / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0206 int dx = col % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0207 0208 // Is there a column layout at the right most position ? 0209 // In this case the shift is impossible. 0210 ColumnFormat** cl = m_cluster[ CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1 ]; 0211 if (cl && cl[ CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1 ]) 0212 return false; 0213 0214 bool a = autoDelete(); 0215 setAutoDelete(false); 0216 0217 for (int i = CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1; i >= cx ; --i) { 0218 ColumnFormat** cl = m_cluster[ i ]; 0219 if (cl) { 0220 int left = 0; 0221 if (i == cx) 0222 left = dx; 0223 int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; 0224 if (i == CALLIGRA_SHEETS_CLUSTER_LEVEL1 - 1) 0225 right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 2; 0226 for (int k = right; k >= left; --k) { 0227 ColumnFormat* c = cl[ k ]; 0228 if (c) { 0229 removeElement(c->column()); 0230 c->setColumn(c->column() + 1); 0231 insertElement(c, c->column()); 0232 } 0233 } 0234 } 0235 } 0236 0237 setAutoDelete(a); 0238 0239 return true; 0240 } 0241 0242 bool ColumnCluster::removeColumn(int column) 0243 { 0244 if (column >= CALLIGRA_SHEETS_CLUSTER_MAX || column < 0) { 0245 debugSheets << "ColumnCluster::removeColumn: invalid column value (col:" 0246 << column << ")" << endl; 0247 return false; 0248 } 0249 0250 int cx = column / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0251 int dx = column % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0252 0253 removeElement(column); 0254 0255 bool a = autoDelete(); 0256 setAutoDelete(false); 0257 0258 for (int i = cx; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { 0259 ColumnFormat** cl = m_cluster[ i ]; 0260 if (cl) { 0261 int left = 0; 0262 if (i == cx) 0263 left = dx + 1; 0264 int right = CALLIGRA_SHEETS_CLUSTER_LEVEL2 - 1; 0265 for (int k = left; k <= right; ++k) { 0266 ColumnFormat* c = cl[ k ]; 0267 if (c) { 0268 removeElement(c->column()); 0269 c->setColumn(c->column() - 1); 0270 insertElement(c, c->column()); 0271 } 0272 } 0273 } 0274 } 0275 0276 setAutoDelete(a); 0277 0278 return true; 0279 } 0280 0281 void ColumnCluster::setAutoDelete(bool a) 0282 { 0283 m_autoDelete = a; 0284 } 0285 0286 bool ColumnCluster::autoDelete() const 0287 { 0288 return m_autoDelete; 0289 } 0290 0291 ColumnFormat* ColumnCluster::next(int col) const 0292 { 0293 if (col >= CALLIGRA_SHEETS_CLUSTER_MAX || col < 0) { 0294 debugSheets << "ColumnCluster::next: invalid column value (col:" 0295 << col << ")" << endl; 0296 return 0; 0297 } 0298 0299 int cx = (col + 1) / CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0300 int dx = (col + 1) % CALLIGRA_SHEETS_CLUSTER_LEVEL2; 0301 0302 while (cx < CALLIGRA_SHEETS_CLUSTER_LEVEL1) { 0303 if (m_cluster[ cx ]) { 0304 while (dx < CALLIGRA_SHEETS_CLUSTER_LEVEL2) { 0305 0306 if (m_cluster[ cx ][ dx ]) { 0307 return m_cluster[ cx ][ dx ]; 0308 } 0309 ++dx; 0310 } 0311 } 0312 ++cx; 0313 dx = 0; 0314 } 0315 return 0; 0316 } 0317 0318 void ColumnCluster::operator=(const ColumnCluster & other) 0319 { 0320 m_first = 0; 0321 m_autoDelete = other.m_autoDelete; 0322 // TODO Stefan: Optimize! 0323 m_cluster = (ColumnFormat***)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL1 * sizeof(ColumnFormat**)); 0324 for (int i = 0; i < CALLIGRA_SHEETS_CLUSTER_LEVEL1; ++i) { 0325 if (other.m_cluster[i]) { 0326 m_cluster[i] = (ColumnFormat**)malloc(CALLIGRA_SHEETS_CLUSTER_LEVEL2 * sizeof(ColumnFormat*)); 0327 for (int j = 0; j < CALLIGRA_SHEETS_CLUSTER_LEVEL2; ++j) { 0328 m_cluster[i][j] = 0; 0329 if (other.m_cluster[i][j]) { 0330 ColumnFormat* columnFormat = new ColumnFormat(*other.m_cluster[i][j]); 0331 columnFormat->setNext(0); 0332 columnFormat->setPrevious(0); 0333 insertElement(columnFormat, columnFormat->column()); 0334 } 0335 } 0336 } else 0337 m_cluster[i] = 0; 0338 } 0339 } 0340 0341