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);
|
|
|
|
}
|
|
|
|
}
|