1    
2    /* ====================================================================
3     * The Apache Software License, Version 1.1
4     *
5     * Copyright (c) 2002 The Apache Software Foundation.  All rights
6     * reserved.
7     *
8     * Redistribution and use in source and binary forms, with or without
9     * modification, are permitted provided that the following conditions
10    * are met:
11    *
12    * 1. Redistributions of source code must retain the above copyright
13    *    notice, this list of conditions and the following disclaimer.
14    *
15    * 2. Redistributions in binary form must reproduce the above copyright
16    *    notice, this list of conditions and the following disclaimer in
17    *    the documentation and/or other materials provided with the
18    *    distribution.
19    *
20    * 3. The end-user documentation included with the redistribution,
21    *    if any, must include the following acknowledgment:
22    *       "This product includes software developed by the
23    *        Apache Software Foundation (http://www.apache.org/)."
24    *    Alternately, this acknowledgment may appear in the software itself,
25    *    if and wherever such third-party acknowledgments normally appear.
26    *
27    * 4. The names "Apache" and "Apache Software Foundation" and
28    *    "Apache POI" must not be used to endorse or promote products
29    *    derived from this software without prior written permission. For
30    *    written permission, please contact apache@apache.org.
31    *
32    * 5. Products derived from this software may not be called "Apache",
33    *    "Apache POI", nor may "Apache" appear in their name, without
34    *    prior written permission of the Apache Software Foundation.
35    *
36    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47    * SUCH DAMAGE.
48    * ====================================================================
49    *
50    * This software consists of voluntary contributions made by many
51    * individuals on behalf of the Apache Software Foundation.  For more
52    * information on the Apache Software Foundation, please see
53    * <http://www.apache.org/>.
54    */
55   
56   /*
57    * AreaPtg.java
58    *
59    * Created on November 17, 2001, 9:30 PM
60    */
61   package org.apache.poi.hssf.record.formula;
62   
63   import org.apache.poi.util.LittleEndian;
64   import org.apache.poi.util.BitField;
65   
66   import org.apache.poi.hssf.util.AreaReference;
67   import org.apache.poi.hssf.util.CellReference;
68   import org.apache.poi.hssf.util.SheetReferences;
69   
70   /**
71    * Specifies a rectangular area of cells A1:A4 for instance.
72    * @author  andy
73    * @author Jason Height (jheight at chariot dot net dot au)
74    */
75   
76   public class AreaPtg
77       extends Ptg
78   {
79       public final static short sid  = 0x25;
80       private final static int  SIZE = 9;
81       private short             field_1_first_row;
82       private short             field_2_last_row;
83       private short             field_3_first_column;
84       private short             field_4_last_column;
85       
86       private BitField         rowRelative = new BitField(0x8000);
87       private BitField         colRelative = new BitField(0x4000);
88       private BitField         column      = new BitField(0x3FFF);
89   
90       private AreaPtg() {
91         //Required for clone methods
92       }
93      
94       public AreaPtg(String arearef) {
95           AreaReference ar = new AreaReference(arearef);
96           setFirstRow((short)ar.getCells()[0].getRow());
97           setFirstColumn((short)ar.getCells()[0].getCol());
98           setLastRow((short)ar.getCells()[1].getRow());
99           setLastColumn((short)ar.getCells()[1].getCol());
100          setFirstColRelative(!ar.getCells()[0].isColAbsolute());
101          setLastColRelative(!ar.getCells()[1].isColAbsolute());
102          setFirstRowRelative(!ar.getCells()[0].isRowAbsolute());
103          setLastRowRelative(!ar.getCells()[1].isRowAbsolute());
104          
105      }
106  
107      public AreaPtg(byte [] data, int offset)
108      {
109          offset++;
110          field_1_first_row    = LittleEndian.getShort(data, 0 + offset);
111          field_2_last_row     = LittleEndian.getShort(data, 2 + offset);
112          field_3_first_column = LittleEndian.getShort(data, 4 + offset);
113          field_4_last_column  = LittleEndian.getShort(data, 6 + offset);
114          //System.out.println(toString());
115      }
116  
117      public String toString()
118      {
119          StringBuffer buffer = new StringBuffer();
120  
121          buffer.append("AreaPtg\n");
122          buffer.append("firstRow = " + getFirstRow()).append("\n");
123          buffer.append("lastRow  = " + getLastRow()).append("\n");
124          buffer.append("firstCol = " + getFirstColumn()).append("\n");
125          buffer.append("lastCol  = " + getLastColumn()).append("\n");
126          buffer.append("firstColRowRel= "
127                        + isFirstRowRelative()).append("\n");
128          buffer.append("lastColRowRel = "
129                        + isLastRowRelative()).append("\n");
130          buffer.append("firstColRel   = " + isFirstColRelative()).append("\n");
131          buffer.append("lastColRel    = " + isLastColRelative()).append("\n");
132          return buffer.toString();
133      }
134  
135      public void writeBytes(byte [] array, int offset) {
136          array[offset] = (byte) (sid + ptgClass);
137          LittleEndian.putShort(array,offset+1,field_1_first_row);
138          LittleEndian.putShort(array,offset+3,field_2_last_row);
139          LittleEndian.putShort(array,offset+5,field_3_first_column);
140          LittleEndian.putShort(array,offset+7,field_4_last_column);        
141      }
142  
143      public int getSize()
144      {
145          return SIZE;
146      }
147  
148      /**
149       * @return the first row in the area
150       */
151      public short getFirstRow()
152      {
153          return field_1_first_row;
154      }
155  
156      /**
157       * sets the first row
158       * @param row number (0-based)
159       */
160      public void setFirstRow(short row)
161      {
162          field_1_first_row = row;
163      }
164  
165      /**
166       * @return last row in the range (x2 in x1,y1-x2,y2)
167       */
168      public short getLastRow()
169      {
170          return field_2_last_row;
171      }
172  
173      /**
174       * @param last row number in the area 
175       */
176      public void setLastRow(short row)
177      {
178          field_2_last_row = row;
179      }
180  
181      /**
182       * @return the first column number in the area.
183       */
184      public short getFirstColumn()
185      {
186          return column.getShortValue(field_3_first_column);
187      }
188  
189      /**
190       * @return the first column number + the options bit settings unstripped
191       */
192      public short getFirstColumnRaw()
193      {
194          return field_3_first_column;
195      }
196  
197      /**
198       * @return whether or not the first row is a relative reference or not.
199       */
200      public boolean isFirstRowRelative()
201      {
202          return rowRelative.isSet(field_3_first_column);
203      }
204      
205      /**
206       * sets the first row to relative or not
207       * @param rel is relative or not.
208       */
209      public void setFirstRowRelative(boolean rel) {
210          field_3_first_column=rowRelative.setShortBoolean(field_3_first_column,rel);
211      }
212  
213      /**
214       * @return isrelative first column to relative or not
215       */
216      public boolean isFirstColRelative()
217      {
218          return colRelative.isSet(field_3_first_column);
219      }
220      
221      /**
222       * set whether the first column is relative 
223       */
224      public void setFirstColRelative(boolean rel) {
225          field_3_first_column=colRelative.setShortBoolean(field_3_first_column,rel);
226      }
227  
228      /**
229       * set the first column in the area
230       */
231      public void setFirstColumn(short column)
232      {
233          field_3_first_column = column;   // fixme
234      }
235  
236      /**
237       * set the first column irespective of the bitmasks
238       */
239      public void setFirstColumnRaw(short column)
240      {
241          field_3_first_column = column;
242      }
243  
244      /**
245       * @return lastcolumn in the area
246       */
247      public short getLastColumn()
248      {
249          return column.getShortValue(field_4_last_column);
250      }
251  
252      /**
253       * @return last column and bitmask (the raw field)
254       */
255      public short getLastColumnRaw()
256      {
257          return field_4_last_column;
258      }
259  
260      /**
261       * @return last row relative or not
262       */
263      public boolean isLastRowRelative()
264      {
265          return rowRelative.isSet(field_4_last_column);
266      }
267      
268      /**
269       * set whether the last row is relative or not
270       * @param last row relative
271       */
272      public void setLastRowRelative(boolean rel) {
273          field_4_last_column=rowRelative.setShortBoolean(field_4_last_column,rel);
274      }
275  
276      /**
277       * @return lastcol relative or not
278       */
279      public boolean isLastColRelative()
280      {
281          return colRelative.isSet(field_4_last_column);
282      }
283      
284      /**
285       * set whether the last column should be relative or not
286       */
287      public void setLastColRelative(boolean rel) {
288          field_4_last_column=colRelative.setShortBoolean(field_4_last_column,rel);
289      }
290      
291  
292      /**
293       * set the last column in the area
294       */
295      public void setLastColumn(short column)
296      {
297          field_4_last_column = column;   // fixme
298      }
299  
300      /**
301       * set the last column irrespective of the bitmasks
302       */
303      public void setLastColumnRaw(short column)
304      {
305          field_4_last_column = column;
306      }
307  
308      public String toFormulaString(SheetReferences refs)
309      {
310           return (new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative())).toString() + ":" +
311                  (new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString();
312      }
313  
314      public byte getDefaultOperandClass() {
315          return Ptg.CLASS_REF;
316      }
317      
318      public Object clone() {
319        AreaPtg ptg = new AreaPtg();
320        ptg.field_1_first_row = field_1_first_row;
321        ptg.field_2_last_row = field_2_last_row;
322        ptg.field_3_first_column = field_3_first_column;
323        ptg.field_4_last_column = field_4_last_column;
324        return ptg;
325      }
326  
327  }
328