dmolony-DiskBrowser/src/com/bytezone/diskbrowser/visicalc/Cell.java

181 lines
4.3 KiB
Java
Raw Normal View History

2016-03-04 03:56:28 +00:00
package com.bytezone.diskbrowser.visicalc;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2016-03-06 08:05:32 +00:00
class Cell implements Comparable<Cell>
2016-03-04 03:56:28 +00:00
{
private static final Pattern cellContents =
Pattern.compile ("([-+/*]?)(([A-Z]{1,2}[0-9]{1,3})|([0-9.]+)|(@[^-+/*]+))");
final Address address;
2016-03-06 08:05:32 +00:00
private final Sheet parent;
2016-03-04 03:56:28 +00:00
private String label;
private double value;
2016-03-08 09:39:35 +00:00
private String formulaText;
2016-03-07 12:16:11 +00:00
2016-03-05 21:53:29 +00:00
private char format = ' ';
2016-03-04 03:56:28 +00:00
private char repeatingChar;
private String repeat = "";
private boolean valid;
2016-03-06 08:05:32 +00:00
public Cell (Sheet parent, Address address)
2016-03-04 03:56:28 +00:00
{
this.parent = parent;
this.address = address;
}
2016-03-08 09:39:35 +00:00
void format (String format)
{
// /FG - general
// /FD - default
// /FI - integer
// /F$ - dollars and cents
// /FL - left justified
// /FR - right justified
// /F* - graph
if (format.startsWith ("/F"))
this.format = format.charAt (2);
else if (format.startsWith ("/-"))
{
repeatingChar = format.charAt (2);
for (int i = 0; i < 20; i++)
repeat += repeatingChar;
}
else
System.out.printf ("Unexpected format [%s]%n", format);
}
2016-03-04 05:27:14 +00:00
void doCommand (String command)
2016-03-04 03:56:28 +00:00
{
2016-03-04 05:27:14 +00:00
switch (command.charAt (0))
2016-03-04 03:56:28 +00:00
{
2016-03-04 05:27:14 +00:00
case '"':
label = command.substring (1);
break;
default:
if (command.matches ("^[0-9.]+$")) // contains only numbers or .
this.value = Float.parseFloat (command);
else
2016-03-08 09:39:35 +00:00
formulaText = command;
2016-03-04 03:56:28 +00:00
}
}
2016-03-04 05:27:14 +00:00
boolean hasValue ()
2016-03-04 03:56:28 +00:00
{
return label == null && repeatingChar == 0;
}
2016-03-05 21:53:29 +00:00
char getFormat ()
{
return format;
}
2016-03-04 05:27:14 +00:00
double getValue ()
2016-03-04 03:56:28 +00:00
{
2016-03-08 09:39:35 +00:00
if (valid || formulaText == null)
2016-03-04 03:56:28 +00:00
return value;
double result = 0.0;
double interim = 0.0;
2016-03-08 09:39:35 +00:00
if (formulaText.startsWith ("@LOOKUP("))
2016-03-06 04:41:15 +00:00
{
2016-03-08 09:39:35 +00:00
Lookup lookup = new Lookup (parent, formulaText);
2016-03-06 06:58:14 +00:00
return lookup.getValue ();
2016-03-06 04:41:15 +00:00
}
2016-03-05 02:25:15 +00:00
2016-03-08 09:39:35 +00:00
System.out.printf ("Matching:[%s]%n", formulaText);
// [@IF(@ISERROR(BK24),0,BK24)]
// [@IF(D4=0,0,1)]
// [@IF(D4=0,0,B32+1)]
// [@IF(D4=0,0,1+(D3/100/D4)^D4-1*100)]
// [@SUM(C4...F4)]
// [+C4-@SUM(C5...C12)]
// [+D5/100/12]
// [.3*(B4+B7+B8+B9)]
// [+N12+(P12*(.2*K12+K9-O12))]
Matcher m = cellContents.matcher (formulaText);
2016-03-04 03:56:28 +00:00
while (m.find ())
{
valid = true;
char operator = m.group (1).isEmpty () ? '+' : m.group (1).charAt (0);
if (m.group (3) != null) // address
2016-03-07 04:37:01 +00:00
{
Address address = new Address (m.group (3));
Cell cell = parent.getCell (address);
if (cell != null)
interim = cell.getValue ();
}
2016-03-04 03:56:28 +00:00
else if (m.group (4) != null) // constant
try
{
interim = Double.parseDouble (m.group (4));
}
catch (NumberFormatException e)
{
2016-03-08 09:39:35 +00:00
System.out.printf ("NFE: %s [%s]%n", m.group (4), formulaText);
2016-03-04 03:56:28 +00:00
}
else
2016-03-07 12:16:11 +00:00
{
// interim = parent.evaluateFunction (m.group (5)); // function
Function function = Function.getInstance (parent, m.group (5));
if (function != null)
interim = function.getValue ();
}
2016-03-04 03:56:28 +00:00
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;
}
2016-03-08 09:39:35 +00:00
System.out.println ("?? " + formulaText);
2016-03-04 03:56:28 +00:00
return value;
}
2016-03-04 05:27:14 +00:00
String value ()
2016-03-04 03:56:28 +00:00
{
if (label != null)
return label;
if (repeatingChar > 0)
return repeat;
2016-03-08 09:39:35 +00:00
if (formulaText != null)
if (formulaText.length () >= 12)
return formulaText.substring (0, 12);
2016-03-04 03:56:28 +00:00
else
2016-03-08 09:39:35 +00:00
return formulaText;
2016-03-04 03:56:28 +00:00
return value + "";
}
@Override
public String toString ()
{
2016-03-08 09:39:35 +00:00
String value = repeatingChar == 0
? label == null ? formulaText == null ? ", Value : " + this.value
: ", Formula: " + formulaText : ", Label : " + label
: ", Repeat : " + repeatingChar;
return String.format ("[Cell:%5s %-2s%s]", address, format, value);
2016-03-04 03:56:28 +00:00
}
@Override
2016-03-06 08:05:32 +00:00
public int compareTo (Cell o)
2016-03-04 03:56:28 +00:00
{
return address.compareTo (o.address);
}
}