KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hssf > record > aggregates > ColumnInfoRecordsAggregate


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 JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9
10 /**
11  * @author Glen Stampoultzis
12  * @version $Id: ColumnInfoRecordsAggregate.java,v 1.2 2004/08/23 08:52:28 glens Exp $
13  */

14 public class ColumnInfoRecordsAggregate
15     extends Record
16 {
17     int size = 0;
18     List JavaDoc records = null;
19
20     public ColumnInfoRecordsAggregate()
21     {
22         records = new ArrayList JavaDoc();
23     }
24
25     /** You never fill an aggregate */
26     protected void fillFields(byte [] data, short size, int offset)
27     {
28     }
29
30     /** Not required by an aggregate */
31     protected void validateSid(short id)
32     {
33     }
34
35     /** It's an aggregate... just made something up */
36     public short getSid()
37     {
38         return -1012;
39     }
40
41     public int getRecordSize()
42     {
43         return size;
44     }
45
46     public Iterator JavaDoc getIterator()
47     {
48         return records.iterator();
49     }
50
51     /**
52      * Performs a deep clone of the record
53      */

54     public Object JavaDoc clone()
55     {
56         ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate();
57         for ( Iterator JavaDoc colIter = getIterator(); colIter.hasNext(); )
58         {
59             //return the cloned Row Record & insert
60
ColumnInfoRecord col = (ColumnInfoRecord) ( (ColumnInfoRecord) colIter.next() ).clone();
61             rec.insertColumn( col );
62         }
63         return rec;
64     }
65
66     /**
67      * Inserts a column into the aggregate (at the end of the list).
68      */

69     public void insertColumn( ColumnInfoRecord col )
70     {
71         size += col.getRecordSize();
72         records.add( col );
73     }
74
75     /**
76      * Inserts a column into the aggregate (at the position specified
77      * by <code>idx</code>.
78      */

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     /**
91      * called by the class that is responsible for writing this sucker.
92      * Subclasses should implement this so that their data is passed back in a
93      * byte array.
94      *
95      * @param offset offset to begin writing at
96      * @param data byte array containing instance data
97      * @return number of bytes written
98      */

99     public int serialize(int offset, byte [] data)
100     {
101         Iterator JavaDoc 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         // Find the start of the group.
114
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         // Find the end of the group.
140
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         // Look out outline details of end
208
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         // Look out outline details of start
228
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         // Find the start of the group.
264
ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( findStartOfColumnOutlineGroup( idx ) );
265
266         // Hide all the columns until the end of the group
267
columnInfo = writeHidden( columnInfo, idx, true );
268
269         // Write collapse field
270
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 it is already exapanded do nothing.
280
if (!isColumnGroupCollapsed(idx))
281             return;
282
283         // Find the start of the group.
284
int startIdx = findStartOfColumnOutlineGroup( idx );
285         ColumnInfoRecord columnInfo = getColInfo( startIdx );
286
287         // Find the end of the group.
288
int endIdx = findEndOfColumnOutlineGroup( idx );
289         ColumnInfoRecord endColumnInfo = getColInfo( endIdx );
290
291         // expand:
292
// colapsed bit must be unset
293
// hidden bit gets unset _if_ surrounding groups are expanded you can determine
294
// this by looking at the hidden bit of the enclosing group. You will have
295
// to look at the start and the end of the current group to determine which
296
// is the enclosing group
297
// hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
298
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         // Write collapse field
308
setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.FALSE);
309     }
310
311     /**
312      * creates the ColumnInfo Record and sets it to a default column/width
313      * @see org.apache.poi.hssf.record.ColumnInfoRecord
314      * @return record containing a ColumnInfoRecord
315      */

316     public static Record createColInfo()
317     {
318         ColumnInfoRecord retval = new ColumnInfoRecord();
319
320         retval.setColumnWidth(( short ) 2275);
321         // was: retval.setOptions(( short ) 6);
322
retval.setOptions(( short ) 2);
323         retval.setXFIndex(( short ) 0x0f);
324         return retval;
325     }
326
327
328     public void setColumn(short column, Short JavaDoc width, Integer JavaDoc level, Boolean JavaDoc hidden, Boolean JavaDoc 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                 // do nothing...nothing changed.
354
}
355             else if ((ci.getFirstColumn() == column)
356                      && (ci.getLastColumn() == column))
357             { // if its only for this cell then
358
setColumnInfoFields( ci, width, level, hidden, collapsed );
359             }
360             else if ((ci.getFirstColumn() == column)
361                      || (ci.getLastColumn() == column))
362             {
363                 // okay so the width is different but the first or last column == the column we'return setting
364
// we'll just divide the info and create a new one
365
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                 //split to 3 records
386
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             // okay so there ISN'T a column info record that cover's this column so lets create one!
410
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     /**
420      * Sets all non null fields into the <code>ci</code> parameter.
421      */

422     private void setColumnInfoFields( ColumnInfoRecord ci, Short JavaDoc width, Integer JavaDoc level, Boolean JavaDoc hidden, Boolean JavaDoc 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 JavaDoc( "column parameter out of range: " + column );
438         if (fromIdx < 0)
439             throw new IllegalArgumentException JavaDoc( "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     /**
478      * Creates an outline group for the specified columns.
479      * @param fromColumn group from this column (inclusive)
480      * @param toColumn group to this column (inclusive)
481      * @param indent if true the group will be indented by one level,
482      * if false indenting will be removed by one level.
483      */

484     public void groupColumnRange(short fromColumn, short toColumn, boolean indent)
485     {
486
487         // Set the level for each column
488
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; // subtract 1 just in case this column is collapsed later.
500
}
501             setColumn((short)i, null, new Integer JavaDoc(level), null, null);
502             columnIdx = findColumnIdx( i, Math.max(0, fromIdx ) );
503             collapseColInfoRecords( columnIdx );
504         }
505
506     }
507
508
509 }
510
Popular Tags