diff --git a/src/com/bytezone/diskbrowser/visicalc/Abs.java b/src/com/bytezone/diskbrowser/visicalc/Abs.java index 6a1d407..9aa8a08 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Abs.java +++ b/src/com/bytezone/diskbrowser/visicalc/Abs.java @@ -2,33 +2,14 @@ package com.bytezone.diskbrowser.visicalc; public class Abs extends Function { - private boolean hasChecked; - private double value = 0; - Abs (Sheet parent, String text) { super (parent, text); } @Override - public boolean hasValue () + public void calculate () { - if (!hasChecked) - calculate (); - return hasValue; - } - - @Override - public double getValue () - { - return hasValue () ? value : 0; - } - - private void calculate () - { - hasChecked = true; - hasValue = true; - Expression exp = new Expression (parent, functionText); value = Math.abs (exp.getValue ()); } diff --git a/src/com/bytezone/diskbrowser/visicalc/And.java b/src/com/bytezone/diskbrowser/visicalc/And.java index 57d0d64..e95b21a 100644 --- a/src/com/bytezone/diskbrowser/visicalc/And.java +++ b/src/com/bytezone/diskbrowser/visicalc/And.java @@ -9,8 +9,8 @@ class And extends Function } @Override - public double getValue () + public void calculate () { - return 0; + value = 0; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Cell.java b/src/com/bytezone/diskbrowser/visicalc/Cell.java index e223ffe..78dea82 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Cell.java +++ b/src/com/bytezone/diskbrowser/visicalc/Cell.java @@ -28,6 +28,7 @@ class Cell implements Comparable, Value { this.parent = parent; this.address = address; + type = CellType.VALUE; // default to VALUE, formatting may change it } public boolean isValue () @@ -110,8 +111,8 @@ class Cell implements Comparable, Value String getText (int colWidth, char defaultFormat) { // cell may have been created when formatted but no type set - if (type == null) - return justify ("", colWidth); + // if (type == null) + // return justify ("", colWidth); switch (type) { @@ -122,47 +123,43 @@ class Cell implements Comparable, Value return justify (repeat, colWidth); case VALUE: - if (hasValue ()) - { - Double value = getValue (); - if (Double.isNaN (value)) - return justify ("", colWidth); + if (value.isError () || value.isNaN ()) + return justify (value.getText (), colWidth); - char format = cellFormat != ' ' ? cellFormat : defaultFormat; - if (format == 'I') - { - String integerFormat = String.format ("%%%d.0f", colWidth); - return String.format (integerFormat, value); - } - else if (format == '$') - { - String currencyFormat = String.format ("%%%d.%ds", colWidth, colWidth); - return String.format (currencyFormat, nf.format (value)); - } - else if (format == '*') - { - String graphFormat = String.format ("%%-%d.%ds", colWidth, colWidth); - // this is not finished - return String.format (graphFormat, "********************"); - } - else - { - // this could be improved - String numberFormat = String.format ("%%%d.3f", colWidth + 4); - String val = String.format (numberFormat, value); - while (val.endsWith ("0")) - val = ' ' + val.substring (0, val.length () - 1); - if (val.endsWith (".")) - val = ' ' + val.substring (0, val.length () - 1); - if (val.length () > colWidth) - val = val.substring (val.length () - colWidth); - return val; - } + Double thisValue = value.getValue (); + + char format = cellFormat != ' ' ? cellFormat : defaultFormat; + if (format == 'I') + { + String integerFormat = String.format ("%%%d.0f", colWidth); + return String.format (integerFormat, thisValue); + } + else if (format == '$') + { + String currencyFormat = String.format ("%%%d.%ds", colWidth, colWidth); + return String.format (currencyFormat, nf.format (thisValue)); + } + else if (format == '*') + { + String graphFormat = String.format ("%%-%d.%ds", colWidth, colWidth); + // this is not finished + return String.format (graphFormat, "********************"); + } + else + { + // this could be improved + String numberFormat = String.format ("%%%d.3f", colWidth + 4); + String val = String.format (numberFormat, thisValue); + while (val.endsWith ("0")) + val = ' ' + val.substring (0, val.length () - 1); + if (val.endsWith (".")) + val = ' ' + val.substring (0, val.length () - 1); + if (val.length () > colWidth) + val = val.substring (val.length () - colWidth); + return val; } - // else - // return justify ("", colWidth); } - return getError (); + return getText (); } private String justify (String text, int colWidth) @@ -177,40 +174,48 @@ class Cell implements Comparable, Value return (String.format (labelFormat, text)); } - @Override - public boolean hasValue () - { - if (type == CellType.VALUE) - return value.hasValue (); - return false; - } - - // this should be called when doing calculations @Override public double getValue () { - if (type != CellType.VALUE) - return 0; - + assert type == CellType.VALUE; return value.getValue (); } @Override - public String getError () + public String getText () { - return value.getError (); + assert type == CellType.VALUE; + return value.getText (); } - void calculate () + @Override + public boolean isError () { + assert type == CellType.VALUE; + return value.isError (); + } + + @Override + public boolean isNaN () + { + assert type == CellType.VALUE; + return value.isNaN (); + } + + @Override + public void calculate () + { + assert type == CellType.VALUE; if (expressionText == null) { System.out.printf ("%s null expression text %n", address); - value = Function.getInstance (parent, "@ERROR()"); + value = Function.getInstance (parent, "@ERROR"); } else - // could use Number or Cell for simple Values + // should use Number or Cell for simple Values value = new Expression (parent, expressionText); + + value.calculate (); } @Override diff --git a/src/com/bytezone/diskbrowser/visicalc/Count.java b/src/com/bytezone/diskbrowser/visicalc/Count.java index 405f711..43ff191 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Count.java +++ b/src/com/bytezone/diskbrowser/visicalc/Count.java @@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc; class Count extends Function { private final Range range; - private boolean hasChecked; - private double count = 0; public Count (Sheet parent, String text) { @@ -13,33 +11,20 @@ class Count extends Function } @Override - public boolean hasValue () + public void calculate () { - if (!hasChecked) - calculate (); - return hasValue; - } - - @Override - public double getValue () - { - return hasValue () ? count : 0; - } - - private void calculate () - { - hasChecked = true; - hasValue = false; - + value = 0; for (Address address : range) { Cell cell = parent.getCell (address); - if (cell != null && cell.hasValue ()) + if (cell == null || cell.isError () || cell.isNaN ()) { - hasValue = true; - if (cell.getValue () != 0.0) - count++; + isError = true; + break; } + + if (cell.getValue () != 0.0) + value++; } } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Error.java b/src/com/bytezone/diskbrowser/visicalc/Error.java index 922a794..de74c9d 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Error.java +++ b/src/com/bytezone/diskbrowser/visicalc/Error.java @@ -8,15 +8,15 @@ class Error extends Function } @Override - public boolean hasValue () + public boolean isError () { - return false; + return true; } @Override - public String getError () + public boolean isNaN () { - return "@Error"; + return true; } @Override @@ -24,4 +24,9 @@ class Error extends Function { return 0; } + + @Override + public void calculate () + { + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Expression.java b/src/com/bytezone/diskbrowser/visicalc/Expression.java index 2b7f5e8..780e023 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Expression.java +++ b/src/com/bytezone/diskbrowser/visicalc/Expression.java @@ -32,7 +32,8 @@ class Expression implements Value private final List operators = new ArrayList (); private final List signs = new ArrayList (); - private boolean hasValue; + protected boolean isError; + private double value; public Expression (Sheet parent, String text) { @@ -112,14 +113,13 @@ class Expression implements Value } assert values.size () > 0; - hasValue = true; } @Override - public double getValue () + public void calculate () { Value thisValue = values.get (0); - double value = thisValue == null ? 0 : values.get (0).getValue (); + value = thisValue == null ? 0 : values.get (0).getValue (); String sign = signs.get (0); if (sign.equals ("(-)")) @@ -146,21 +146,36 @@ class Expression implements Value else if (operator.equals ("^")) value = Math.pow (value, nextValue); } + } + + @Override + public boolean isNaN () + { + return Double.isNaN (value); + } + + @Override + public String getText () + { + if (isNaN ()) + return "NaN"; + if (isError ()) + return "Error"; + return ""; + } + + @Override + public boolean isError () + { + return isError; + } + + @Override + public double getValue () + { return value; } - @Override - public boolean hasValue () - { - return hasValue; - } - - @Override - public String getError () - { - return hasValue ? "" : "Error"; - } - private String checkBrackets (String input) { String line = input.trim (); diff --git a/src/com/bytezone/diskbrowser/visicalc/Function.java b/src/com/bytezone/diskbrowser/visicalc/Function.java index 6e676c0..e3ad8c0 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Function.java +++ b/src/com/bytezone/diskbrowser/visicalc/Function.java @@ -32,7 +32,9 @@ abstract class Function implements Value protected final Sheet parent; protected String functionText; - protected boolean hasValue; + + protected boolean isError; + protected double value; static Function getInstance (Sheet parent, String text) { @@ -95,19 +97,37 @@ abstract class Function implements Value // get function's parameter string int pos = text.indexOf ('('); if (pos >= 0) - this.functionText = text.substring (pos + 1, text.length () - 1); + functionText = text.substring (pos + 1, text.length () - 1); + else + functionText = ""; } @Override - public boolean hasValue () + public boolean isError () { - return hasValue; + return isError; } @Override - public String getError () + public boolean isNaN () { - return hasValue ? "" : "Error"; + return Double.isNaN (value); + } + + @Override + public double getValue () + { + return value; + } + + @Override + public String getText () + { + if (isNaN ()) + return "NaN"; + if (isError ()) + return "Error"; + return ""; } protected Range getRange (String text) diff --git a/src/com/bytezone/diskbrowser/visicalc/If.java b/src/com/bytezone/diskbrowser/visicalc/If.java index c43b4b8..6121900 100644 --- a/src/com/bytezone/diskbrowser/visicalc/If.java +++ b/src/com/bytezone/diskbrowser/visicalc/If.java @@ -15,25 +15,27 @@ class If extends Function int pos1 = functionText.indexOf (','); int pos2 = functionText.indexOf (',', pos1 + 1); + condition = new Condition (parent, functionText.substring (0, pos1)); + textTrue = functionText.substring (pos1 + 1, pos2); textFalse = functionText.substring (pos2 + 1); } @Override - public double getValue () + public void calculate () { if (condition.getResult ()) { if (expTrue == null) expTrue = new Expression (parent, textTrue); - return expTrue.getValue (); + value = expTrue.getValue (); } else { if (expFalse == null) expFalse = new Expression (parent, textFalse); - return expFalse.getValue (); + value = expFalse.getValue (); } } diff --git a/src/com/bytezone/diskbrowser/visicalc/Int.java b/src/com/bytezone/diskbrowser/visicalc/Int.java index bb47ecb..3e5dcf0 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Int.java +++ b/src/com/bytezone/diskbrowser/visicalc/Int.java @@ -9,8 +9,9 @@ public class Int extends Function } @Override - public double getValue () + public void calculate () { - return 0; + Expression exp = new Expression (parent, functionText); + value = (int) exp.getValue (); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/IsError.java b/src/com/bytezone/diskbrowser/visicalc/IsError.java index 8077342..9f5ec12 100644 --- a/src/com/bytezone/diskbrowser/visicalc/IsError.java +++ b/src/com/bytezone/diskbrowser/visicalc/IsError.java @@ -2,22 +2,18 @@ package com.bytezone.diskbrowser.visicalc; class IsError extends Function { - boolean firstTime = true; - Cell cell; + Expression expression; public IsError (Sheet parent, String text) { super (parent, text); + expression = new Expression (parent, functionText); } @Override - public double getValue () + public void calculate () { - if (firstTime) - { - firstTime = false; - cell = parent.getCell (new Address (functionText)); - } - return cell == null ? 1 : 0; + value = expression.getValue (); + isError = expression.isError (); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/IsNa.java b/src/com/bytezone/diskbrowser/visicalc/IsNa.java index cff1910..30dc907 100644 --- a/src/com/bytezone/diskbrowser/visicalc/IsNa.java +++ b/src/com/bytezone/diskbrowser/visicalc/IsNa.java @@ -2,15 +2,18 @@ package com.bytezone.diskbrowser.visicalc; public class IsNa extends Function { + Expression expression; IsNa (Sheet parent, String text) { super (parent, text); + expression = new Expression (parent, functionText); } @Override - public double getValue () + public void calculate () { - return 0; + value = expression.getValue (); + isError = expression.isError (); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Lookup.java b/src/com/bytezone/diskbrowser/visicalc/Lookup.java index 4b8bc90..0793fda 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Lookup.java +++ b/src/com/bytezone/diskbrowser/visicalc/Lookup.java @@ -3,7 +3,7 @@ package com.bytezone.diskbrowser.visicalc; class Lookup extends Function { Range range; - boolean hasValue; + // boolean hasValue; String sourceText; String rangeText; Expression source; @@ -21,14 +21,13 @@ class Lookup extends Function } // need a mechanism to return NA and ERROR - @Override - public boolean hasValue () - { - return hasValue; - } + // @Override + // public boolean hasValue () + // { + // return hasValue; + // } - @Override - public double getValue () + public void calculate () { double sourceValue = source.getValue (); @@ -43,10 +42,10 @@ class Lookup extends Function if (target != null) if (range.isVertical ()) - return parent.getCell (target.nextColumn ()).getValue (); + value = parent.getCell (target.nextColumn ()).getValue (); else - return parent.getCell (target.nextRow ()).getValue (); + value = parent.getCell (target.nextRow ()).getValue (); - return 0; + // return 0; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Max.java b/src/com/bytezone/diskbrowser/visicalc/Max.java index ce7a733..863f4b8 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Max.java +++ b/src/com/bytezone/diskbrowser/visicalc/Max.java @@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc; class Max extends Function { private final Range range; - private boolean hasChecked; - private double max = Double.MIN_VALUE; public Max (Sheet parent, String text) { @@ -13,34 +11,31 @@ class Max extends Function } @Override - public boolean hasValue () + public void calculate () { - if (!hasChecked) - calculate (); - return hasValue; - } - - @Override - public double getValue () - { - return hasValue () ? max : 0; - } - - private void calculate () - { - hasChecked = true; - hasValue = false; + value = Double.MIN_VALUE; + isError = false; + int totalChecked = 0; for (Address address : range) { Cell cell = parent.getCell (address); - if (cell != null && cell.hasValue ()) + if (cell == null) + continue; + + if (cell.isError () || cell.isNaN ()) { - hasValue = true; - double value = cell.getValue (); - if (value > max) - max = value; + isError = true; + break; } + + double temp = cell.getValue (); + if (temp > value) + value = temp; + totalChecked++; } + + if (totalChecked == 0) + isError = true; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Min.java b/src/com/bytezone/diskbrowser/visicalc/Min.java index 5cd3dde..8763f58 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Min.java +++ b/src/com/bytezone/diskbrowser/visicalc/Min.java @@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc; class Min extends Function { private final Range range; - private boolean hasChecked; - private double min = Double.MAX_VALUE; public Min (Sheet parent, String text) { @@ -13,34 +11,31 @@ class Min extends Function } @Override - public boolean hasValue () + public void calculate () { - if (!hasChecked) - calculate (); - return hasValue; - } - - @Override - public double getValue () - { - return hasValue () ? min : 0; - } - - private void calculate () - { - hasChecked = true; - hasValue = false; + value = Double.MAX_VALUE; + isError = false; + int totalChecked = 0; for (Address address : range) { Cell cell = parent.getCell (address); - if (cell != null && cell.hasValue ()) + if (cell == null) + continue; + + if (cell.isError () || cell.isNaN ()) { - hasValue = true; - double value = cell.getValue (); - if (value < min) - min = value; + isError = true; + break; } + + double temp = cell.getValue (); + if (temp < value) + value = temp; + totalChecked++; } + + if (totalChecked == 0) + isError = true; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Na.java b/src/com/bytezone/diskbrowser/visicalc/Na.java index c1a5237..055a9b0 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Na.java +++ b/src/com/bytezone/diskbrowser/visicalc/Na.java @@ -8,15 +8,15 @@ public class Na extends Function } @Override - public boolean hasValue () + public boolean isError () { - return false; + return true; } @Override - public String getError () + public boolean isNaN () { - return "@NA"; + return true; } @Override @@ -24,4 +24,9 @@ public class Na extends Function { return 0; } + + @Override + public void calculate () + { + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Npv.java b/src/com/bytezone/diskbrowser/visicalc/Npv.java index f7ee6ed..95ede29 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Npv.java +++ b/src/com/bytezone/diskbrowser/visicalc/Npv.java @@ -8,9 +8,6 @@ public class Npv extends Function private final Expression valueExp; private final Range range; - private boolean hasChecked; - private final double value = 0; - Npv (Sheet parent, String text) { super (parent, text); @@ -24,32 +21,23 @@ public class Npv extends Function } @Override - public boolean hasValue () + public void calculate () { - if (!hasChecked) - calculate (); - return hasValue; - } - - @Override - public double getValue () - { - return hasValue () ? value : 0; - } - - private void calculate () - { - hasChecked = true; - hasValue = false; + value = 0; for (Address address : range) { Cell cell = parent.getCell (address); - if (cell != null && cell.hasValue ()) + if (cell == null) + continue; + + if (cell.isError () || cell.isNaN ()) { - hasValue = true; - // calculate something + isError = true; + break; } + + double temp = cell.getValue (); } } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Number.java b/src/com/bytezone/diskbrowser/visicalc/Number.java index 0d5a5d7..e30fdfb 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Number.java +++ b/src/com/bytezone/diskbrowser/visicalc/Number.java @@ -2,26 +2,37 @@ package com.bytezone.diskbrowser.visicalc; class Number implements Value { - private double value; - private boolean hasValue; + double value; + boolean isError; public Number (String text) { try { - this.value = Double.parseDouble (text); - hasValue = true; + value = Double.parseDouble (text); } catch (NumberFormatException e) { - hasValue = false; + isError = true; } } @Override - public boolean hasValue () + public boolean isError () { - return hasValue; + return isError; + } + + @Override + public boolean isNaN () + { + return Double.isNaN (value); + } + + @Override + public String toString () + { + return String.format ("Number: %f", value); } @Override @@ -31,14 +42,13 @@ class Number implements Value } @Override - public String getError () + public String getText () { - return hasValue ? "" : "@NA"; + return null; } @Override - public String toString () + public void calculate () { - return String.format ("Number: %f", value); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Or.java b/src/com/bytezone/diskbrowser/visicalc/Or.java index 1d475a9..61751c2 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Or.java +++ b/src/com/bytezone/diskbrowser/visicalc/Or.java @@ -9,8 +9,8 @@ class Or extends Function } @Override - public double getValue () + public void calculate () { - return 0; + value = 0; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Pi.java b/src/com/bytezone/diskbrowser/visicalc/Pi.java index fc8a2ba..5739787 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Pi.java +++ b/src/com/bytezone/diskbrowser/visicalc/Pi.java @@ -8,8 +8,8 @@ class Pi extends Function } @Override - public double getValue () + public void calculate () { - return 3.1415926536; + value = 3.1415926536; } } diff --git a/src/com/bytezone/diskbrowser/visicalc/Sheet.java b/src/com/bytezone/diskbrowser/visicalc/Sheet.java index b5fb32e..4fa4364 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Sheet.java +++ b/src/com/bytezone/diskbrowser/visicalc/Sheet.java @@ -14,6 +14,7 @@ public class Sheet private static final Pattern addressPattern = Pattern.compile ("([AB]?[A-Z])([0-9]{1,3}):"); private static final byte END_OF_LINE_TOKEN = (byte) 0x8D; + private static final int FORMAT_LENGTH = 3; private final Map rowOrderCells = new TreeMap (); private final Map columnOrderCells = new TreeMap (); @@ -266,7 +267,8 @@ public class Sheet String format = ""; while (line.startsWith ("/")) { - String fmt = line.substring (0, 3); + String fmt = line.substring (0, FORMAT_LENGTH); + line = line.substring (FORMAT_LENGTH); if (fmt.equals ("/TH") || fmt.equals ("/TV")) // lock titles ?? { @@ -275,7 +277,6 @@ public class Sheet else currentCell.format (fmt); // formatting command - line = line.substring (3); format += fmt; } diff --git a/src/com/bytezone/diskbrowser/visicalc/Sum.java b/src/com/bytezone/diskbrowser/visicalc/Sum.java index 08f1643..99b1478 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Sum.java +++ b/src/com/bytezone/diskbrowser/visicalc/Sum.java @@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc; class Sum extends Function { private final Range range; - private boolean hasChecked; - private double sum = 0; public Sum (Sheet parent, String text) { @@ -13,32 +11,21 @@ class Sum extends Function } @Override - public boolean hasValue () - { - if (!hasChecked) - calculate (); - return hasValue; - } - - @Override - public double getValue () - { - return hasValue () ? sum : 0; - } - public void calculate () { - hasChecked = true; - hasValue = false; - + value = 0; for (Address address : range) { Cell cell = parent.getCell (address); - if (cell != null && cell.hasValue ()) + if (cell == null) + continue; + + if (cell.isError () || cell.isNaN ()) { - hasValue = true; - sum += cell.getValue (); + isError = true; + break; } + value += cell.getValue (); } } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Value.java b/src/com/bytezone/diskbrowser/visicalc/Value.java index ca3ee74..06638c9 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Value.java +++ b/src/com/bytezone/diskbrowser/visicalc/Value.java @@ -2,9 +2,15 @@ package com.bytezone.diskbrowser.visicalc; interface Value { - public boolean hasValue (); + // public boolean hasValue (); public double getValue (); - public String getError (); + public String getText (); + + public boolean isError (); + + public boolean isNaN (); + + public void calculate (); } \ No newline at end of file