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   
69   /**
70    * Specifies a rectangular area of cells A1:A4 for instance.
71    * @author  andy
72    */
73   
74   public class AreaPtg
75       extends Ptg
76   {
77       public final static short sid  = 0x25;
78       private final static int  SIZE = 9;
79       private short             field_1_first_row;
80       private short             field_2_last_row;
81       private short             field_3_first_column;
82       private short             field_4_last_column;
83       
84       private BitField         rowRelative = new BitField(0x8000);
85       private BitField         colRelative = new BitField(0x4000);
86       private BitField         column      = new BitField(0x3FFF);
87   
88       
89      
90       protected AreaPtg(String arearef) {
91           //int[] xyxy = ReferenceUtil.getXYXYFromAreaRef(arearef);
92           AreaReference ar = new AreaReference(arearef);
93           
94           setFirstRow((short)ar.getCells()[0].getRow());
95           setFirstColumn((short)ar.getCells()[0].getCol());
96           setLastRow((short)ar.getCells()[1].getRow());
97           setLastColumn((short)ar.getCells()[1].getCol());
98           setFirstColRelative(!ar.getCells()[0].isColAbsolute());
99           setLastColRelative(!ar.getCells()[1].isColAbsolute());
100          setFirstRowRelative(!ar.getCells()[0].isRowAbsolute());
101          setLastRowRelative(!ar.getCells()[1].isRowAbsolute());
102          
103      }
104  
105      public AreaPtg(byte [] data, int offset)
106      {
107          offset++;
108          field_1_first_row    = LittleEndian.getShort(data, 0 + offset);
109          field_2_last_row     = LittleEndian.getShort(data, 2 + offset);
110          field_3_first_column = LittleEndian.getShort(data, 4 + offset);
111          field_4_last_column  = LittleEndian.getShort(data, 6 + offset);
112          //System.out.println(toString());
113      }
114  
115      public String toString()
116      {
117          StringBuffer buffer = new StringBuffer();
118  
119          buffer.append("AreaPtg\n");
120          buffer.append("firstRow = " + getFirstRow()).append("\n");
121          buffer.append("lastRow  = " + getLastRow()).append("\n");
122          buffer.append("firstCol = " + getFirstColumn()).append("\n");
123          buffer.append("lastCol  = " + getLastColumn()).append("\n");
124          buffer.append("firstColRowRel= "
125                        + isFirstRowRelative()).append("\n");
126          buffer.append("lastColRowRel = "
127                        + isLastRowRelative()).append("\n");
128          buffer.append("firstColRel   = " + isFirstColRelative()).append("\n");
129          buffer.append("lastColRel    = " + isLastColRelative()).append("\n");
130          return buffer.toString();
131      }
132  
133      public void writeBytes(byte [] array, int offset) {
134          array[offset] = (byte) (sid + ptgClass);
135          LittleEndian.putShort(array,offset+1,field_1_first_row);
136          LittleEndian.putShort(array,offset+3,field_2_last_row);
137          LittleEndian.putShort(array,offset+5,field_3_first_column);
138          LittleEndian.putShort(array,offset+7,field_4_last_column);        
139      }
140  
141      public int getSize()
142      {
143          return SIZE;
144      }
145  
146      /**
147       * @return the first row in the area
148       */
149      public short getFirstRow()
150      {
151          return field_1_first_row;
152      }
153  
154      /**
155       * sets the first row
156       * @param row number (0-based)
157       */
158      public void setFirstRow(short row)
159      {
160          field_1_first_row = row;
161      }
162  
163      /**
164       * @return last row in the range (x2 in x1,y1-x2,y2)
165       */
166      public short getLastRow()
167      {
168          return field_2_last_row;
169      }
170  
171      /**
172       * @param last row number in the area 
173       */
174      public void setLastRow(short row)
175      {
176          field_2_last_row = row;
177      }
178  
179      /**
180       * @return the first column number in the area.
181       */
182      public short getFirstColumn()
183      {
184          return column.getShortValue(field_3_first_column);
185      }
186  
187      /**
188       * @return the first column number + the options bit settings unstripped
189       */
190      public short getFirstColumnRaw()
191      {
192          return field_3_first_column;
193      }
194  
195      /**
196       * @return whether or not the first row is a relative reference or not.
197       */
198      public boolean isFirstRowRelative()
199      {
200          return rowRelative.isSet(field_3_first_column);
201      }
202      
203      /**
204       * sets the first row to relative or not
205       * @param isRelative or not.
206       */
207      public void setFirstRowRelative(boolean rel) {
208          field_3_first_column=rowRelative.setShortBoolean(field_3_first_column,rel);
209      }
210  
211      /**
212       * @return isrelative first column to relative or not
213       */
214      public boolean isFirstColRelative()
215      {
216          return colRelative.isSet(field_3_first_column);
217      }
218      
219      /**
220       * set whether the first column is relative 
221       */
222      public void setFirstColRelative(boolean rel) {
223          field_3_first_column=colRelative.setShortBoolean(field_3_first_column,rel);
224      }
225  
226      /**
227       * set the first column in the area
228       */
229      public void setFirstColumn(short column)
230      {
231          field_3_first_column = column;   // fixme
232      }
233  
234      /**
235       * set the first column irespective of the bitmasks
236       */
237      public void setFirstColumnRaw(short column)
238      {
239          field_3_first_column = column;
240      }
241  
242      /**
243       * @return lastcolumn in the area
244       */
245      public short getLastColumn()
246      {
247          return column.getShortValue(field_4_last_column);
248      }
249  
250      /**
251       * @return last column and bitmask (the raw field)
252       */
253      public short getLastColumnRaw()
254      {
255          return field_4_last_column;
256      }
257  
258      /**
259       * @return last row relative or not
260       */
261      public boolean isLastRowRelative()
262      {
263          return rowRelative.isSet(field_4_last_column);
264      }
265      
266      /**
267       * set whether the last row is relative or not
268       * @param last row relative
269       */
270      public void setLastRowRelative(boolean rel) {
271          field_4_last_column=rowRelative.setShortBoolean(field_4_last_column,rel);
272      }
273  
274      /**
275       * @return lastcol relative or not
276       */
277      public boolean isLastColRelative()
278      {
279          return colRelative.isSet(field_4_last_column);
280      }
281      
282      /**
283       * set whether the last column should be relative or not
284       */
285      public void setLastColRelative(boolean rel) {
286          field_4_last_column=colRelative.setShortBoolean(field_4_last_column,rel);
287      }
288      
289  
290      /**
291       * set the last column in the area
292       */
293      public void setLastColumn(short column)
294      {
295          field_4_last_column = column;   // fixme
296      }
297  
298      /**
299       * set the last column irrespective of the bitmasks
300       */
301      public void setLastColumnRaw(short column)
302      {
303          field_4_last_column = column;
304      }
305  
306      public String toFormulaString()
307      {
308           return (new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative())).toString() + ":" +
309                  (new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString();
310      }
311  
312      public byte getDefaultOperandClass() {
313          return Ptg.CLASS_REF;
314      }
315      
316  }
317