mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-06-27 08:29:31 +00:00
Visicalc improvements
This commit is contained in:
parent
176a03a786
commit
119d8472bd
|
@ -26,7 +26,7 @@ public class VisicalcFile extends AbstractFile
|
|||
|
||||
if (debug)
|
||||
{
|
||||
text.append ("\n\n");
|
||||
text.append ("\n");
|
||||
text.append (sheet.getLines ());
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.bytezone.diskbrowser.visicalc;
|
|||
|
||||
public class Abs extends Function
|
||||
{
|
||||
Expression source;
|
||||
|
||||
Abs (Sheet parent, String text)
|
||||
{
|
||||
super (parent, text);
|
||||
|
@ -10,8 +12,15 @@ public class Abs extends Function
|
|||
@Override
|
||||
public Value calculate ()
|
||||
{
|
||||
Expression exp = new Expression (parent, functionText);
|
||||
value = Math.abs (exp.getValue ());
|
||||
if (source == null)
|
||||
{
|
||||
source = new Expression (parent, functionText);
|
||||
values.add (source);
|
||||
}
|
||||
|
||||
value = Math.abs (source.getValue ());
|
||||
valueType = source.getValueType ();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
17
src/com/bytezone/diskbrowser/visicalc/AbstractValue.java
Normal file
17
src/com/bytezone/diskbrowser/visicalc/AbstractValue.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
public abstract class AbstractValue implements Value
|
||||
{
|
||||
protected final String typeText;
|
||||
|
||||
public AbstractValue (String typeText)
|
||||
{
|
||||
this.typeText = typeText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeText ()
|
||||
{
|
||||
return typeText;
|
||||
}
|
||||
}
|
|
@ -85,10 +85,21 @@ class Address implements Comparable<Address>
|
|||
return "" + (c1 == '@' ? "" : c1) + c2 + row;
|
||||
}
|
||||
|
||||
public String getText ()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getDetails ()
|
||||
{
|
||||
return String.format ("Row:%3d Col:%3d rKey:%5d cKey:%5d", row, column, rowKey,
|
||||
columnKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return String.format ("%-4s %3d %3d %4d", text, row, column, rowKey);
|
||||
return String.format ("%-6s Row:%3d Col:%3d Key:%4d", text, row, column, rowKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class And extends Function
|
||||
{
|
||||
List<Condition> conditions = new ArrayList<Condition> ();
|
||||
|
||||
public And (Sheet parent, String text)
|
||||
{
|
||||
super (parent, text);
|
||||
String list[] = text.split (",");
|
||||
for (String s : list)
|
||||
conditions.add (new Condition (parent, s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value calculate ()
|
||||
{
|
||||
value = 0;
|
||||
for (Condition condition : conditions)
|
||||
if (!condition.getResult ())
|
||||
{
|
||||
value = 0;
|
||||
return this;
|
||||
}
|
||||
value = 1;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
class Cell implements Comparable<Cell>, Value
|
||||
class Cell extends AbstractValue implements Comparable<Cell>
|
||||
{
|
||||
private static final DecimalFormat nf = new DecimalFormat ("#####0.00");
|
||||
// private static final DecimalFormat nf = new DecimalFormat ("#####0.00");
|
||||
private static final String line = "+----------------------------------------"
|
||||
+ "--------------------------------------------+";
|
||||
|
||||
final Address address;
|
||||
private final Address address;
|
||||
private final Sheet parent;
|
||||
private CellType cellType;
|
||||
private char cellFormat = ' ';
|
||||
private final Format format = new Format ();
|
||||
|
||||
private char repeatingChar;
|
||||
private String repeatingText;
|
||||
private String repeat = "";
|
||||
private String label;
|
||||
|
||||
|
@ -20,44 +20,58 @@ class Cell implements Comparable<Cell>, Value
|
|||
|
||||
enum CellType
|
||||
{
|
||||
LABEL, REPEATING_CHARACTER, VALUE
|
||||
LABEL, REPEATING_CHARACTER, VALUE, EMPTY
|
||||
}
|
||||
|
||||
public Cell (Sheet parent, Address address)
|
||||
{
|
||||
super ("Cell " + address.text);
|
||||
|
||||
this.parent = parent;
|
||||
this.address = address;
|
||||
|
||||
cellType = CellType.VALUE; // default to VALUE, formatting may change it
|
||||
value = new Number ("0.0");
|
||||
cellType = CellType.EMPTY;
|
||||
}
|
||||
|
||||
void format (String format)
|
||||
Address getAddress ()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
void setFormat (String formatText)
|
||||
{
|
||||
// /FG - general
|
||||
// /FD - default
|
||||
// /FI - integer
|
||||
// /F$ - dollars and cents
|
||||
// /F$ - two decimal places
|
||||
// /FL - left justified
|
||||
// /FR - right justified
|
||||
// /F* - graph (histogram)
|
||||
|
||||
if (format.startsWith ("/F"))
|
||||
this.cellFormat = format.charAt (2);
|
||||
else if (format.startsWith ("/-"))
|
||||
if (formatText.equals ("/TH") || formatText.equals ("/TV")) // lock titles
|
||||
return;
|
||||
|
||||
if (formatText.startsWith ("/F"))
|
||||
{
|
||||
repeatingChar = format.charAt (2);
|
||||
for (int i = 0; i < 20; i++)
|
||||
repeat += repeatingChar;
|
||||
cellType = CellType.REPEATING_CHARACTER;
|
||||
format.cellFormat = formatText.charAt (2);
|
||||
return;
|
||||
}
|
||||
else
|
||||
System.out.printf ("Unexpected format [%s]%n", format);
|
||||
|
||||
if (formatText.startsWith ("/-"))
|
||||
{
|
||||
repeatingText = formatText.substring (2);
|
||||
for (int i = 0; i < 20; i++)
|
||||
repeat += repeatingText;
|
||||
cellType = CellType.REPEATING_CHARACTER;
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.printf ("Unexpected format [%s]%n", formatText);
|
||||
}
|
||||
|
||||
void setValue (String command)
|
||||
{
|
||||
if (command.charAt (0) == '"')
|
||||
if (!command.isEmpty () && command.charAt (0) == '"')
|
||||
{
|
||||
label = command.substring (1);
|
||||
cellType = CellType.LABEL;
|
||||
|
@ -80,7 +94,7 @@ class Cell implements Comparable<Cell>, Value
|
|||
expressionText = "8";
|
||||
|
||||
// IRA.VC
|
||||
if (false)
|
||||
if (true)
|
||||
if (address.rowKey == 66)
|
||||
expressionText = "10";
|
||||
else if (address.rowKey == 130)
|
||||
|
@ -104,75 +118,37 @@ class Cell implements Comparable<Cell>, Value
|
|||
expressionText = "11.9";
|
||||
}
|
||||
|
||||
// format cell value for output
|
||||
String getText (int colWidth, char defaultFormat)
|
||||
{
|
||||
char format = cellFormat != ' ' ? cellFormat : defaultFormat;
|
||||
|
||||
switch (cellType)
|
||||
{
|
||||
case LABEL:
|
||||
return justify (label, colWidth, cellFormat);
|
||||
return format.justify (label, colWidth, format.cellFormat);
|
||||
|
||||
case REPEATING_CHARACTER:
|
||||
return justify (repeat, colWidth, format);
|
||||
return format.justify (repeat, colWidth, ' ');
|
||||
|
||||
case EMPTY:
|
||||
return "";
|
||||
|
||||
case VALUE:
|
||||
if (value.isValueType (ValueType.ERROR) || value.isValueType (ValueType.NA)
|
||||
|| value.isValueType (ValueType.NAN))
|
||||
return justify (value.getText (), colWidth, format);
|
||||
if (value == null)
|
||||
calculate ();
|
||||
return format.format (value, defaultFormat, colWidth);
|
||||
|
||||
Double thisValue = value.getValue ();
|
||||
|
||||
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;
|
||||
}
|
||||
default:
|
||||
assert false;
|
||||
return getText (); // not possible
|
||||
}
|
||||
return getText ();
|
||||
}
|
||||
|
||||
private String justify (String text, int colWidth, char format)
|
||||
{
|
||||
// right justify
|
||||
if (format == 'R' || format == '$' || format == 'I')
|
||||
{
|
||||
String labelFormat = String.format ("%%%d.%ds", colWidth, colWidth);
|
||||
return (String.format (labelFormat, text));
|
||||
}
|
||||
|
||||
// left justify
|
||||
String labelFormat = String.format ("%%-%d.%ds", colWidth, colWidth);
|
||||
return (String.format (labelFormat, text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue ()
|
||||
{
|
||||
if (value == null)
|
||||
calculate ();
|
||||
|
||||
return value.getValue ();
|
||||
}
|
||||
|
||||
|
@ -185,12 +161,18 @@ class Cell implements Comparable<Cell>, Value
|
|||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
if (value == null)
|
||||
calculate ();
|
||||
|
||||
return value.getText ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValueType (ValueType type)
|
||||
{
|
||||
if (value == null)
|
||||
calculate ();
|
||||
|
||||
return value.isValueType (type);
|
||||
}
|
||||
|
||||
|
@ -202,21 +184,106 @@ class Cell implements Comparable<Cell>, Value
|
|||
@Override
|
||||
public Value calculate ()
|
||||
{
|
||||
if (!isCellType (CellType.VALUE))
|
||||
if (value != null && value.isValueType (ValueType.VALUE))
|
||||
return this;
|
||||
|
||||
if (expressionText == null)
|
||||
if (value == null)
|
||||
{
|
||||
System.out.printf ("%s null expression text %n", address);
|
||||
value = Function.getInstance (parent, "@ERROR");
|
||||
if (expressionText == null)
|
||||
expressionText = "";
|
||||
|
||||
Expression expression = new Expression (parent, expressionText);
|
||||
value = expression.size () == 1 ? expression.get (0) : expression;
|
||||
}
|
||||
value.calculate ();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDebugText ()
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
text.append (line);
|
||||
text.append ("\n");
|
||||
text.append (String.format ("| %-21s %s %17s |%n", address.getText (),
|
||||
address.getDetails (), "Format : " + format.cellFormat));
|
||||
text.append (line);
|
||||
text.append ("\n");
|
||||
|
||||
switch (cellType)
|
||||
{
|
||||
case LABEL:
|
||||
text.append (String.format ("| LABEL : %-69s |%n", label));
|
||||
break;
|
||||
|
||||
case REPEATING_CHARACTER:
|
||||
text.append (String.format ("| REPEAT : %-69s |%n", repeatingText));
|
||||
break;
|
||||
|
||||
case EMPTY:
|
||||
text.append (String.format ("| EMPTY : %-69s |%n", ""));
|
||||
break;
|
||||
|
||||
case VALUE:
|
||||
text.append (String.format ("| VALUE : %-69s |%n", expressionText));
|
||||
if (value == null)
|
||||
text.append (String.format ("| Value : %-69s |%n", "null"));
|
||||
// else if (value instanceof Expression)
|
||||
// text.append (getExpressionComponents ((Expression) value, 1));
|
||||
else
|
||||
text.append (getValueText (value, 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
text.append ("Unknown CellType: " + cellType + "\n");
|
||||
}
|
||||
|
||||
text.append (line);
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
private String getValueText (Value value, int depth)
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
||||
String typeText = " " + value.getTypeText ();
|
||||
if (value.isValueType (ValueType.VALUE))
|
||||
{
|
||||
String valueText = String.format ("%f", value.getValue ());
|
||||
text.append (String.format ("| %-10s : %-69s |%n", typeText, valueText));
|
||||
}
|
||||
else
|
||||
{
|
||||
// should use Number or Cell or Function for simple Values
|
||||
value = new Expression (parent, expressionText);
|
||||
value.calculate ();
|
||||
}
|
||||
return this;
|
||||
text.append (
|
||||
String.format ("| %-10s : %-69s |%n", typeText, value.getValueType ()));
|
||||
|
||||
if (value instanceof Expression)
|
||||
text.append (getExpressionComponents ((Expression) value, depth + 1));
|
||||
else if (value instanceof Function)
|
||||
text.append (getFunctionComponents ((Function) value, depth + 1));
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
private String getExpressionComponents (Expression expression, int depth)
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
||||
text.append (String.format ("| Expression : %-69s |%n", expression.fullText ()));
|
||||
for (Value value : expression)
|
||||
text.append (getValueText (value, depth));
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
private String getFunctionComponents (Function function, int depth)
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
||||
text.append (String.format ("| Function : %-69s |%n", function.fullText));
|
||||
for (Value value : function)
|
||||
text.append (getValueText (value, depth));
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -230,11 +297,13 @@ class Cell implements Comparable<Cell>, Value
|
|||
contents = "Labl: " + label;
|
||||
break;
|
||||
case REPEATING_CHARACTER:
|
||||
contents = "Rept: " + repeatingChar;
|
||||
contents = "Rept: " + repeatingText;
|
||||
break;
|
||||
case VALUE:
|
||||
contents = "Exp : " + expressionText;
|
||||
break;
|
||||
case EMPTY:
|
||||
contents = "Empty";
|
||||
}
|
||||
|
||||
return String.format ("[Cell:%5s %s]", address, contents);
|
||||
|
|
|
@ -19,6 +19,7 @@ class Condition
|
|||
public Condition (Sheet parent, String text)
|
||||
{
|
||||
this.parent = parent;
|
||||
// System.out.println (text);
|
||||
|
||||
for (String comp : comparators)
|
||||
{
|
||||
|
@ -54,9 +55,13 @@ class Condition
|
|||
|
||||
conditionExpression.calculate ();
|
||||
valueExpression.calculate ();
|
||||
|
||||
// expressions.add (conditionExpression);
|
||||
// expressions.add (valueExpression);
|
||||
}
|
||||
|
||||
if (conditionExpression.isValueType (ValueType.ERROR) || valueExpression.isValueType (ValueType.ERROR))
|
||||
if (conditionExpression.isValueType (ValueType.ERROR)
|
||||
|| valueExpression.isValueType (ValueType.ERROR))
|
||||
return false;
|
||||
|
||||
double conditionResult = conditionExpression.getValue ();
|
||||
|
@ -84,6 +89,6 @@ class Condition
|
|||
public String toString ()
|
||||
{
|
||||
return String.format ("[cond=%s, op=%s, value=%s]", conditionText, comparator,
|
||||
valueText);
|
||||
valueText);
|
||||
}
|
||||
}
|
|
@ -22,9 +22,9 @@ class Count extends Function
|
|||
if (cell == null || cell.isValueType (ValueType.NA))
|
||||
continue;
|
||||
|
||||
if (cell.isValueType (ValueType.ERROR))
|
||||
if (!cell.isValueType (ValueType.VALUE))
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
valueType = cell.getValueType ();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ class Error extends Function
|
|||
public Error (Sheet parent, String text)
|
||||
{
|
||||
super (parent, text);
|
||||
valueType = ValueType.ERROR;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
class Expression implements Value
|
||||
class Expression extends AbstractValue implements Iterable<Value>
|
||||
{
|
||||
// Expressions:
|
||||
// number
|
||||
|
@ -32,13 +33,15 @@ class Expression implements Value
|
|||
private final List<String> operators = new ArrayList<String> ();
|
||||
private final List<String> signs = new ArrayList<String> ();
|
||||
|
||||
private ValueType valueType;
|
||||
private ValueType valueType = ValueType.VALUE;
|
||||
private double value;
|
||||
private String text;
|
||||
|
||||
public Expression (Sheet parent, String text)
|
||||
{
|
||||
super ("Exp");
|
||||
this.text = text;
|
||||
|
||||
String line = checkBrackets (text);
|
||||
|
||||
int ptr = 0;
|
||||
|
@ -92,7 +95,10 @@ class Expression implements Value
|
|||
ptr += addressText.length ();
|
||||
Cell cell = parent.getCell (addressText);
|
||||
if (cell == null)
|
||||
{
|
||||
System.out.println ("adding NA");
|
||||
values.add (Function.getInstance (parent, "@NA"));
|
||||
}
|
||||
else
|
||||
values.add (parent.getCell (addressText));
|
||||
}
|
||||
|
@ -117,24 +123,44 @@ class Expression implements Value
|
|||
}
|
||||
}
|
||||
|
||||
assert values.size () > 0;
|
||||
// assert values.size () > 0;
|
||||
if (values.size () == 0)
|
||||
System.out.printf ("Nothing[%s]%n", text);
|
||||
}
|
||||
|
||||
int size ()
|
||||
{
|
||||
return values.size ();
|
||||
}
|
||||
|
||||
Value get (int index)
|
||||
{
|
||||
return values.get (index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value calculate ()
|
||||
{
|
||||
if (values.size () == 0)
|
||||
{
|
||||
System.out.println ("nothing to calculate: " + text);
|
||||
return this;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Value thisValue = values.get (0);
|
||||
thisValue.calculate ();
|
||||
if (thisValue.isValueType (ValueType.ERROR))
|
||||
|
||||
value = 0;
|
||||
if (thisValue.isValueType (ValueType.VALUE))
|
||||
value = thisValue.getValue ();
|
||||
else
|
||||
{
|
||||
valueType = thisValue.getValueType ();
|
||||
return this;
|
||||
}
|
||||
|
||||
value = thisValue.isValueType (ValueType.NA) ? 0 : thisValue.getValue ();
|
||||
|
||||
String sign = signs.get (0);
|
||||
if (sign.equals ("(-)"))
|
||||
value *= -1;
|
||||
|
@ -143,14 +169,16 @@ class Expression implements Value
|
|||
{
|
||||
thisValue = values.get (i);
|
||||
thisValue.calculate ();
|
||||
if (thisValue.isValueType (ValueType.ERROR))
|
||||
|
||||
double nextValue = 0;
|
||||
if (thisValue.isValueType (ValueType.VALUE))
|
||||
nextValue = thisValue.getValue ();
|
||||
else
|
||||
{
|
||||
valueType = thisValue.getValueType ();
|
||||
return this;
|
||||
}
|
||||
|
||||
double nextValue = thisValue.isValueType (ValueType.NA) ? 0 : thisValue.getValue ();
|
||||
|
||||
sign = signs.get (i);
|
||||
if (sign.equals ("(-)"))
|
||||
nextValue *= -1;
|
||||
|
@ -169,13 +197,14 @@ class Expression implements Value
|
|||
}
|
||||
|
||||
if (Double.isNaN (value))
|
||||
valueType = ValueType.NAN;
|
||||
valueType = ValueType.ERROR;
|
||||
else
|
||||
valueType = ValueType.VALUE;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
e.printStackTrace ();
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -187,29 +216,6 @@ class Expression implements Value
|
|||
return valueType;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isValue ()
|
||||
// {
|
||||
// return valueType == ValueType.VALUE;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNotAvailable ()
|
||||
// {
|
||||
// return valueType == ValueType.NA;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNotANumber ()
|
||||
// {
|
||||
// return valueType == ValueType.NAN;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isError ()
|
||||
// {
|
||||
// return valueType == ValueType.ERROR;
|
||||
// }
|
||||
@Override
|
||||
public boolean isValueType (ValueType type)
|
||||
{
|
||||
|
@ -219,30 +225,30 @@ class Expression implements Value
|
|||
@Override
|
||||
public double getValue ()
|
||||
{
|
||||
// assert valueType == ValueType.VALUE : "Expression ValueType = " + valueType;
|
||||
return value;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String getText ()
|
||||
// {
|
||||
// return isNotAvailable () ? "NA" : isError () ? "Error" : isNotANumber () ? "NaN" : "";
|
||||
// // return isNotAvailable () ? "NA" : isError () ? "Error" : "";
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
if (valueType == null && values.size () > 0)
|
||||
calculate ();
|
||||
|
||||
if (valueType == null)
|
||||
{
|
||||
System.out.printf ("null valuetype in exp [%s]%n", text);
|
||||
System.out.println (values.size ());
|
||||
}
|
||||
switch (valueType)
|
||||
{
|
||||
case NA:
|
||||
return "NA";
|
||||
case ERROR:
|
||||
return "Error";
|
||||
case NAN:
|
||||
return "NaN";
|
||||
// case NAN:
|
||||
// return "NaN";
|
||||
default:
|
||||
return "";
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,7 +270,7 @@ class Expression implements Value
|
|||
if (rightBracket > leftBracket)
|
||||
{
|
||||
System.out.printf ("**** Unbalanced brackets: left:%d, right:%d ****%n",
|
||||
leftBracket, rightBracket);
|
||||
leftBracket, rightBracket);
|
||||
System.out.println (input);
|
||||
return "@ERROR";
|
||||
}
|
||||
|
@ -324,29 +330,28 @@ class Expression implements Value
|
|||
return text.substring (0, ptr);
|
||||
}
|
||||
|
||||
public String fullText ()
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
||||
int ptr = 0;
|
||||
for (Value value : values)
|
||||
{
|
||||
assert value != null;
|
||||
text.append (signs.get (ptr));
|
||||
text.append (value.getValue ());
|
||||
if (ptr < operators.size ())
|
||||
text.append (operators.get (ptr++));
|
||||
}
|
||||
|
||||
return text.toString ();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
// StringBuilder text = new StringBuilder ();
|
||||
//
|
||||
// int ptr = 0;
|
||||
// for (Value value : values)
|
||||
// {
|
||||
// assert value != null;
|
||||
// text.append (signs.get (ptr));
|
||||
// // value.calculate ();
|
||||
// // if (value.isValue ())
|
||||
// // text.append (value.getValue ());
|
||||
// if (ptr < operators.size ())
|
||||
// {
|
||||
// // System.out.println (operators.get (ptr));
|
||||
// text.append (operators.get (ptr++));
|
||||
// }
|
||||
// }
|
||||
// // System.out.println ("finished building");
|
||||
//
|
||||
// return text.toString ();
|
||||
return "Expression: " + text;
|
||||
return "Expression : " + text;
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
|
@ -355,4 +360,10 @@ class Expression implements Value
|
|||
System.out.println (ex.getValue ());
|
||||
System.out.println (ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Value> iterator ()
|
||||
{
|
||||
return values.iterator ();
|
||||
}
|
||||
}
|
66
src/com/bytezone/diskbrowser/visicalc/Format.java
Normal file
66
src/com/bytezone/diskbrowser/visicalc/Format.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import com.bytezone.diskbrowser.visicalc.Value.ValueType;
|
||||
|
||||
public class Format
|
||||
{
|
||||
private static final DecimalFormat nf = new DecimalFormat ("#####0.00");
|
||||
char cellFormat = ' ';
|
||||
|
||||
String format (Value value, char defaultFormat, int colWidth)
|
||||
{
|
||||
char formatChar = cellFormat != ' ' ? cellFormat : defaultFormat;
|
||||
|
||||
if (!value.isValueType (ValueType.VALUE))
|
||||
{
|
||||
// char formatChar = format.cellFormat != ' ' ? format.cellFormat : defaultFormat;
|
||||
return justify (value.getText (), colWidth, formatChar);
|
||||
}
|
||||
|
||||
if (formatChar == 'I')
|
||||
{
|
||||
String integerFormat = String.format ("%%%d.0f", colWidth);
|
||||
return String.format (integerFormat, value.getValue ());
|
||||
}
|
||||
else if (formatChar == '$')
|
||||
{
|
||||
String currencyFormat = String.format ("%%%d.%ds", colWidth, colWidth);
|
||||
return String.format (currencyFormat, nf.format (value.getValue ()));
|
||||
}
|
||||
else if (formatChar == '*')
|
||||
{
|
||||
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.getValue ());
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
String justify (String text, int colWidth, char format)
|
||||
{
|
||||
// right justify
|
||||
if (format == 'R' || format == '$' || format == 'I')
|
||||
{
|
||||
String labelFormat = String.format ("%%%d.%ds", colWidth, colWidth);
|
||||
return (String.format (labelFormat, text));
|
||||
}
|
||||
|
||||
// left justify
|
||||
String labelFormat = String.format ("%%-%d.%ds", colWidth, colWidth);
|
||||
return (String.format (labelFormat, text));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
// http://www.bricklin.com/history/refcard1.htm
|
||||
// Functions:
|
||||
// @AVERAGE
|
||||
|
@ -21,15 +25,19 @@ package com.bytezone.diskbrowser.visicalc;
|
|||
// @TAN
|
||||
// @ATAN
|
||||
|
||||
abstract class Function implements Value
|
||||
// should Function extend Expression? should it be Iterable<Expression>?
|
||||
abstract class Function extends AbstractValue implements Iterable<Value>
|
||||
{
|
||||
protected final Sheet parent;
|
||||
protected String functionName;
|
||||
protected String functionText;
|
||||
protected String fullText;
|
||||
|
||||
protected ValueType valueType;
|
||||
protected double value;
|
||||
|
||||
protected List<Value> values = new ArrayList<Value> ();
|
||||
|
||||
static Function getInstance (Sheet parent, String text)
|
||||
{
|
||||
if (text.charAt (0) != '@')
|
||||
|
@ -92,7 +100,9 @@ abstract class Function implements Value
|
|||
|
||||
Function (Sheet parent, String text)
|
||||
{
|
||||
super ("Function");
|
||||
this.parent = parent;
|
||||
fullText = text;
|
||||
|
||||
// get function's parameter string
|
||||
int pos = text.indexOf ('(');
|
||||
|
@ -123,7 +133,6 @@ abstract class Function implements Value
|
|||
@Override
|
||||
public double getValue ()
|
||||
{
|
||||
assert valueType == ValueType.VALUE : "Function ValueType = " + valueType;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -136,13 +145,19 @@ abstract class Function implements Value
|
|||
return "NA";
|
||||
case ERROR:
|
||||
return "Error";
|
||||
case NAN:
|
||||
return "NaN";
|
||||
// case NAN:
|
||||
// return "NaN";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Value> iterator ()
|
||||
{
|
||||
return values.iterator ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ class If extends Function
|
|||
public If (Sheet parent, String text)
|
||||
{
|
||||
super (parent, text);
|
||||
// System.out.println (text);
|
||||
|
||||
int pos1 = functionText.indexOf (',');
|
||||
int pos2 = functionText.indexOf (',', pos1 + 1);
|
||||
|
@ -27,29 +28,32 @@ class If extends Function
|
|||
{
|
||||
valueType = ValueType.VALUE;
|
||||
|
||||
// System.out.println (functionText);
|
||||
if (condition.getResult ())
|
||||
{
|
||||
// System.out.println ("true");
|
||||
if (expTrue == null)
|
||||
{
|
||||
expTrue = new Expression (parent, textTrue);
|
||||
values.add (expTrue);
|
||||
}
|
||||
|
||||
expTrue.calculate ();
|
||||
|
||||
if (expTrue.isValueType (ValueType.ERROR) || expTrue.isValueType (ValueType.NA))
|
||||
if (!expTrue.isValueType (ValueType.VALUE))
|
||||
valueType = expTrue.getValueType ();
|
||||
else
|
||||
value = expTrue.getValue ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// System.out.println ("false");
|
||||
if (expFalse == null)
|
||||
{
|
||||
expFalse = new Expression (parent, textFalse);
|
||||
values.add (expFalse);
|
||||
}
|
||||
|
||||
expFalse.calculate ();
|
||||
|
||||
if (expFalse.isValueType (ValueType.ERROR) || expFalse.isValueType (ValueType.NA))
|
||||
if (!expFalse.isValueType (ValueType.VALUE))
|
||||
valueType = expFalse.getValueType ();
|
||||
else
|
||||
value = expFalse.getValue ();
|
||||
|
|
|
@ -13,6 +13,7 @@ public class Int extends Function
|
|||
{
|
||||
Expression exp = new Expression (parent, functionText);
|
||||
value = (int) exp.getValue ();
|
||||
valueType = exp.getValueType ();
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ class IsError extends Function
|
|||
if (cell == null)
|
||||
cell = parent.getCell (functionText);
|
||||
|
||||
value = cell == null ? 1 : 0;
|
||||
value = cell == null ? 1 : cell.isValueType (ValueType.ERROR) ? 1 : 0;
|
||||
valueType = ValueType.VALUE;
|
||||
|
||||
return this;
|
||||
|
|
|
@ -21,7 +21,10 @@ class Lookup extends Function
|
|||
public Value calculate ()
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
source = new Expression (parent, sourceText);
|
||||
values.add (source);
|
||||
}
|
||||
|
||||
source.calculate ();
|
||||
if (!source.isValueType (ValueType.VALUE))
|
||||
|
@ -41,16 +44,16 @@ class Lookup extends Function
|
|||
target = address;
|
||||
}
|
||||
|
||||
if (target != null)
|
||||
if (target == null)
|
||||
valueType = ValueType.NA;
|
||||
else
|
||||
{
|
||||
if (range.isVertical ())
|
||||
value = parent.getCell (target.nextColumn ()).getValue ();
|
||||
else
|
||||
value = parent.getCell (target.nextRow ()).getValue ();
|
||||
Address adjacentAddress =
|
||||
range.isVertical () ? target.nextColumn () : target.nextRow ();
|
||||
Cell adjacentCell = parent.getCell (adjacentAddress);
|
||||
value = adjacentCell.getValue ();
|
||||
valueType = ValueType.VALUE;
|
||||
}
|
||||
else
|
||||
System.out.println ("Target is null!");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ class Max extends Function
|
|||
if (cell == null || cell.isValueType (ValueType.NA))
|
||||
continue;
|
||||
|
||||
if (cell.isValueType (ValueType.ERROR))
|
||||
if (!cell.isValueType (ValueType.VALUE))
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
valueType = cell.getValueType ();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ class Min extends Function
|
|||
if (cell == null || cell.isValueType (ValueType.NA))
|
||||
continue;
|
||||
|
||||
if (cell.isValueType (ValueType.ERROR))
|
||||
if (!cell.isValueType (ValueType.VALUE))
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
valueType = cell.getValueType ();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,9 @@ public class Na extends Function
|
|||
public Na (Sheet parent, String text)
|
||||
{
|
||||
super (parent, text);
|
||||
valueType = ValueType.NA;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isError ()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNotAvailable ()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public double getValue ()
|
||||
{
|
||||
|
|
|
@ -32,9 +32,9 @@ public class Npv extends Function
|
|||
if (cell == null || cell.isValueType (ValueType.NA))
|
||||
continue;
|
||||
|
||||
if (cell.isValueType (ValueType.ERROR))
|
||||
if (!cell.isValueType (ValueType.VALUE))
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
valueType = cell.getValueType ();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
class Number implements Value
|
||||
class Number extends AbstractValue
|
||||
{
|
||||
private double value;
|
||||
private ValueType valueType;
|
||||
|
||||
public Number (String text)
|
||||
{
|
||||
super ("Constant");
|
||||
|
||||
try
|
||||
{
|
||||
value = Double.parseDouble (text);
|
||||
|
@ -15,32 +17,10 @@ class Number implements Value
|
|||
catch (NumberFormatException e)
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
e.printStackTrace ();
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isValue ()
|
||||
// {
|
||||
// return valueType == ValueType.VALUE;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isError ()
|
||||
// {
|
||||
// return valueType == ValueType.ERROR;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNotAvailable ()
|
||||
// {
|
||||
// return valueType == ValueType.NA;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNotANumber ()
|
||||
// {
|
||||
// return valueType == ValueType.NAN;
|
||||
// }
|
||||
@Override
|
||||
public boolean isValueType (ValueType type)
|
||||
{
|
||||
|
@ -59,13 +39,6 @@ class Number implements Value
|
|||
return value;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String getText ()
|
||||
// {
|
||||
// return isNotAvailable () ? "NA" : isError () ? "Error" : isNotANumber () ? "NaN" : "";
|
||||
// // return valueType == ValueType.ERROR ? "Error" : "";
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
|
@ -75,8 +48,8 @@ class Number implements Value
|
|||
return "NA";
|
||||
case ERROR:
|
||||
return "Error";
|
||||
case NAN:
|
||||
return "NaN";
|
||||
// case NAN:
|
||||
// return "NaN";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class Or extends Function
|
||||
{
|
||||
List<Condition> conditions = new ArrayList<Condition> ();
|
||||
|
||||
public Or (Sheet parent, String text)
|
||||
{
|
||||
super (parent, text);
|
||||
String list[] = text.split (",");
|
||||
for (String s : list)
|
||||
conditions.add (new Condition (parent, s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value calculate ()
|
||||
{
|
||||
for (Condition condition : conditions)
|
||||
if (condition.getResult ())
|
||||
{
|
||||
value = 1;
|
||||
return this;
|
||||
}
|
||||
value = 0;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
import com.bytezone.diskbrowser.visicalc.Value.ValueType;
|
||||
import com.bytezone.diskbrowser.visicalc.Cell.CellType;
|
||||
|
||||
public class Sheet
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ public class Sheet
|
|||
private final Map<Integer, Cell> columnOrderCells = new TreeMap<Integer, Cell> ();
|
||||
private final List<String> lines = new ArrayList<String> ();
|
||||
|
||||
private Cell currentCell = null;
|
||||
// private Cell currentCell = null;
|
||||
private char defaultFormat;
|
||||
|
||||
private final Map<Integer, Integer> columnWidths = new TreeMap<Integer, Integer> ();
|
||||
|
@ -116,7 +116,7 @@ public class Sheet
|
|||
|
||||
/S STORAGE COMMANDS
|
||||
/SS SAVE
|
||||
/SL LOAD
|
||||
/SL LOAD (left/right arrow to scroll through catalog)
|
||||
/SD DELETES SPECIFIED FILE ON DISK
|
||||
/SI INITIALIZE A DISK ON SPECIFIED DRIVE
|
||||
/SQ QUITS VISICALC
|
||||
|
@ -149,14 +149,27 @@ public class Sheet
|
|||
{
|
||||
int length = getLineLength (buffer, ptr);
|
||||
String line = HexFormatter.getString (buffer, ptr, length);
|
||||
assert !line.isEmpty ();
|
||||
lines.add (line);
|
||||
processLine (line);
|
||||
|
||||
if (line.startsWith ("/"))
|
||||
doFormat (line);
|
||||
else if (line.startsWith (">")) // GOTO cell
|
||||
processLine (line);
|
||||
else
|
||||
System.out.printf ("Error [%s]%n", line);
|
||||
|
||||
ptr += length + 1; // +1 for end-of-line token
|
||||
}
|
||||
|
||||
// might have to keep recalculating until nothing changes??
|
||||
calculate (recalculationOrder);
|
||||
calculate (recalculationOrder);
|
||||
if (recalculation == 'A') // auto
|
||||
{
|
||||
// recalculationOrder = 'R';
|
||||
// System.out.printf ("Calculation order: %s%n", recalculationOrder);
|
||||
calculate (recalculationOrder);
|
||||
calculate (recalculationOrder);
|
||||
}
|
||||
|
||||
if (false)
|
||||
printDebug ();
|
||||
|
@ -166,70 +179,23 @@ public class Sheet
|
|||
{
|
||||
Map<Integer, Cell> cells = order == 'R' ? rowOrderCells : columnOrderCells;
|
||||
for (Cell cell : cells.values ())
|
||||
if (cell.isValueType (ValueType.VALUE))
|
||||
if (cell.isCellType (CellType.VALUE))
|
||||
cell.calculate ();
|
||||
}
|
||||
|
||||
private int getLineLength (byte[] buffer, int offset)
|
||||
{
|
||||
int ptr = offset;
|
||||
while (buffer[ptr] != END_OF_LINE_TOKEN) // end-of-line token
|
||||
while (buffer[ptr] != END_OF_LINE_TOKEN)
|
||||
ptr++;
|
||||
return ptr - offset;
|
||||
}
|
||||
|
||||
private void processLine (String line)
|
||||
{
|
||||
assert !line.isEmpty ();
|
||||
Cell currentCell = null;
|
||||
|
||||
if (line.startsWith ("/"))
|
||||
{
|
||||
switch (line.charAt (1))
|
||||
{
|
||||
case 'W':
|
||||
// System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
case 'G':
|
||||
switch (line.charAt (2))
|
||||
{
|
||||
case 'R':
|
||||
recalculation = line.charAt (3);
|
||||
break;
|
||||
case 'O':
|
||||
recalculationOrder = line.charAt (3);
|
||||
break;
|
||||
case 'P':
|
||||
// System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
case 'C':
|
||||
columnWidth = Integer.parseInt (line.substring (3));
|
||||
break;
|
||||
case 'F':
|
||||
defaultFormat = line.charAt (3);
|
||||
break;
|
||||
default:
|
||||
System.out.printf ("Unknown global format [%s]%n", line);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
// System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
default:
|
||||
System.out.printf ("Skipping [%s]%n", line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!line.startsWith (">")) // GOTO cell
|
||||
{
|
||||
System.out.printf ("Error [%s]%n", line);
|
||||
return;
|
||||
}
|
||||
|
||||
currentCell = null;
|
||||
|
||||
Matcher m = addressPattern.matcher (line);
|
||||
Matcher m = addressPattern.matcher (line); // <cell address>:<contents>
|
||||
if (m.find ())
|
||||
{
|
||||
Address address = new Address (m.group (1), m.group (2));
|
||||
|
@ -258,7 +224,7 @@ public class Sheet
|
|||
if (line.charAt (2) == 'C' && line.charAt (3) == 'C')
|
||||
{
|
||||
int width = Integer.parseInt (line.substring (4));
|
||||
columnWidths.put (currentCell.address.column, width);
|
||||
columnWidths.put (currentCell.getAddress ().column, width);
|
||||
}
|
||||
else
|
||||
System.out.printf ("Unknown Global:[%s]%n", line);
|
||||
|
@ -270,35 +236,36 @@ public class Sheet
|
|||
String format = "";
|
||||
while (line.startsWith ("/"))
|
||||
{
|
||||
String fmt = line.substring (0, FORMAT_LENGTH);
|
||||
line = line.substring (FORMAT_LENGTH);
|
||||
|
||||
if (fmt.equals ("/TH") || fmt.equals ("/TV")) // lock titles ??
|
||||
if (line.charAt (1) == '-') // repeating label
|
||||
{
|
||||
// ignore
|
||||
currentCell.setFormat (line);
|
||||
line = "";
|
||||
format += line;
|
||||
}
|
||||
else
|
||||
currentCell.format (fmt); // formatting command
|
||||
|
||||
format += fmt;
|
||||
{
|
||||
String fmt = line.substring (0, FORMAT_LENGTH);
|
||||
line = line.substring (FORMAT_LENGTH);
|
||||
currentCell.setFormat (fmt); // formatting command
|
||||
format += fmt;
|
||||
}
|
||||
}
|
||||
|
||||
// if there is anything left it must be an expression
|
||||
if (!line.isEmpty ())
|
||||
currentCell.setValue (line); // expression
|
||||
|
||||
if (false)
|
||||
System.out.printf ("[%s][%-3s][%s]%n", currentCell.address, format, line);
|
||||
System.out.printf ("[%s][%-3s][%s]%n", currentCell.getAddress (), format, line);
|
||||
}
|
||||
|
||||
private void addCell (Cell cell)
|
||||
{
|
||||
rowOrderCells.put (cell.address.rowKey, cell);
|
||||
columnOrderCells.put (cell.address.columnKey, cell);
|
||||
rowOrderCells.put (cell.getAddress ().rowKey, cell);
|
||||
columnOrderCells.put (cell.getAddress ().columnKey, cell);
|
||||
|
||||
if (cell.address.row > highestRow)
|
||||
highestRow = cell.address.row;
|
||||
if (cell.address.column > highestColumn)
|
||||
highestColumn = cell.address.column;
|
||||
highestRow = Math.max (highestRow, cell.getAddress ().row);
|
||||
highestColumn = Math.max (highestColumn, cell.getAddress ().column);
|
||||
}
|
||||
|
||||
Cell getCell (String addressText)
|
||||
|
@ -316,6 +283,44 @@ public class Sheet
|
|||
return rowOrderCells.size ();
|
||||
}
|
||||
|
||||
private void doFormat (String line)
|
||||
{
|
||||
switch (line.charAt (1))
|
||||
{
|
||||
case 'W':
|
||||
// System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
case 'G':
|
||||
switch (line.charAt (2))
|
||||
{
|
||||
case 'R':
|
||||
recalculation = line.charAt (3);
|
||||
break;
|
||||
case 'O':
|
||||
recalculationOrder = line.charAt (3);
|
||||
break;
|
||||
case 'P':
|
||||
// System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
case 'C':
|
||||
columnWidth = Integer.parseInt (line.substring (3));
|
||||
break;
|
||||
case 'F':
|
||||
defaultFormat = line.charAt (3);
|
||||
break;
|
||||
default:
|
||||
System.out.printf ("Unknown global format [%s]%n", line);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
// System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
default:
|
||||
System.out.printf ("Skipping [%s]%n", line);
|
||||
}
|
||||
}
|
||||
|
||||
public String getLines ()
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
@ -376,7 +381,7 @@ public class Sheet
|
|||
|
||||
for (Cell cell : rowOrderCells.values ())
|
||||
{
|
||||
Address cellAddress = cell.address;
|
||||
Address cellAddress = cell.getAddress ();
|
||||
while (lastRow < cellAddress.row)
|
||||
{
|
||||
++lastRow;
|
||||
|
@ -404,6 +409,24 @@ public class Sheet
|
|||
|
||||
text.append (cell.getText (colWidth, defaultFormat));
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
text.append ("\n\n");
|
||||
int last = -1;
|
||||
for (Cell cell : columnOrderCells.values ())
|
||||
{
|
||||
if (last < cell.getAddress ().column)
|
||||
{
|
||||
text.append ("\n *** Column "
|
||||
+ cell.getAddress ().column + " ***\n\n");
|
||||
last = cell.getAddress ().column;
|
||||
}
|
||||
text.append (cell.getDebugText ());
|
||||
text.append ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
|
@ -417,7 +440,7 @@ public class Sheet
|
|||
System.out.println ();
|
||||
System.out.println ("Cells:");
|
||||
for (Cell cell : rowOrderCells.values ())
|
||||
System.out.println (cell);
|
||||
System.out.println (cell.getDebugText ());
|
||||
|
||||
System.out.println ();
|
||||
System.out.println ("Column widths:");
|
||||
|
|
|
@ -22,9 +22,9 @@ class Sum extends Function
|
|||
if (cell == null || cell.isValueType (ValueType.NA))
|
||||
continue;
|
||||
|
||||
if (cell.isValueType (ValueType.ERROR))
|
||||
if (!cell.isValueType (ValueType.VALUE))
|
||||
{
|
||||
valueType = ValueType.ERROR;
|
||||
valueType = cell.getValueType ();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ interface Value
|
|||
{
|
||||
enum ValueType
|
||||
{
|
||||
VALUE, ERROR, NA, NAN
|
||||
VALUE, ERROR, NA
|
||||
}
|
||||
|
||||
public double getValue ();
|
||||
|
@ -16,4 +16,6 @@ interface Value
|
|||
public ValueType getValueType ();
|
||||
|
||||
public Value calculate ();
|
||||
|
||||
public String getTypeText ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user