//prepare the original Reference
final Reference orgref = ctx != null ?
(Reference) ctx.getVariableResolver().resolveVariable("zkoss.ss.Ref") : null;
final SheetImpl sheet = orgref != null ?
(SheetImpl) orgref.getSheet() : null;
final Book book = sheet != null ?
sheet.getBook() : (ctx instanceof Book) ? (Book) ctx : null;
final String[] range = parseRange(value);
final String sheetnm1 = range[0];
final String sheetnm2 = range[1];
final String cell1 = range[2];
final String cell2 = range[3];
int[] lt = null;
int[] rb = null;
boolean var1 = false;
boolean var2 = false;
lt = parseCell(cell1);
var1 = (lt == null);
if (cell2 != null) {
rb = parseCell(cell2);
var2 = (lt == null);
} else { //cell2 == null
// cell1 is single col but cell2 is not available, should be a variable
if (!var1 && lt[1] == -1) {
var1 = true;
}
}
if (lt != null && rb != null) {
int l = lt[0];
int t = lt[1];
int absl = lt[2];
int abst = lt[3];
int r = rb[0];
int b = rb[1];
int absr = rb[2];
int absb = rb[3];
if (l > r) {
int tmp = l;
l = r;
r = tmp;
tmp = absl;
absl = absr;
absr = tmp;
lt[0] = l;
lt[2] = absl;
rb[0] = r;
rb[2] = absr;
}
if (t > b) {
int tmp = t;
t = b;
b = tmp;
tmp = abst;
abst = absb;
absb = tmp;
lt[1] = t;
lt[3] = abst;
rb[1] = b;
rb[3] = absb;
}
}
final SheetImpl psheet1 = (book != null && sheetnm1 != null) ?
(SheetImpl)book.lookupSheet(sheetnm1) : sheet;
final SheetImpl psheet2 = (book != null && sheetnm2 != null) ?
(SheetImpl)book.lookupSheet(sheetnm2) : sheet;
// final SheetImpl psheet1 = sheet1 != null ? sheet1 : sheet;
// final SheetImpl psheet2 = sheet2 != null ? sheet2 : sheet;
final boolean abssheet = book != null && (sheetnm1 != null || sheetnm2 != null);
if (cell2 != null) { //a range
if (var1 || var2) {
//prepare Range operator token
operand.setType(TokenType.OP_IN);
operand.setValue(":"); //as a Range operator
if (var1) {
//lookup NameRange
final Range rng = book.lookupNameRange(cell1);
if (rng != null) {
ranges.add(rng);
operand.addOperand(new Token(rng, TokenType.OPERAND, TokenSubtype.RANGE));
} else {
operand.addOperand(new Token(cell1, TokenType.OPERAND, TokenSubtype.VAR));
if (!((BookImpl)book).addVariable(cell1, orgref)) {
throw new XelException("Illegal variable name: "+cell1);
}
}
} else {
final Token token1 =
new Token(cell1, TokenType.OPERAND, TokenSubtype.CELL);
//TODO: matain ref DAG graph
//TODO: How do we handle variable range2d?
// final SheetImpl psheet = sheet1 != null ? sheet1 : sheet;
// final Abacus pabacus = psheet.getBook().getAbacus();
final int left = lt[0];
final int top = lt[1];
final int right = left;
final int bottom = top;
final boolean absleft = lt[2] != 0;
final boolean abstop = lt[3] != 0;
final boolean absright = absleft;
final boolean absbottom = abstop;
final Range rng = psheet1 == null ? RangeRefError.RANGE_REF_ERROR :
new RangeRef(psheet1, null, left, top, right, bottom, absleft, abstop, absright, absbottom, abssheet);
ranges.add(rng);
/* if (orgref != null) {
final Reference precedent = pabacus.addRef(new SimpleRef(psheet, rng, orgrow, orgcol));
orgref.addPrecedent(precedent);
}
*/ token1.setValue(rng);
operand.addOperand(token1);
}
if (var2) {
//lookup NameRange
final Range rng = book.lookupNameRange(cell2);
if (rng != null) {
ranges.add(rng);
operand.addOperand(new Token(rng, TokenType.OPERAND, TokenSubtype.RANGE));
} else {
operand.addOperand(new Token(cell2, TokenType.OPERAND, TokenSubtype.VAR));
if (!((BookImpl)book).addVariable(cell2, orgref)) {
throw new XelException("Illegal variable name: "+cell2);
}
}
} else {
final Token token2 =
new Token(cell2, TokenType.OPERAND, TokenSubtype.CELL);
//TODO: matain ref DAG graph
//TODO: How do we handle variable range2d?
// final SheetImpl psheet = sheet2 != null ? sheet2 : sheet;
// final Abacus pabacus = psheet.getBook().getAbacus();
final int left = rb[0];
final int top = rb[1];
final int right = left;
final int bottom = top;
final boolean absleft = rb[2] != 0;
final boolean abstop = rb[3] != 0;
final boolean absright = absleft;
final boolean absbottom = abstop;
final Range rng =
new RangeRef(psheet2, null, left, top, right, bottom, absleft, abstop, absright, absbottom, abssheet);
ranges.add(rng);
/* if (orgref != null) {
final Reference precedent = pabacus.addRef(new SimpleRef(psheet, rng, orgrow, orgcol));
orgref.addPrecedent(precedent);
}
*/ token2.setValue(rng);
operand.addOperand(token2);
}
} else { //a const cell or a const range
if (sheetnm1 == null || (sheetnm2 == null || sheetnm1.equals(sheetnm2))) { //single sheet
if (cell1.equals(cell2)) { //a cell reference
if (lt[0] == -1 || lt[1] == -1) { //single row || single column
// final SheetImpl psheet = sheet1 != null ? sheet1 : sheet;
// final Abacus pabacus = psheet.getBook().getAbacus();
final int left = lt[0];
final int top = lt[1];
final int right = rb[0];
final int bottom = rb[1];
final boolean absleft = lt[2] != 0;
final boolean abstop = lt[3] != 0;
final boolean absright = rb[2] != 0;
final boolean absbottom = rb[3] != 0;
final Range rng = psheet1 == null ? RangeRefError.RANGE_REF_ERROR :
new RangeRef(psheet1, null, left, top, right, bottom, absleft, abstop, absright, absbottom, abssheet);
ranges.add(rng);
/* if (orgref != null) {
final Reference precedent = pabacus.addRef(new SimpleRef(psheet, rng, orgrow, orgcol));
orgref.addPrecedent(precedent);
}
*/ operand.setValue(rng);
} else { //degrad to single cell
operand.setSubtype(TokenSubtype.CELL);
//TODO: maintain DAG reference
// final SheetImpl psheet = sheet1 != null ? sheet1 : sheet;
// final Abacus pabacus = psheet.getBook().getAbacus();
final int left = lt[0];
final int top = lt[1];
final int right = left;
final int bottom = top;
final boolean absleft = lt[2] != 0;
final boolean abstop = lt[3] != 0;
final boolean absright = absleft;
final boolean absbottom = abstop;
final Range rng = psheet1 == null ? RangeRefError.RANGE_REF_ERROR :
new RangeRef(psheet1, null, left, top, right, bottom, absleft, abstop, absright, absbottom, abssheet);
ranges.add(rng);
/* if (orgref != null) {
final Reference precedent = pabacus.addRef(new SimpleRef(psheet, rng, orgrow, orgcol));
orgref.addPrecedent(precedent);
}
*/ operand.setValue(rng);
}
} else { //a range reference
//TODO: maintain DAG reference
// final SheetImpl psheet = sheet1 != null ? sheet1 : sheet;
// final Abacus pabacus = psheet.getBook().getAbacus();
final int left = lt[0];
final int top = lt[1];
final int right = rb[0];
final int bottom = rb[1];
final boolean absleft = lt[2] != 0;
final boolean abstop = lt[3] != 0;
final boolean absright = rb[2] != 0;
final boolean absbottom = rb[3] != 0;
final Range rng = psheet1 == null ? RangeRefError.RANGE_REF_ERROR :
new RangeRef(psheet1, null, left, top, right, bottom, absleft, abstop, absright, absbottom, abssheet);
ranges.add(rng);
/* if (orgref != null) {
final Reference precedent = pabacus.addRef(new SimpleRef(psheet, rng, orgrow, orgcol));
orgref.addPrecedent((Reference)precedent);
}
*/ operand.setValue(rng);
}
} else { //range 3d
//TODO: maintain DAG reference
//TODO: for each sheet between two sheet name
final int left = lt[0];
final int top = lt[1];
final int right = rb[0];
final int bottom = rb[1];
final boolean absleft = lt[2] != 0;
final boolean abstop = lt[3] != 0;
final boolean absright = rb[2] != 0;
final boolean absbottom = rb[3] != 0;
final Range rng = (psheet1 == null || psheet2 == null) ? RangeRefError.RANGE_REF_ERROR :
new RangeRef(psheet1, psheet2, left, top, right, bottom, absleft, abstop, absright, absbottom, abssheet);
ranges.add(rng);
/* if (orgref != null) {
final Book pbook = sheet1.getBook();
final int from = pbook.indexOfSheet(sheet1);
final int to = pbook.indexOfSheet(sheet2);
final Abacus pabacus = pbook.getAbacus();
final List sheets = book.getSheets();
for (int j=from; j <= to; ++j) {
final SheetImpl psheet = (SheetImpl) sheets.get(j);
final Reference precedent = pabacus.addRef(new SimpleRef(psheet, rng, orgrow, orgcol));
orgref.addPrecedent((Reference)precedent);
}
}
*/ operand.setValue(rng);
}
}
} else if (var1) { //single variable
//lookup NameRange
final Range rng = book.lookupNameRange(cell1);
if (rng != null) {
ranges.add(rng);
operand.setValue(rng);
} else {
operand.setSubtype(TokenSubtype.VAR);