001: /* ====================================================================
002: Copyright 2002-2004 Apache Software Foundation
003:
004: Licensed under the Apache License, Version 2.0 (the "License");
005: you may not use this file except in compliance with the License.
006: You may obtain a copy of the License at
007:
008: http://www.apache.org/licenses/LICENSE-2.0
009:
010: Unless required by applicable law or agreed to in writing, software
011: distributed under the License is distributed on an "AS IS" BASIS,
012: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: See the License for the specific language governing permissions and
014: limitations under the License.
015: ==================================================================== */
016:
017: package org.apache.poi.hssf.util;
018:
019: import org.apache.poi.hssf.record.RecordInputStream;
020: import org.apache.poi.util.LittleEndian;
021: import java.util.ArrayList;
022:
023: /**
024: * <p>Title: HSSFCellRangeAddress</p>
025: * <p>Description:
026: * Implementation of the cell range address lists,like is described in
027: * OpenOffice.org's Excel Documentation .
028: * In BIFF8 there is a common way to store absolute cell range address
029: * lists in several records (not formulas). A cell range address list
030: * consists of a field with the number of ranges and the list of the range
031: * addresses. Each cell range address (called an ADDR structure) contains
032: * 4 16-bit-values.</p>
033: * <p>Copyright: Copyright (c) 2004</p>
034: * <p>Company: </p>
035: * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
036: * @version 2.0-pre
037: */
038:
039: public class HSSFCellRangeAddress {
040: /**
041: * Number of following ADDR structures
042: */
043: private short field_addr_number;
044:
045: /**
046: * List of ADDR structures. Each structure represents a cell range
047: */
048: private ArrayList field_regions_list;
049:
050: public HSSFCellRangeAddress() {
051:
052: }
053:
054: /**
055: * Construct a new HSSFCellRangeAddress object and sets its fields appropriately .
056: * Even this isn't an Excel record , I kept the same behavior for reading/writing
057: * the object's data as for a regular record .
058: *
059: * @param in the RecordInputstream to read the record from
060: */
061: public HSSFCellRangeAddress(RecordInputStream in) {
062: this .fillFields(in);
063: }
064:
065: public void fillFields(RecordInputStream in) {
066: this .field_addr_number = in.readShort();
067: this .field_regions_list = new ArrayList(this .field_addr_number);
068:
069: for (int k = 0; k < this .field_addr_number; k++) {
070: short first_row = in.readShort();
071: short first_col = in.readShort();
072: short last_row = in.readShort();
073: short last_col = in.readShort();
074:
075: AddrStructure region = new AddrStructure(first_row,
076: first_col, last_row, last_col);
077: this .field_regions_list.add(region);
078: }
079: }
080:
081: /**
082: * Get the number of following ADDR structures.
083: * The number of this structures is automatically set when reading an Excel file
084: * and/or increased when you manually add a new ADDR structure .
085: * This is the reason there isn't a set method for this field .
086: * @return number of ADDR structures
087: */
088: public short getADDRStructureNumber() {
089: return this .field_addr_number;
090: }
091:
092: /**
093: * Add an ADDR structure .
094: * @param first_row - the upper left hand corner's row
095: * @param first_col - the upper left hand corner's col
096: * @param last_row - the lower right hand corner's row
097: * @param last_col - the lower right hand corner's col
098: * @return the index of this ADDR structure
099: */
100: public int addADDRStructure(short first_row, short first_col,
101: short last_row, short last_col) {
102: if (this .field_regions_list == null) {
103: //just to be sure :-)
104: this .field_addr_number = 0;
105: this .field_regions_list = new ArrayList(10);
106: }
107: AddrStructure region = new AddrStructure(first_row, last_row,
108: first_col, last_col);
109:
110: this .field_regions_list.add(region);
111: this .field_addr_number++;
112: return this .field_addr_number;
113: }
114:
115: /**
116: * Remove the ADDR structure stored at the passed in index
117: * @param index The ADDR structure's index
118: */
119: public void removeADDRStructureAt(int index) {
120: this .field_regions_list.remove(index);
121: this .field_addr_number--;
122: }
123:
124: /**
125: * return the ADDR structure at the given index.
126: * @return AddrStructure representing
127: */
128: public AddrStructure getADDRStructureAt(int index) {
129: return (AddrStructure) this .field_regions_list.get(index);
130: }
131:
132: public int serialize(int offset, byte[] data) {
133: int pos = 2;
134:
135: LittleEndian.putShort(data, offset, this
136: .getADDRStructureNumber());
137: for (int k = 0; k < this .getADDRStructureNumber(); k++) {
138: AddrStructure region = this .getADDRStructureAt(k);
139: LittleEndian.putShort(data, offset + pos, region
140: .getFirstRow());
141: pos += 2;
142: LittleEndian.putShort(data, offset + pos, region
143: .getLastRow());
144: pos += 2;
145: LittleEndian.putShort(data, offset + pos, region
146: .getFirstColumn());
147: pos += 2;
148: LittleEndian.putShort(data, offset + pos, region
149: .getLastColumn());
150: pos += 2;
151: }
152: return this .getSize();
153: }
154:
155: public int getSize() {
156: return 2 + this .field_addr_number * 8;
157: }
158:
159: public class AddrStructure {
160: private short _first_row;
161: private short _first_col;
162: private short _last_row;
163: private short _last_col;
164:
165: public AddrStructure(short first_row, short last_row,
166: short first_col, short last_col) {
167: this ._first_row = first_row;
168: this ._last_row = last_row;
169: this ._first_col = first_col;
170: this ._last_col = last_col;
171: }
172:
173: /**
174: * get the upper left hand corner column number
175: * @return column number for the upper left hand corner
176: */
177: public short getFirstColumn() {
178: return this ._first_col;
179: }
180:
181: /**
182: * get the upper left hand corner row number
183: * @return row number for the upper left hand corner
184: */
185: public short getFirstRow() {
186: return this ._first_row;
187: }
188:
189: /**
190: * get the lower right hand corner column number
191: * @return column number for the lower right hand corner
192: */
193: public short getLastColumn() {
194: return this ._last_col;
195: }
196:
197: /**
198: * get the lower right hand corner row number
199: * @return row number for the lower right hand corner
200: */
201: public short getLastRow() {
202: return this ._last_row;
203: }
204:
205: /**
206: * set the upper left hand corner column number
207: * @param this._first_col column number for the upper left hand corner
208: */
209: public void setFirstColumn(short first_col) {
210: this ._first_col = first_col;
211: }
212:
213: /**
214: * set the upper left hand corner row number
215: * @param rowFrom row number for the upper left hand corner
216: */
217: public void setFirstRow(short first_row) {
218: this ._first_row = first_row;
219: }
220:
221: /**
222: * set the lower right hand corner column number
223: * @param colTo column number for the lower right hand corner
224: */
225: public void setLastColumn(short last_col) {
226: this ._last_col = last_col;
227: }
228:
229: /**
230: * get the lower right hand corner row number
231: * @param rowTo row number for the lower right hand corner
232: */
233: public void setLastRow(short last_row) {
234: this._last_row = last_row;
235: }
236: }
237: }
|