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