2016-03-04 03:56:28 +00:00
|
|
|
package com.bytezone.diskbrowser.visicalc;
|
|
|
|
|
2016-03-11 22:32:19 +00:00
|
|
|
import java.text.DecimalFormat;
|
|
|
|
|
2016-03-09 10:38:53 +00:00
|
|
|
class Cell implements Comparable<Cell>, Value
|
2016-03-04 03:56:28 +00:00
|
|
|
{
|
2016-03-11 22:32:19 +00:00
|
|
|
private static final DecimalFormat nf = new DecimalFormat ("$#####0.00");
|
|
|
|
|
2016-03-04 03:56:28 +00:00
|
|
|
final Address address;
|
2016-03-06 08:05:32 +00:00
|
|
|
private final Sheet parent;
|
2016-03-13 10:57:20 +00:00
|
|
|
private CellType type;
|
2016-03-14 20:54:47 +00:00
|
|
|
private char cellFormat = ' ';
|
2016-03-13 10:57:20 +00:00
|
|
|
|
2016-03-04 03:56:28 +00:00
|
|
|
private char repeatingChar;
|
|
|
|
private String repeat = "";
|
2016-03-09 10:38:53 +00:00
|
|
|
|
2016-03-11 21:56:02 +00:00
|
|
|
private String label;
|
2016-03-13 10:57:20 +00:00
|
|
|
|
2016-03-09 10:38:53 +00:00
|
|
|
private String expressionText;
|
2016-03-11 21:56:02 +00:00
|
|
|
private Value value;
|
2016-03-13 10:57:20 +00:00
|
|
|
|
|
|
|
enum CellType
|
|
|
|
{
|
|
|
|
LABEL, REPEATING_CHARACTER, VALUE
|
|
|
|
}
|
2016-03-04 03:56:28 +00:00
|
|
|
|
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-15 20:06:04 +00:00
|
|
|
public boolean isValue ()
|
|
|
|
{
|
|
|
|
return type == CellType.VALUE;
|
|
|
|
}
|
|
|
|
|
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
|
2016-03-10 02:39:23 +00:00
|
|
|
// /F* - graph (histogram)
|
|
|
|
|
2016-03-08 09:39:35 +00:00
|
|
|
if (format.startsWith ("/F"))
|
2016-03-14 20:54:47 +00:00
|
|
|
this.cellFormat = format.charAt (2);
|
2016-03-08 09:39:35 +00:00
|
|
|
else if (format.startsWith ("/-"))
|
|
|
|
{
|
|
|
|
repeatingChar = format.charAt (2);
|
|
|
|
for (int i = 0; i < 20; i++)
|
|
|
|
repeat += repeatingChar;
|
2016-03-13 10:57:20 +00:00
|
|
|
type = CellType.REPEATING_CHARACTER;
|
2016-03-08 09:39:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
System.out.printf ("Unexpected format [%s]%n", format);
|
|
|
|
}
|
|
|
|
|
2016-03-11 21:56:02 +00:00
|
|
|
void setValue (String command)
|
2016-03-04 03:56:28 +00:00
|
|
|
{
|
2016-03-13 10:57:20 +00:00
|
|
|
if (command.charAt (0) == '"')
|
2016-03-04 03:56:28 +00:00
|
|
|
{
|
2016-03-13 10:57:20 +00:00
|
|
|
label = command.substring (1);
|
|
|
|
type = CellType.LABEL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
expressionText = command;
|
|
|
|
type = CellType.VALUE;
|
2016-03-04 03:56:28 +00:00
|
|
|
}
|
2016-03-09 10:38:53 +00:00
|
|
|
|
|
|
|
// FUTURE.VC
|
2016-03-10 09:21:47 +00:00
|
|
|
if (false)
|
2016-03-15 20:06:04 +00:00
|
|
|
if (address.rowKey == 67)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "1000";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 131)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "10.5";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 195)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "12";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 259)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "8";
|
|
|
|
|
|
|
|
// IRA.VC
|
|
|
|
if (false)
|
2016-03-15 20:06:04 +00:00
|
|
|
if (address.rowKey == 66)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "10";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 130)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "30";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 194)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "65";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 258)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "1000";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 386)
|
2016-03-10 09:21:47 +00:00
|
|
|
expressionText = "15";
|
2016-03-11 01:52:22 +00:00
|
|
|
|
|
|
|
// CARLOAN.VC
|
2016-03-12 22:38:03 +00:00
|
|
|
if (false)
|
2016-03-15 20:06:04 +00:00
|
|
|
if (address.rowKey == 67)
|
2016-03-11 01:52:22 +00:00
|
|
|
expressionText = "9375";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 131)
|
2016-03-11 01:52:22 +00:00
|
|
|
expressionText = "4500";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 195)
|
2016-03-11 01:52:22 +00:00
|
|
|
expressionText = "24";
|
2016-03-15 20:06:04 +00:00
|
|
|
else if (address.rowKey == 259)
|
2016-03-11 01:52:22 +00:00
|
|
|
expressionText = "11.9";
|
2016-03-04 03:56:28 +00:00
|
|
|
}
|
|
|
|
|
2016-03-11 22:32:19 +00:00
|
|
|
String getText (int colWidth, char defaultFormat)
|
2016-03-04 03:56:28 +00:00
|
|
|
{
|
2016-03-14 08:58:54 +00:00
|
|
|
// cell may have been created when formatted but no type set
|
2016-03-13 10:57:20 +00:00
|
|
|
if (type == null)
|
|
|
|
return justify ("", colWidth);
|
2016-03-11 22:32:19 +00:00
|
|
|
|
2016-03-13 10:57:20 +00:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case LABEL:
|
|
|
|
return justify (label, colWidth);
|
|
|
|
|
|
|
|
case REPEATING_CHARACTER:
|
|
|
|
return justify (repeat, colWidth);
|
|
|
|
|
|
|
|
case VALUE:
|
|
|
|
if (hasValue ())
|
2016-03-14 20:54:47 +00:00
|
|
|
{
|
2016-03-14 22:55:17 +00:00
|
|
|
Double value = getValue ();
|
|
|
|
if (Double.isNaN (value))
|
|
|
|
return justify ("", colWidth);
|
|
|
|
|
2016-03-14 20:54:47 +00:00
|
|
|
char format = cellFormat != ' ' ? cellFormat : defaultFormat;
|
2016-03-13 10:57:20 +00:00
|
|
|
if (format == 'I')
|
|
|
|
{
|
|
|
|
String integerFormat = String.format ("%%%d.0f", colWidth);
|
2016-03-14 22:55:17 +00:00
|
|
|
return String.format (integerFormat, value);
|
2016-03-13 10:57:20 +00:00
|
|
|
}
|
|
|
|
else if (format == '$')
|
|
|
|
{
|
|
|
|
String currencyFormat = String.format ("%%%d.%ds", colWidth, colWidth);
|
2016-03-14 22:35:22 +00:00
|
|
|
return String.format (currencyFormat, nf.format (value));
|
2016-03-13 10:57:20 +00:00
|
|
|
}
|
|
|
|
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);
|
2016-03-14 22:55:17 +00:00
|
|
|
String val = String.format (numberFormat, value);
|
2016-03-13 10:57:20 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-03-14 20:54:47 +00:00
|
|
|
}
|
2016-03-14 22:35:22 +00:00
|
|
|
// else
|
|
|
|
// return justify ("", colWidth);
|
2016-03-13 10:57:20 +00:00
|
|
|
}
|
|
|
|
return getError ();
|
|
|
|
}
|
2016-03-11 22:32:19 +00:00
|
|
|
|
2016-03-13 10:57:20 +00:00
|
|
|
private String justify (String text, int colWidth)
|
|
|
|
{
|
2016-03-14 20:54:47 +00:00
|
|
|
if (cellFormat == 'R')
|
2016-03-11 22:32:19 +00:00
|
|
|
{
|
|
|
|
String labelFormat = String.format ("%%%d.%ds", colWidth, colWidth);
|
|
|
|
return (String.format (labelFormat, text));
|
|
|
|
}
|
2016-03-13 10:57:20 +00:00
|
|
|
|
|
|
|
String labelFormat = String.format ("%%-%d.%ds", colWidth, colWidth);
|
|
|
|
return (String.format (labelFormat, text));
|
2016-03-09 10:38:53 +00:00
|
|
|
}
|
2016-03-05 02:25:15 +00:00
|
|
|
|
2016-03-11 21:56:02 +00:00
|
|
|
@Override
|
|
|
|
public boolean hasValue ()
|
|
|
|
{
|
2016-03-14 08:58:54 +00:00
|
|
|
if (type == CellType.VALUE)
|
|
|
|
return value.hasValue ();
|
|
|
|
return false;
|
2016-03-11 21:56:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// this should be called when doing calculations
|
2016-03-09 10:38:53 +00:00
|
|
|
@Override
|
|
|
|
public double getValue ()
|
|
|
|
{
|
2016-03-14 20:09:04 +00:00
|
|
|
if (type != CellType.VALUE)
|
|
|
|
return 0;
|
|
|
|
|
2016-03-11 21:56:02 +00:00
|
|
|
return value.getValue ();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getError ()
|
|
|
|
{
|
2016-03-11 22:32:19 +00:00
|
|
|
return value.getError ();
|
2016-03-11 21:56:02 +00:00
|
|
|
}
|
|
|
|
|
2016-03-15 20:06:04 +00:00
|
|
|
void calculate ()
|
2016-03-11 21:56:02 +00:00
|
|
|
{
|
|
|
|
if (expressionText == null)
|
2016-03-10 02:39:23 +00:00
|
|
|
{
|
2016-03-11 21:56:02 +00:00
|
|
|
System.out.printf ("%s null expression text %n", address);
|
|
|
|
value = Function.getInstance (parent, "@ERROR()");
|
2016-03-10 02:39:23 +00:00
|
|
|
}
|
2016-03-11 21:56:02 +00:00
|
|
|
else
|
2016-03-11 22:32:19 +00:00
|
|
|
// could use Number or Cell for simple Values
|
2016-03-11 21:56:02 +00:00
|
|
|
value = new Expression (parent, expressionText);
|
2016-03-04 03:56:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString ()
|
|
|
|
{
|
2016-03-14 08:58:54 +00:00
|
|
|
String contents = "<empty>";
|
2016-03-13 10:57:20 +00:00
|
|
|
if (type != null)
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case LABEL:
|
|
|
|
contents = "Labl: " + label;
|
|
|
|
break;
|
|
|
|
case REPEATING_CHARACTER:
|
|
|
|
contents = "Rept: " + repeatingChar;
|
|
|
|
break;
|
|
|
|
case VALUE:
|
|
|
|
contents = "Exp : " + expressionText;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-03-09 10:38:53 +00:00
|
|
|
return String.format ("[Cell:%5s %s]", address, contents);
|
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);
|
|
|
|
}
|
|
|
|
}
|