1 package org.apache.poi.hssf.record.aggregates; 2 3 import org.apache.poi.hssf.record.ColumnInfoRecord; 4 import org.apache.poi.hssf.record.Record; 5 6 import java.util.ArrayList ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 10 14 public class ColumnInfoRecordsAggregate 15 extends Record 16 { 17 int size = 0; 18 List records = null; 19 20 public ColumnInfoRecordsAggregate() 21 { 22 records = new ArrayList (); 23 } 24 25 26 protected void fillFields(byte [] data, short size, int offset) 27 { 28 } 29 30 31 protected void validateSid(short id) 32 { 33 } 34 35 36 public short getSid() 37 { 38 return -1012; 39 } 40 41 public int getRecordSize() 42 { 43 return size; 44 } 45 46 public Iterator getIterator() 47 { 48 return records.iterator(); 49 } 50 51 54 public Object clone() 55 { 56 ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate(); 57 for ( Iterator colIter = getIterator(); colIter.hasNext(); ) 58 { 59 ColumnInfoRecord col = (ColumnInfoRecord) ( (ColumnInfoRecord) colIter.next() ).clone(); 61 rec.insertColumn( col ); 62 } 63 return rec; 64 } 65 66 69 public void insertColumn( ColumnInfoRecord col ) 70 { 71 size += col.getRecordSize(); 72 records.add( col ); 73 } 74 75 79 public void insertColumn( int idx, ColumnInfoRecord col ) 80 { 81 size += col.getRecordSize(); 82 records.add( idx, col ); 83 } 84 85 public int getNumColumns( ) 86 { 87 return records.size(); 88 } 89 90 99 public int serialize(int offset, byte [] data) 100 { 101 Iterator itr = records.iterator(); 102 int pos = offset; 103 104 while (itr.hasNext()) 105 { 106 pos += (( Record ) itr.next()).serialize(pos, data); 107 } 108 return pos - offset; 109 } 110 111 public int findStartOfColumnOutlineGroup(int idx) 112 { 113 ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( idx ); 115 int level = columnInfo.getOutlineLevel(); 116 while (idx != 0) 117 { 118 ColumnInfoRecord prevColumnInfo = (ColumnInfoRecord) records.get( idx - 1 ); 119 if (columnInfo.getFirstColumn() - 1 == prevColumnInfo.getLastColumn()) 120 { 121 if (prevColumnInfo.getOutlineLevel() < level) 122 { 123 break; 124 } 125 idx--; 126 columnInfo = prevColumnInfo; 127 } 128 else 129 { 130 break; 131 } 132 } 133 134 return idx; 135 } 136 137 public int findEndOfColumnOutlineGroup(int idx) 138 { 139 ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( idx ); 141 int level = columnInfo.getOutlineLevel(); 142 while (idx < records.size() - 1) 143 { 144 ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) records.get( idx + 1 ); 145 if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn()) 146 { 147 if (nextColumnInfo.getOutlineLevel() < level) 148 { 149 break; 150 } 151 idx++; 152 columnInfo = nextColumnInfo; 153 } 154 else 155 { 156 break; 157 } 158 } 159 160 return idx; 161 } 162 163 public ColumnInfoRecord getColInfo(int idx) 164 { 165 return (ColumnInfoRecord) records.get( idx ); 166 } 167 168 public ColumnInfoRecord writeHidden( ColumnInfoRecord columnInfo, int idx, boolean hidden ) 169 { 170 int level = columnInfo.getOutlineLevel(); 171 while (idx < records.size()) 172 { 173 columnInfo.setHidden( hidden ); 174 if (idx + 1 < records.size()) 175 { 176 ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) records.get( idx + 1 ); 177 if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn()) 178 { 179 if (nextColumnInfo.getOutlineLevel() < level) 180 break; 181 columnInfo = nextColumnInfo; 182 } 183 else 184 { 185 break; 186 } 187 } 188 idx++; 189 } 190 return columnInfo; 191 } 192 193 public boolean isColumnGroupCollapsed( int idx ) 194 { 195 int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); 196 if (endOfOutlineGroupIdx >= records.size()) 197 return false; 198 if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn()) 199 return false; 200 else 201 return getColInfo(endOfOutlineGroupIdx+1).getCollapsed(); 202 } 203 204 205 public boolean isColumnGroupHiddenByParent( int idx ) 206 { 207 int endLevel; 209 boolean endHidden; 210 int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); 211 if (endOfOutlineGroupIdx >= records.size()) 212 { 213 endLevel = 0; 214 endHidden = false; 215 } 216 else if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn()) 217 { 218 endLevel = 0; 219 endHidden = false; 220 } 221 else 222 { 223 endLevel = getColInfo( endOfOutlineGroupIdx + 1).getOutlineLevel(); 224 endHidden = getColInfo( endOfOutlineGroupIdx + 1).getHidden(); 225 } 226 227 int startLevel; 229 boolean startHidden; 230 int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx ); 231 if (startOfOutlineGroupIdx <= 0) 232 { 233 startLevel = 0; 234 startHidden = false; 235 } 236 else if (getColInfo(startOfOutlineGroupIdx).getFirstColumn() - 1 != getColInfo(startOfOutlineGroupIdx - 1).getLastColumn()) 237 { 238 startLevel = 0; 239 startHidden = false; 240 } 241 else 242 { 243 startLevel = getColInfo( startOfOutlineGroupIdx - 1).getOutlineLevel(); 244 startHidden = getColInfo( startOfOutlineGroupIdx - 1 ).getHidden(); 245 } 246 247 if (endLevel > startLevel) 248 { 249 return endHidden; 250 } 251 else 252 { 253 return startHidden; 254 } 255 } 256 257 public void collapseColumn( short columnNumber ) 258 { 259 int idx = findColumnIdx( columnNumber, 0 ); 260 if (idx == -1) 261 return; 262 263 ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( findStartOfColumnOutlineGroup( idx ) ); 265 266 columnInfo = writeHidden( columnInfo, idx, true ); 268 269 setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.TRUE); 271 } 272 273 public void expandColumn( short columnNumber ) 274 { 275 int idx = findColumnIdx( columnNumber, 0 ); 276 if (idx == -1) 277 return; 278 279 if (!isColumnGroupCollapsed(idx)) 281 return; 282 283 int startIdx = findStartOfColumnOutlineGroup( idx ); 285 ColumnInfoRecord columnInfo = getColInfo( startIdx ); 286 287 int endIdx = findEndOfColumnOutlineGroup( idx ); 289 ColumnInfoRecord endColumnInfo = getColInfo( endIdx ); 290 291 if (!isColumnGroupHiddenByParent( idx )) 299 { 300 for (int i = startIdx; i <= endIdx; i++) 301 { 302 if (columnInfo.getOutlineLevel() == getColInfo(i).getOutlineLevel()) 303 getColInfo(i).setHidden( false ); 304 } 305 } 306 307 setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.FALSE); 309 } 310 311 316 public static Record createColInfo() 317 { 318 ColumnInfoRecord retval = new ColumnInfoRecord(); 319 320 retval.setColumnWidth(( short ) 2275); 321 retval.setOptions(( short ) 2); 323 retval.setXFIndex(( short ) 0x0f); 324 return retval; 325 } 326 327 328 public void setColumn(short column, Short width, Integer level, Boolean hidden, Boolean collapsed) 329 { 330 ColumnInfoRecord ci = null; 331 int k = 0; 332 333 for (k = 0; k < records.size(); k++) 334 { 335 ci = ( ColumnInfoRecord ) records.get(k); 336 if ((ci.getFirstColumn() <= column) 337 && (column <= ci.getLastColumn())) 338 { 339 break; 340 } 341 ci = null; 342 } 343 344 if (ci != null) 345 { 346 boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue(); 347 boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue(); 348 boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue(); 349 boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue(); 350 boolean columnChanged = widthChanged || levelChanged || hiddenChanged || collapsedChanged; 351 if (!columnChanged) 352 { 353 } 355 else if ((ci.getFirstColumn() == column) 356 && (ci.getLastColumn() == column)) 357 { setColumnInfoFields( ci, width, level, hidden, collapsed ); 359 } 360 else if ((ci.getFirstColumn() == column) 361 || (ci.getLastColumn() == column)) 362 { 363 if (ci.getFirstColumn() == column) 366 { 367 ci.setFirstColumn(( short ) (column + 1)); 368 } 369 else 370 { 371 ci.setLastColumn(( short ) (column - 1)); 372 } 373 ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo(); 374 375 nci.setFirstColumn(column); 376 nci.setLastColumn(column); 377 nci.setOptions(ci.getOptions()); 378 nci.setXFIndex(ci.getXFIndex()); 379 setColumnInfoFields( nci, width, level, hidden, collapsed ); 380 381 insertColumn(k, nci); 382 } 383 else 384 { 385 short lastcolumn = ci.getLastColumn(); 387 ci.setLastColumn(( short ) (column - 1)); 388 389 ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo(); 390 nci.setFirstColumn(column); 391 nci.setLastColumn(column); 392 nci.setOptions(ci.getOptions()); 393 nci.setXFIndex(ci.getXFIndex()); 394 setColumnInfoFields( nci, width, level, hidden, collapsed ); 395 insertColumn(++k, nci); 396 397 nci = ( ColumnInfoRecord ) createColInfo(); 398 nci.setFirstColumn((short)(column+1)); 399 nci.setLastColumn(lastcolumn); 400 nci.setOptions(ci.getOptions()); 401 nci.setXFIndex(ci.getXFIndex()); 402 nci.setColumnWidth(ci.getColumnWidth()); 403 insertColumn(++k, nci); 404 } 405 } 406 else 407 { 408 409 ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo(); 411 412 nci.setFirstColumn(column); 413 nci.setLastColumn(column); 414 setColumnInfoFields( nci, width, level, hidden, collapsed ); 415 insertColumn(k, nci); 416 } 417 } 418 419 422 private void setColumnInfoFields( ColumnInfoRecord ci, Short width, Integer level, Boolean hidden, Boolean collapsed ) 423 { 424 if (width != null) 425 ci.setColumnWidth(width.shortValue()); 426 if (level != null) 427 ci.setOutlineLevel( level.shortValue() ); 428 if (hidden != null) 429 ci.setHidden( hidden.booleanValue() ); 430 if (collapsed != null) 431 ci.setCollapsed( collapsed.booleanValue() ); 432 } 433 434 public int findColumnIdx(int column, int fromIdx) 435 { 436 if (column < 0) 437 throw new IllegalArgumentException ( "column parameter out of range: " + column ); 438 if (fromIdx < 0) 439 throw new IllegalArgumentException ( "fromIdx parameter out of range: " + fromIdx ); 440 441 ColumnInfoRecord ci; 442 for (int k = fromIdx; k < records.size(); k++) 443 { 444 ci = ( ColumnInfoRecord ) records.get(k); 445 if ((ci.getFirstColumn() <= column) 446 && (column <= ci.getLastColumn())) 447 { 448 return k; 449 } 450 ci = null; 451 } 452 return -1; 453 } 454 455 public void collapseColInfoRecords( int columnIdx ) 456 { 457 if (columnIdx == 0) 458 return; 459 ColumnInfoRecord previousCol = (ColumnInfoRecord) records.get( columnIdx - 1); 460 ColumnInfoRecord currentCol = (ColumnInfoRecord) records.get( columnIdx ); 461 boolean adjacentColumns = previousCol.getLastColumn() == currentCol.getFirstColumn() - 1; 462 if (!adjacentColumns) 463 return; 464 465 boolean columnsMatch = 466 previousCol.getXFIndex() == currentCol.getXFIndex() && 467 previousCol.getOptions() == currentCol.getOptions() && 468 previousCol.getColumnWidth() == currentCol.getColumnWidth(); 469 470 if (columnsMatch) 471 { 472 previousCol.setLastColumn( currentCol.getLastColumn() ); 473 records.remove( columnIdx ); 474 } 475 } 476 477 484 public void groupColumnRange(short fromColumn, short toColumn, boolean indent) 485 { 486 487 int fromIdx = 0; 489 for (int i = fromColumn; i <= toColumn; i++) 490 { 491 int level = 1; 492 int columnIdx = findColumnIdx( i, Math.max(0,fromIdx) ); 493 if (columnIdx != -1) 494 { 495 level = ((ColumnInfoRecord)records.get( columnIdx )).getOutlineLevel(); 496 if (indent) level++; else level--; 497 level = Math.max(0, level); 498 level = Math.min(7, level); 499 fromIdx = columnIdx - 1; } 501 setColumn((short)i, null, new Integer (level), null, null); 502 columnIdx = findColumnIdx( i, Math.max(0, fromIdx ) ); 503 collapseColInfoRecords( columnIdx ); 504 } 505 506 } 507 508 509 } 510 | Popular Tags |