1 /* ====================================================================
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 ==================================================================== */
17
18 package org.apache.poi.hssf.record.formula;
19
20 import org.apache.poi.hssf.record.RecordInputStream;
21 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
22 import org.apache.poi.hssf.util.CellReference;
23 import org.apache.poi.hssf.util.RangeAddress;
24 import org.apache.poi.hssf.util.SheetReferences;
25 import org.apache.poi.util.BitField;
26 import org.apache.poi.util.BitFieldFactory;
27 import org.apache.poi.util.LittleEndian;
28
29 /**
30 * Title: Reference 3D Ptg <P>
31 * Description: Defined a cell in extern sheet. <P>
32 * REFERENCE: <P>
33 * @author Libin Roman (Vista Portal LDT. Developer)
34 * @author Jason Height (jheight at chariot dot net dot au)
35 * @version 1.0-pre
36 */
37 public final class Ref3DPtg extends OperandPtg {
38 public final static byte sid = 0x3a;
39 private final static int SIZE = 7; // 6 + 1 for Ptg
40 private short field_1_index_extern_sheet;
41 /** The row index - zero based unsigned 16 bit value */
42 private int field_2_row;
43 /** Field 2
44 * - lower 8 bits is the zero based unsigned byte column index
45 * - bit 16 - isRowRelative
46 * - bit 15 - isColumnRelative
47 */
48 private int field_3_column;
49 private BitField rowRelative = BitFieldFactory.getInstance(0x8000);
50 private BitField colRelative = BitFieldFactory.getInstance(0x4000);
51
52 /** Creates new AreaPtg */
53 public Ref3DPtg() {}
54
55 public Ref3DPtg(RecordInputStream in) {
56 field_1_index_extern_sheet = in.readShort();
57 field_2_row = in.readShort();
58 field_3_column = in.readShort();
59 }
60
61 public Ref3DPtg(String cellref, short externIdx ) {
62 CellReference c= new CellReference(cellref);
63 setRow(c.getRow());
64 setColumn(c.getCol());
65 setColRelative(!c.isColAbsolute());
66 setRowRelative(!c.isRowAbsolute());
67 setExternSheetIndex(externIdx);
68 }
69
70 public String toString() {
71 CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(),!isColRelative());
72 StringBuffer sb = new StringBuffer();
73 sb.append(getClass().getName());
74 sb.append(" [");
75 sb.append("sheetIx=").append(getExternSheetIndex());
76 sb.append(" ! ");
77 sb.append(cr.formatAsString());
78 sb.append("]");
79 return sb.toString();
80 }
81
82 public void writeBytes(byte [] array, int offset) {
83 array[ 0 + offset ] = (byte) (sid + getPtgClass());
84 LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
85 LittleEndian.putShort(array, 3 + offset , (short)getRow());
86 LittleEndian.putShort(array, 5 + offset , (short)getColumnRaw());
87 }
88
89 public int getSize() {
90 return SIZE;
91 }
92
93 public short getExternSheetIndex(){
94 return field_1_index_extern_sheet;
95 }
96
97 public void setExternSheetIndex(short index){
98 field_1_index_extern_sheet = index;
99 }
100
101 public int getRow() {
102 return field_2_row;
103 }
104
105 public void setRow(int row) {
106 field_2_row = row;
107 }
108
109 public int getColumn() {
110 return field_3_column & 0xFF;
111 }
112
113 public int getColumnRaw() {
114 return field_3_column;
115 }
116
117 public boolean isRowRelative()
118 {
119 return rowRelative.isSet(field_3_column);
120 }
121
122 public void setRowRelative(boolean rel) {
123 field_3_column=rowRelative.setBoolean(field_3_column,rel);
124 }
125
126 public boolean isColRelative()
127 {
128 return colRelative.isSet(field_3_column);
129 }
130
131 public void setColRelative(boolean rel) {
132 field_3_column=colRelative.setBoolean(field_3_column,rel);
133 }
134 public void setColumn(short column) {
135 field_3_column &= 0xFF00;
136 field_3_column |= column & 0xFF;
137 }
138
139 public void setColumnRaw(short column) {
140 field_3_column = column;
141 }
142
143 /* public String getArea(){
144 RangeAddress ra = new RangeAddress("");
145
146 String result = (ra.numTo26Sys(getColumn()) + (getRow() + 1));
147
148 return result;
149 }*/
150
151 public void setArea(String ref){
152 RangeAddress ra = new RangeAddress(ref);
153
154 String from = ra.getFromCell();
155
156 setColumn((short) (ra.getXPosition(from) -1));
157 setRow((short) (ra.getYPosition(from) -1));
158
159 }
160
161 // TODO - find a home for this method
162 // There is already a method on HSSFWorkbook called getSheetName but it seems to do something different.
163 static String getSheetName(HSSFWorkbook book, int externSheetIndex) {
164 // TODO - there are 3 ways this method can return null. Is each valid?
165 if (book == null) {
166 return null;
167 }
168
169 SheetReferences refs = book.getSheetReferences();
170 if (refs == null) {
171 return null;
172 }
173 return refs.getSheetName(externSheetIndex);
174 }
175 /**
176 * @return text representation of this cell reference that can be used in text
177 * formulas. The sheet name will get properly delimited if required.
178 */
179 public String toFormulaString(HSSFWorkbook book)
180 {
181 StringBuffer retval = new StringBuffer();
182 String sheetName = getSheetName(book, field_1_index_extern_sheet);
183 if(sheetName != null) {
184 SheetNameFormatter.appendFormat(retval, sheetName);
185 retval.append( '!' );
186 }
187 retval.append((new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).formatAsString());
188 return retval.toString();
189 }
190
191 public byte getDefaultOperandClass() {
192 return Ptg.CLASS_REF;
193 }
194 }