⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reference.java

📁 类似于Windows上的Excel
💻 JAVA
字号:
/*
 * MC2 -- j2me spreadsheet
 *
 * Copyright (c) 2004-2006 Michael Zemljanukha (mixaz@mail.ru)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package com.wapindustrial.calc;
/* * Reference.java * * Created on February 26, 2004, 3:35 PM */public class Reference extends LispObject {
    static final byte ABS_I1 = 0x01;    static final byte ABS_J1 = 0x02;    static final byte ABS_I2 = 0x04;    static final byte ABS_J2 = 0x08;    static final byte BAD_REF = 0x10;        final short i1,j1,i2,j2;    final byte absFlags;              // absolute/relative flags        /** Without normalization (used in (selection))     */        Reference( int _i1, int _j1, int _i2, int _j2 ) {        i1 = (short)_i1; j1 = (short)_j1;        i2 = (short)_i2; j2 = (short)_j2;
        absFlags = 0;    }        Reference( int i1, int j1, int i2, int j2, int absFlags ) {        
        if (i1 > i2) {
            int ii = i1;
            i1 = i2;
            i2 = ii;
            absFlags = (byte) ((absFlags & ~(ABS_I1 | ABS_I2)) | (absFlags & ABS_I1 << 2) | (absFlags & ABS_I2 >> 2));
        }
        if (j1 > j2) {
            int jj = j1;
            j1 = j2;
            j2 = jj;
            absFlags = (byte) ((absFlags & ~(ABS_J1 | ABS_J2)) | (absFlags & ABS_J1 << 2) | (absFlags & ABS_J2 >> 2));
        }
//        if (i1 == i2) {
//            absFlags = (byte) ((absFlags & ~ABS_I2) | ((absFlags & ABS_I1) << 2));
//        }
//        if (j1 == j2) {
//            absFlags = (byte) ((absFlags & ~ABS_J2) | ((absFlags & ABS_J1) << 2));
//        }
        
        this.i1 = (byte)i1;
        this.j1 = (byte)j1;
        this.i2 = (byte)i2;
        this.j2 = (byte)j2;
        this.absFlags = (byte) absFlags;
            }        // not an atom! just a mix of functor/atom    // this evaluation is implemented for experessions (ops and lisp as well)    // functor going to manumulate with references must not evaluate them before ops    public LispObject evaluateSExp() throws EvaluateException {        // this for atoms & list, calculate functions for functors        if( (absFlags&BAD_REF) != 0 )            return FormulaError.REF_ERROR;
//#ifndef NOGUI                return CanvasHandler1.canvasHandler.getCellValue( i1, j1 );
//#else
//#     return NIL;        
//#endif            }    //    public LispObject convertToType( int type ) throws EvaluateException {//        if( (absFlags&BAD_REF) != 0 )//            throw new EvaluateException( "bad cell reference" );//        LispObject value = CanvasHandler1.canvasHandler.getCellValue( i1, j1 );//        return value.convertToType( type );//    }    //    public LispObject getReferredValue() {//        return getReferredValue0().getReferredValue();//    }    /** Gets value of the first cell in the referred range     * @return Cell.value or REF_ERROR     */        public FunctorList toList() {        return new FunctorListN(
            Bfunc.BFUNC.table[Bfunc.INDEX_REF],            new LispObject[] {                new ShortAtom( i1 ),                 new ShortAtom( j1 ),                new ShortAtom( i2 ),                new ShortAtom( j2 ),                new ShortAtom( absFlags )            }        );    }            /** Used to represent atoms (and lists) in worksheets formulas.     * The representation must be supported by Operator.parseFormula(),     * this is related interfaces.     * To be overrided by implementations.     * @param sb Buffer to write to. To get a string use toFormulaString()     */        public void toFormulaBuffer( StringBuffer sb ) {        sb.append( rangeAddress( i1,j1, i2, j2, absFlags ) );    }//    public void toValueBuffer( StringBuffer sb, int format ) {//        LispObject value = getReferredValue();//        value.toValueBuffer( sb, format );//    }//        public int typeNumber() {        return TYPE_REFERENCE;    }        public LispObject cloneReferences() {        return new Reference( i1,j1,i2,j2,absFlags );                // for immutable items    }        /**     *  Description of the Method     *     *@param  j  Description of the Parameter     *@return    Description of the Return Value     */    public static String columnName(int j) {        StringBuffer name = new StringBuffer(2);        final int nn = 'Z' - 'A' + 1;        int n1 = j / nn;        if (n1 > 0) {            name.append((char) ('A' + n1 - 1));        }        j %= nn;        name.append((char) ('A' + j));        return name.toString();    }    public static String cellAddress(int i, int j, int absolute) {        StringBuffer sb = new StringBuffer(10);        if ((absolute & ABS_J1) != 0) {            sb.append('$');        }        sb.append(columnName(j));        if ((absolute & ABS_I1) != 0) {            sb.append('$');        }        sb.append(String.valueOf(i + 1));        return sb.toString();    }    public static String rangeAddress(int i1, int j1, int i2, int j2, int absolute) {        StringBuffer sb = new StringBuffer(cellAddress(i1, j1, absolute));        if (i1 != i2 || j1 != j2 || (absolute&0x3) != (absolute>>2)) {            sb.append(':');            sb.append(cellAddress(i2, j2, absolute >> 2));        }        return sb.toString();    }    public static Reference parseAddress(String ss) throws FormulaParseException {        byte sss[] = ss.toUpperCase().getBytes();        int ii = 0;        char cc;        try {            byte abs = 0;            final int nn = 'Z' - 'A' + 1;            int col = -1;            int row = 0;                        // read column number            if (sss[0] == '$') {                ii = 1;                abs = ABS_J1;            }            while (!(
//#ifdef ISDIGIT            		
//#            		isDigit(cc = (char) (sss[ii]))
//#else
            		Character.isDigit(cc = (char) (sss[ii]))
//#endif					
			|| cc == '$')) {                if (cc < 'A' || cc > 'Z') {                    throw new Exception();                }                ii++;                int ncc = cc - 'A';                // second pass                if( col != -1 ) {                    col = (col+1) * nn + ncc;                }                else {                    col = ncc;                }                if (col >= nn * (nn+1)) {                    // only 2 chars in column name allowed                    throw new Exception();                }                // only 2 chars in column name are allowed            }            if( col < 0 ) {                throw new Exception();            }            // read row number            if (cc == '$') {                ii++;                abs |= ABS_I1;            }            while (ii < sss.length &&
//#ifdef ISDIGIT            		
//#            		isDigit(cc = (char) (sss[ii]))
//#else            		
            		Character.isDigit(cc = (char) (sss[ii]))
//#endif            		
			) {                row *= 10;                row += (short) (cc - '0');                ii++;            }            row--;            if (row < 0) {                throw new Exception();            }            if (ii == sss.length) {                return new Reference(row, col, row, col, abs|(abs<<2));            }            if (cc == ':') {                //		ii++;                if (ss.indexOf(':', ii + 1) != -1) {                    // more then 1 occurency of ':'                    throw new Exception();                }                Reference rrr = parseAddress(ss.substring(ii + 1));                return new Reference(row,col,rrr.i1,rrr.j1,((rrr.absFlags << 2) | abs));            }            // there are characters after digits            if (ii != sss.length) {                throw new Exception();            }        } catch (Exception e) {                debug( "exception catched:" );                debug( e.getMessage() );        }        throw new FormulaParseException("illegal cell address [" + ss + "]");    }    // returns true if changed    public LispObject shiftReferences(int I1, int J1, int dI, int dJ) {        boolean rr;//        boolean rr1 = false;//        boolean rr2 = false;        boolean inter = false;//        for (int i = 0; i < funcargs.length; i++) {////	    rr = rr || funcargs[i].shiftReferences(I1, J1, dI, dJ);     ! error !//	    rr1 = funcargs[i].shiftReferences(I1, J1, dI, dJ);//            rr = rr || rr1;	//!!! see below//        }//        int i1 = this.i1;
        int j1 = this.j1;
        int i2 = this.i2;
        int j2 = this.j2;
        
        if (dI < 0) {            if (i1 >= I1 && i2 < I1 - dI) {                // range within deleted area
                return new Reference(i1,j1,i2,j2,absFlags|BAD_REF);            }            inter = Reference.intersect(i1, j1, i2, j2, I1, J1, (short) (I1 - dI), j2);            // check _before_ deleting            if (i1 >= I1 - dI) {                i1 += dI;            } else if (i1 > I1) {                i1 = I1;            }            if (i2 >= I1 - dI) {                i2 += dI;            } else if (i2 > I1) {                i2 = I1;            }        } else if (dI > 0) {            if (i1 >= I1) {                i1 += dI;            }            if (i2 >= I1) {                i2 += dI;            }            inter = Reference.intersect(i1, j1, i2, j2, I1, J1, I1 + dI, j2);            // check _after_ inserting        }        // dI = 0        if (dJ < 0) {            if (j1 >= J1 && j2 < J1 - dJ) {                return new Reference(i1,j1,i2,j2,absFlags|BAD_REF);
            }            inter = Reference.intersect(i1, j1, i2, j2, I1, J1, i2, J1 - dJ);            // check _before_ deleting            if (j1 >= J1 - dJ) {                j1 += dJ;            } else if (j1 > J1) {                j1 = J1;            }            if (j2 >= J1 - dJ) {                j2 += dJ;            } else if (j2 > J1) {                j2 = J1;            }        } else if (dJ > 0) {            if (j1 >= J1) {                j1 += dJ;            }            if (j2 >= J1) {                j2 += dJ;            }            inter = Reference.intersect(i1, j1, i2, j2, I1, J1, i2, J1 + dJ);        }        // dJ = 0        rr = inter || i1 != this.i1 || j1 != this.j1 || i2 != this.i2 || j2 != this.j2;        // formula has changed ?
        if(rr)
            return new Reference(i1,j1,i2,j2,absFlags);
        // no changes        return this;    }    /**     *  shifts references according to absolute flags (being used in copy/paste operations)     *     *@param  di  Description of the Parameter     *@param  dj  Description of the Parameter     *@return true if reference changed (not formula but refers to othe cell), needs value recalculation     */    public LispObject moveReferences(int di, int dj) {        boolean rr;
        int i1 = this.i1;        int j1 = this.j1;
        int i2 = this.i2;
        int j2 = this.j2;
        
        if ((absFlags & ABS_I1) == 0) {            i1 += di;        }        if ((absFlags & ABS_J1) == 0) {            j1 += dj;        }        if ((absFlags & ABS_I2) == 0) {            i2 += di;        }        if ((absFlags & ABS_J2) == 0) {            j2 += dj;        }        rr = (absFlags & (ABS_I1 | ABS_J1 | ABS_I2 | ABS_J2)) != (ABS_I1 | ABS_J1 | ABS_I2 | ABS_J2);
        // formula has changed ?
        if(rr)
            return new Reference(i1,j1,i2,j2,absFlags);
        // no changes
        return this;
    }

        public static final boolean intersect(
                int x1, int y1, int x2, int y2,
                int xx1, int yy1, int xx2, int yy2) {
            int xxx1 = x1 > xx1 ? x1 : xx1;
            int xxx2 = x2 < xx2 ? x2 : xx2;
            int yyy1 = y1 > yy1 ? y1 : yy1;
            int yyy2 = y2 < yy2 ? y2 : yy2;
            return xxx1 < xxx2 && yyy1 < yyy2;
        }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -