dmolony-DiskBrowser/src/com/bytezone/diskbrowser/visicalc/Cell.java
2016-03-06 19:05:32 +11:00

165 lines
4.1 KiB
Java

package com.bytezone.diskbrowser.visicalc;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Cell implements Comparable<Cell>
{
private static final Pattern cellContents =
Pattern.compile ("([-+/*]?)(([A-Z]{1,2}[0-9]{1,3})|([0-9.]+)|(@[^-+/*]+))");
final Address address;
private final Sheet parent;
private String label;
private double value;
private String formula;
private char format = ' ';
private int width;
private char repeatingChar;
private String repeat = "";
private boolean valid;
public Cell (Sheet parent, Address address)
{
this.parent = parent;
this.address = address;
}
void doCommand (String command)
{
// System.out.printf ("Cell command:%s%n", command);
switch (command.charAt (0))
{
case '/':
if (command.charAt (1) == 'F') // format cell
{
// /FG - general
// /FD - default
// /FI - integer
// /F$ - dollars and cents
// /FL - left justified
// /FR - right justified
// /F* - graph
format = command.charAt (2);
if (command.length () > 3 && command.charAt (3) == '"')
label = command.substring (4);
}
else if (command.charAt (1) == '-') // repeating label
{
repeatingChar = command.charAt (2);
for (int i = 0; i < 20; i++)
repeat += repeatingChar;
}
else
System.out.println ("Unknown command: " + command);
break;
case '"':
label = command.substring (1);
break;
default:
if (command.matches ("^[0-9.]+$")) // contains only numbers or .
this.value = Float.parseFloat (command);
else
formula = command;
}
}
boolean hasValue ()
{
return label == null && repeatingChar == 0;
}
char getFormat ()
{
return format;
}
double getValue ()
{
if (valid || formula == null)
return value;
double result = 0.0;
double interim = 0.0;
if (formula.startsWith ("@LOOKUP("))
{
Lookup lookup = new Lookup (parent, formula);
return lookup.getValue ();
}
Matcher m = cellContents.matcher (formula);
while (m.find ())
{
valid = true;
char operator = m.group (1).isEmpty () ? '+' : m.group (1).charAt (0);
if (m.group (3) != null) // address
interim = parent.getValue (m.group (3));
else if (m.group (4) != null) // constant
try
{
interim = Double.parseDouble (m.group (4));
}
catch (NumberFormatException e)
{
System.out.printf ("NFE: %s [%s]%n", m.group (4), formula);
}
else
interim = parent.evaluateFunction (m.group (5)); // function
if (operator == '+')
result += interim;
else if (operator == '-')
result -= interim;
else if (operator == '*')
result *= interim;
else if (operator == '/')
result = interim == 0.0 ? 0 : result / interim;
}
if (valid)
{
value = result;
return result;
}
System.out.println ("?? " + formula);
return value;
}
String value ()
{
if (label != null)
return label;
if (repeatingChar > 0)
return repeat;
if (formula != null)
if (formula.length () >= 12)
return formula.substring (0, 12);
else
return formula;
return value + "";
}
@Override
public String toString ()
{
String value = repeatingChar == 0 ? label == null
? formula == null ? ", Value: " + this.value : ", Formula: " + formula
: ", Label: " + label : ", Rpeat: " + repeatingChar;
String format = this.format == ' ' ? "" : ", Format: " + this.format;
String width = this.width == 0 ? "" : ", Width: " + this.width;
return String.format ("[Cell:%5s%s%s%s]", address, format, width, value);
}
@Override
public int compareTo (Cell o)
{
return address.compareTo (o.address);
}
}