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   package org.apache.poi.hssf.record.formula;
57   
58   import org.apache.poi.util.LittleEndian;
59   import org.apache.poi.hssf.util.RangeAddress;
60   import org.apache.poi.hssf.util.AreaReference;
61   import org.apache.poi.hssf.util.CellReference;
62   import org.apache.poi.hssf.util.SheetReferences;
63   
64   import org.apache.poi.hssf.model.Workbook;
65   import org.apache.poi.util.BitField;
66   
67   /**
68    * Title:        Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
69    * Description:  Defined a area in Extern Sheet. <P>
70    * REFERENCE:  <P>
71    * @author Libin Roman (Vista Portal LDT. Developer)
72    * @author avik
73    * @author Jason Height (jheight at chariot dot net dot au)
74    * @version 1.0-pre
75    */
76   
77   public class Area3DPtg extends Ptg
78   {
79       public final static byte sid  = 0x3b;
80       private final static int  SIZE = 11; // 10 + 1 for Ptg
81       private short             field_1_index_extern_sheet;
82       private short             field_2_first_row;
83       private short             field_3_last_row;
84       private short             field_4_first_column;
85       private short             field_5_last_column;
86       
87       private BitField         rowRelative = new BitField(0x8000);
88       private BitField         colRelative = new BitField(0x4000);
89   
90       /** Creates new AreaPtg */
91       public Area3DPtg() {}
92      
93      public Area3DPtg(String arearef, short externIdx) {
94           AreaReference ar = new AreaReference(arearef);
95           
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          setExternSheetIndex(externIdx);
105          
106      }
107      public Area3DPtg(byte[] data, int offset)
108      {
109          offset++;
110          field_1_index_extern_sheet = LittleEndian.getShort(data, 0 + offset);
111          field_2_first_row          = LittleEndian.getShort(data, 2 + offset);
112          field_3_last_row           = LittleEndian.getShort(data, 4 + offset);
113          field_4_first_column       = LittleEndian.getShort(data, 6 + offset);
114          field_5_last_column        = LittleEndian.getShort(data, 8 + offset);
115      }
116  
117      public String toString()
118      {
119          StringBuffer buffer = new StringBuffer();
120  
121          buffer.append("AreaPtg\n");
122          buffer.append("Index to Extern Sheet = " + getExternSheetIndex()).append("\n");
123          buffer.append("firstRow = " + getFirstRow()).append("\n");
124          buffer.append("lastRow  = " + getLastRow()).append("\n");
125          buffer.append("firstCol = " + getFirstColumn()).append("\n");
126          buffer.append("lastCol  = " + getLastColumn()).append("\n");
127          buffer.append("firstColRel= "
128                        + isFirstRowRelative()).append("\n");
129          buffer.append("lastColRowRel = "
130                        + isLastRowRelative()).append("\n");
131          buffer.append("firstColRel   = " + isFirstColRelative()).append("\n");
132          buffer.append("lastColRel    = " + isLastColRelative()).append("\n");
133          return buffer.toString();
134      }
135  
136      public void writeBytes(byte [] array, int offset)
137      {
138          array[ 0 + offset ] = (byte) (sid + ptgClass);
139          LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
140          LittleEndian.putShort(array, 3 + offset , getFirstRow());
141          LittleEndian.putShort(array, 5 + offset , getLastRow());
142          LittleEndian.putShort(array, 7 + offset , getFirstColumnRaw());
143          LittleEndian.putShort(array, 9 + offset , getLastColumnRaw());
144      }
145  
146      public int getSize()
147      {
148          return SIZE;
149      }
150  
151      public short getExternSheetIndex(){
152          return field_1_index_extern_sheet;
153      }
154  
155      public void setExternSheetIndex(short index){
156          field_1_index_extern_sheet = index;
157      }
158  
159      public short getFirstRow()
160      {
161          return field_2_first_row;
162      }
163  
164      public void setFirstRow(short row)
165      {
166          field_2_first_row = row;
167      }
168  
169      public short getLastRow()
170      {
171          return field_3_last_row;
172      }
173  
174      public void setLastRow(short row)
175      {
176          field_3_last_row = row;
177      }
178  
179      public short getFirstColumn()
180      {
181          return ( short ) (field_4_first_column & 0xFF);
182      }
183  
184      public short getFirstColumnRaw()
185      {
186          return field_4_first_column;
187      }
188  
189      public boolean isFirstRowRelative()
190      {
191          return rowRelative.isSet(field_4_first_column);
192      }
193      
194      public boolean isFirstColRelative()
195      {
196          return colRelative.isSet(field_4_first_column);
197      }
198  
199      public void setFirstColumn(short column)
200      {
201          field_4_first_column &= 0xFF00;
202          field_4_first_column |= column & 0xFF;
203      }
204  
205      public void setFirstColumnRaw(short column)
206      {
207          field_4_first_column = column;
208      }
209  
210      public short getLastColumn()
211      {
212          return ( short ) (field_5_last_column & 0xFF);
213      }
214  
215      public short getLastColumnRaw()
216      {
217          return field_5_last_column;
218      }
219  
220       public boolean isLastRowRelative()
221      {
222          return rowRelative.isSet(field_5_last_column);
223      }
224      public boolean isLastColRelative()
225      {
226          return colRelative.isSet(field_5_last_column);
227      }
228      
229      public void setLastColumn(short column)
230      {
231          field_5_last_column &= 0xFF00;
232          field_5_last_column |= column & 0xFF;
233      }
234  
235      public void setLastColumnRaw(short column)
236      {
237          field_5_last_column = column;
238      }
239      
240          /**
241       * sets the first row to relative or not
242       * @param isRelative or not.
243       */
244      public void setFirstRowRelative(boolean rel) {
245          field_4_first_column=rowRelative.setShortBoolean(field_4_first_column,rel);
246      }
247  
248      /**
249       * set whether the first column is relative 
250       */
251      public void setFirstColRelative(boolean rel) {
252          field_4_first_column=colRelative.setShortBoolean(field_4_first_column,rel);
253      }
254      
255      /**
256       * set whether the last row is relative or not
257       * @param last row relative
258       */
259      public void setLastRowRelative(boolean rel) {
260          field_5_last_column=rowRelative.setShortBoolean(field_5_last_column,rel);
261      }
262      
263      /**
264       * set whether the last column should be relative or not
265       */
266      public void setLastColRelative(boolean rel) {
267          field_5_last_column=colRelative.setShortBoolean(field_5_last_column,rel);
268      }
269      
270  
271      /*public String getArea(){
272          RangeAddress ra = new RangeAddress( getFirstColumn(),getFirstRow() + 1, getLastColumn(), getLastRow() + 1);
273          String result = ra.getAddress();
274  
275          return result;
276      }*/
277  
278      public void setArea(String ref){
279          RangeAddress ra = new RangeAddress(ref);
280  
281          String from = ra.getFromCell();
282          String to   = ra.getToCell();
283  
284          setFirstColumn((short) (ra.getXPosition(from) -1));
285          setFirstRow((short) (ra.getYPosition(from) -1));
286          setLastColumn((short) (ra.getXPosition(to) -1));
287          setLastRow((short) (ra.getYPosition(to) -1));
288  
289      }
290  
291      public String toFormulaString(SheetReferences refs)
292      {
293          StringBuffer retval = new StringBuffer();
294          if (refs != null) {
295              retval.append(refs.getSheetName(this.field_1_index_extern_sheet));
296              retval.append('!');
297          }
298          retval.append((new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative())).toString()); 
299          retval.append(':');
300          retval.append((new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString());
301          return retval.toString();
302      }
303  
304     public byte getDefaultOperandClass() {
305         return Ptg.CLASS_REF;
306     }
307  
308     public Object clone() {
309       Area3DPtg ptg = new Area3DPtg();
310       ptg.field_1_index_extern_sheet = field_1_index_extern_sheet;
311       ptg.field_2_first_row = field_2_first_row;
312       ptg.field_3_last_row = field_3_last_row;
313       ptg.field_4_first_column = field_4_first_column;
314       ptg.field_5_last_column = field_5_last_column;
315       return ptg;
316     }
317  
318  }
319