📄 sheet.java
字号:
}
debug( "new value: " + rr.toString() );
wc.cell.value = rr;
waveCells.remove( wc.cell ); // no problem with enumeration changes?
//#ifndef NOGUI
if( canvas != null )
canvas.repaintCell( wc.cell.i, wc.cell.j );
//#endif
}
}
level++;
}
waveCells = null;
}
void markDepended(Cell cell, int level ) throws CircularReferenceException {
if( pathCells.containsKey( cell ) )
throw new CircularReferenceException();
pathCells.put( cell, cell );
changedCells.remove( cell ); // this will remove crosslinked cells
WaveCell wavecell = (WaveCell) waveCells.get( cell );
if( wavecell == null || (wavecell != null && wavecell.level < level) ) {
// this cell hasn't been added yet
// ... or there's a longer path to it
wavecell = new WaveCell( cell, level );
waveCells.put( cell, wavecell );
for( int i=refTable.size()-1; i>=0; i-- ) {
Dependency dep = (Dependency) refTable.elementAt( i );
// is cell within dependency source range?
if(
cell.i >= dep.i1 && cell.i <= dep.i2 &&
cell.j >= dep.j1 && cell.j <= dep.j2
)
markDepended( getCell( dep.i3, dep.j3 ), level+1 );
}
}
// else if( wavecell.level <= level ) // already added and not a circular ref
pathCells.remove( cell );
}
// used to recalculate references when deleting/adding rows/columns
// public void shiftAllReferences(int I1, int J1, int dI, int dJ) {
// for( Enumeration cll = cells.elements(); cll.hasMoreElements() ; ) {
// Cell cell = (Cell) cll.nextElement();
// if( cell.isFormula() || (cell.formula instanceof Reference) ) {
// LispObject formula = cell.formula.shiftReferences( I1, J1, dI, dJ );
// if( refChanged ) {
// cell.formula = formula;
// try {
// cell.value = formula.evaluateSExp();
// }
// catch( EvaluateException ee ) {
// cell.value = FormulaError.ERROR;
// }
// putCell( cell );
// }
// }
// }
// }
// insert rows/columns (no formula modifications)
public void insertCells( int I1, int J1, int dI, int dJ ) {
Hashtable _cells = createHashtable( cells.size() );
refTable.removeAllElements();
changedCells.clear();
// will copy cells into a new hastable
for( Enumeration cll = cells.elements(); cll.hasMoreElements() ; ) {
Cell cell = (Cell) cll.nextElement();
boolean fDelete = false;
if( cell.i >= I1 ) {
if( /*(dI > 0 && cell.i1+dI >= rows) || */(dI < 0 && cell.i+dI < I1) )
fDelete = true; // remove it - outside the area or inside cut area
else
cell.i += dI;
}
if( cell.j >= J1 ) {
if( /*(dJ > 0 && cell.j1+dJ >= columns) || */(dJ < 0 && cell.j+dJ < J1) )
fDelete = true; // remove it - outside the area or inside cut area
else
cell.j += dJ;
}
if( !fDelete ) {
LispObject newformula = cell.formula.shiftReferences( I1, J1, dI, dJ );
if( cell.formula != newformula ) {
cell.formula = newformula;
changedCells.put( cell, cell );
}
_cells.put( cell, cell );
addRef( cell.formula, cell.i, cell.j );
}
}
cells = _cells;
// copy row/columns height/width
Hashtable hh = rows;
for( Enumeration cll = hh.elements(); cll.hasMoreElements() ; ) {
RowColumn rw = (RowColumn) cll.nextElement();
if( dI > 0 && rw.index >= I1 ) {
hh.remove( rw );
rw.index += dI;
hh.put( rw, rw );
}
else if( dI < 0 ) {
if( rw.index >= I1 ) {
hh.remove( rw );
rw.index += dI;
hh.put( rw, rw );
}
else if( rw.index >= I1-dI ) {
hh.remove( rw );
}
}
}
hh = columns;
for( Enumeration cll = hh.elements(); cll.hasMoreElements() ; ) {
RowColumn rw = (RowColumn) cll.nextElement();
if( dJ > 0 && rw.index >= J1 ) {
hh.remove( rw );
rw.index += dJ;
hh.put( rw, rw );
}
else if( dJ < 0 ) {
if( rw.index >= J1 ) {
hh.remove( rw );
rw.index += dJ;
hh.put( rw, rw );
}
else if( rw.index >= J1-dJ ) {
hh.remove( rw );
}
}
}
}
public void copyCell1( int i, int j, int di, int dj ) {
if( di == 0 && dj == 0 ) return;
int newI = i+di;
int newJ = j+dj;
Cell cell = getCell( i, j );
// FIXME movereferences must return new object, if it's old - not changed
// LispObject formula = cell.formula.cloneReferences();
// /*boolean recalc = */formula.moveReferences( di, dj );
LispObject formula = cell.formula.moveReferences( di, dj );
Cell newcell = new Cell( newI, newJ, formula, cell.format );
// if( recalc ) {
// try {
// newcell.value = formula.evaluateSExp();
// }
// catch( EvaluateException ee ) {
// newcell.value = FormulaError.ERROR;
// }
// }
putCell( newcell );
}
// public void copyRow1( int i, int di ) {
// for( int j=0; j<CanvasHandler1.MAX_COLUMNS_ROWS[AXIS_X]; j++ )
// copyCell1( i,j, di,0 );
// }
//
// uses proxy pattern
public Cell getCell( int i, int j ) {
Cell cell = (Cell) cells.get( new Integer( (i<<16)|j ) );
if( cell == null ) {
cell = new Cell( i, j, NIL, 0 );
}
return cell;
}
public LispObject getCellValue( int i, int j ) {
return getCell( i, j ).value;
}
public RowColumn getRowColumn( int axis, int ij ) {
RowColumn rw = (RowColumn) (axis == AXIS_Y ? rows : columns ).get( new Integer(ij) );
if( rw == null )
return new RowColumn( ij, defaultWidthHeight[axis] );
return rw;
}
/* ====================================================
* loading/saving
*/
//#ifndef NOGUI
public void saveToRecordStore( String rsname ) throws RecordStoreException {
// debug("saving sheet: <"+rsname+">");
ByteArrayOutputStream ba = null;
DataOutputStream ds = null;
byte bcontent[] = null;
String content = null;
try {
content = toString();
// debug("sheet to write: "+content);
ba = new ByteArrayOutputStream( content.length() );
ds = new DataOutputStream( ba );
try {
ds.writeUTF( content );
}
catch( IOException ee ) {
throw new RecordStoreException( "writeUTF() error" );
}
}
finally {
// free resources
content = null;
if( ds != null ) {
try {
ds.flush();
ds.close();
}
catch( IOException ee ) {
debug("exception when closing DataOutputStream");
}
ds = null;
}
if( ba != null ) {
try {
ba.flush();
bcontent = ba.toByteArray();
ba.close();
}
catch( IOException ee ) {
debug("exception when closing ByteArrayOutputStream");
}
ba = null;
}
}
// delete the old one
try {
// debug("deleting old store");
RecordStore.deleteRecordStore( rsname );
}
catch( RecordStoreException ee ) {
// debug("can't delete: "+ee.getMessage());
}
// create new
// debug("opening recordstore");
RecordStore rs = RecordStore.openRecordStore( rsname, true );
// and write to
try {
// debug("writting record");
rs.addRecord( bcontent, 0, bcontent.length );
}
finally {
if( rs != null ) {
rs.closeRecordStore();
rs = null;
}
}
// debug("writting <"+rsname+"> complete");
}
public static Sheet readFromRecordStore( String rsname ) throws RecordStoreException, ParseException, EvaluateException {
RecordStore rs = RecordStore.openRecordStore( rsname, false );
byte bcontent[] = null;
try {
bcontent = rs.getRecord( 1 );
}
finally {
if( rs != null ) {
rs.closeRecordStore();
rs = null;
}
}
ByteArrayInputStream ba = null;
DataInputStream ds = null;
String content = null;
try {
ba = new ByteArrayInputStream( bcontent );
ds = new DataInputStream( ba );
try {
content = ds.readUTF();
// debug("sheet content being read: "+content);
}
catch( IOException ee ) {
throw new RecordStoreException( "readUTF() error" );
}
}
finally {
// free resources
if( ds != null ) {
try {
ds.close();
}
catch( IOException ee ) {
}
}
if( ba != null ) {
try {
ba.close();
}
catch( IOException ee ) {
}
}
}
return sheetFromList( (FunctorList) LispObject.parseSExp( content ) );
}
public static void deleteFromRecordStore( String rsname ) throws RecordStoreException {
RecordStore.deleteRecordStore( rsname );
}
static QuotedList listSheets() {
String ss[] = RecordStore.listRecordStores();
int size = ss == null? 0 : ss.length;
LispObject val[] = new LispObject[size];
for( int i=0; i<size; i++ )
val[i] = new StringAtom( ss[i] );
return new QuotedList( val );
}
//#endif
}
class RowColumn extends LispObject {
short index; // row/column number
// int position; // abs coordinate in characters/64
int width_height; // in characters/64
// hashcode(), equals()
RowColumn( int _index, int _width_height ) {
index = (short)_index;
width_height = _width_height;
}
public int typeNumber() {
return TYPE_ROWCOLUMN;
}
// complex atom interface
public FunctorList toList() {
return new FunctorList2(
Bfunc.BFUNC.table[Bfunc.INDEX_ROWCOLUMN],
new ShortAtom( index ),
new ShortAtom( width_height )
);
}
public String getName( int axis ) {
if( axis == 0 ) {
return Reference.columnName( index );
}
return Integer.toString( index+1 );
}
public int hashCode() {
return index;
}
public boolean equals(Object obj) {
return index == obj.hashCode();
}
}
class Dependency {
short i1,j1,i2,j2; // source
short i3,j3; // depended
Dependency( int _i1, int _j1, int _i2, int _j2, int _i3, int _j3 ) {
i1 = (short)_i1; j1 = (short)_j1;
i2 = (short)_i2; j2 = (short)_j2;
i3 = (short)_i3; j3 = (short)_j3;
}
}
class WaveCell {
Cell cell;
int level;
WaveCell( Cell _cell, int _level ) {
cell = _cell;
level = _level;
}
}
class CircularReferenceException extends Exception {
CircularReferenceException() {
super("Circular reference");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -