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

423 lines
13 KiB
Java
Raw Normal View History

2016-03-04 03:56:28 +00:00
package com.bytezone.diskbrowser.visicalc;
2017-03-24 04:09:24 +00:00
import java.util.Iterator;
2020-02-10 11:05:40 +00:00
// -----------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
class Cell implements Value, Comparable<Cell>
2020-02-10 11:05:40 +00:00
// -----------------------------------------------------------------------------------//
2016-03-04 03:56:28 +00:00
{
2017-02-26 10:44:10 +00:00
private static final String empty = " ";
2016-03-11 22:32:19 +00:00
2017-02-25 03:56:22 +00:00
private final Address address;
2016-03-06 08:05:32 +00:00
private final Sheet parent;
2017-03-23 13:30:41 +00:00
private String fullText;
2017-02-27 09:41:05 +00:00
private char cellFormat = ' ';
2016-03-04 03:56:28 +00:00
private String repeat = "";
2017-03-20 11:02:05 +00:00
private boolean calculated;
2016-03-13 10:57:20 +00:00
2017-03-23 13:30:41 +00:00
private CellType cellType;
2017-03-25 21:58:10 +00:00
private String repeatingText; // CellType.FILLER
private String label; // CellType.LABEL
private Value value; // CellType.VALUE
2017-03-23 13:30:41 +00:00
2016-03-13 10:57:20 +00:00
enum CellType
{
2017-03-24 04:09:24 +00:00
LABEL, FILLER, VALUE, EMPTY
2016-03-13 10:57:20 +00:00
}
2016-03-04 03:56:28 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
Cell (Sheet parent, Address address)
// ---------------------------------------------------------------------------------//
2016-03-04 03:56:28 +00:00
{
this.parent = parent;
this.address = address;
2017-02-25 03:56:22 +00:00
cellType = CellType.EMPTY;
2017-03-20 07:17:46 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-02-25 03:56:22 +00:00
void setFormat (String formatText)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-08 09:39:35 +00:00
{
2017-02-26 10:44:10 +00:00
if (formatText.startsWith ("/T")) // lock titles
2017-02-25 03:56:22 +00:00
return;
if (formatText.startsWith ("/F"))
{
2017-02-27 09:41:05 +00:00
cellFormat = formatText.charAt (2);
2017-02-25 03:56:22 +00:00
return;
}
if (formatText.startsWith ("/-"))
2016-03-08 09:39:35 +00:00
{
2017-03-25 21:58:10 +00:00
assert cellType == CellType.EMPTY;
2017-02-25 03:56:22 +00:00
repeatingText = formatText.substring (2);
2017-03-25 21:58:10 +00:00
2016-03-08 09:39:35 +00:00
for (int i = 0; i < 20; i++)
2017-02-25 03:56:22 +00:00
repeat += repeatingText;
2017-03-24 04:09:24 +00:00
cellType = CellType.FILLER;
2017-03-25 21:58:10 +00:00
2017-02-25 03:56:22 +00:00
return;
2016-03-08 09:39:35 +00:00
}
2017-02-25 03:56:22 +00:00
System.out.printf ("Unexpected format [%s]%n", formatText);
2016-03-08 09:39:35 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-25 21:58:10 +00:00
void setValue (String valueText)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-04 03:56:28 +00:00
{
2017-02-28 20:39:26 +00:00
assert cellType == CellType.EMPTY;
2017-03-25 21:58:10 +00:00
if (!valueText.isEmpty () && valueText.charAt (0) == '"')
2016-03-04 03:56:28 +00:00
{
2017-03-25 21:58:10 +00:00
label = valueText.substring (1);
2016-08-01 01:22:34 +00:00
cellType = CellType.LABEL;
2016-03-13 10:57:20 +00:00
}
else
{
2017-03-25 21:58:10 +00:00
fullText = valueText;
2017-03-23 13:30:41 +00:00
cellType = CellType.VALUE;
2017-03-14 11:28:52 +00:00
try
{
2017-03-23 13:30:41 +00:00
value = new Expression (this, fullText).reduce ();
2017-03-14 11:28:52 +00:00
}
catch (IllegalArgumentException e)
{
2017-03-23 13:30:41 +00:00
value = new Error (this, "@ERROR");
2017-03-14 11:28:52 +00:00
}
2016-03-04 03:56:28 +00:00
}
2016-03-09 10:38:53 +00:00
2016-03-10 09:21:47 +00:00
if (false)
2017-03-23 13:30:41 +00:00
setTestData (0);
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
void reset ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
{
2017-03-24 11:02:52 +00:00
calculated = false;
}
2016-03-10 09:21:47 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
Value getExpressionValue (String text)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return new Expression (this, text).reduce ();
}
2016-03-11 01:52:22 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
boolean isCellType (CellType cellType)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return this.cellType == cellType;
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
Address getAddress ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return address;
2016-03-04 03:56:28 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-02-25 03:56:22 +00:00
// format cell value for output
2017-03-20 11:02:05 +00:00
String getFormattedText (int colWidth, char globalFormat)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-04 03:56:28 +00:00
{
2017-03-08 09:18:59 +00:00
char fmtChar = cellFormat != ' ' ? cellFormat : globalFormat;
2016-08-01 01:22:34 +00:00
switch (cellType)
2016-03-13 10:57:20 +00:00
{
case LABEL:
2017-03-12 16:47:11 +00:00
if (fmtChar != 'R')
2017-03-08 09:18:59 +00:00
fmtChar = 'L';
return Format.justify (label, colWidth, fmtChar);
2016-03-13 10:57:20 +00:00
2017-03-24 04:09:24 +00:00
case FILLER:
2017-02-27 09:41:05 +00:00
return Format.justify (repeat, colWidth, ' ');
2017-02-25 03:56:22 +00:00
case EMPTY:
2017-02-27 09:41:05 +00:00
return Format.justify (empty, colWidth, ' ');
2016-03-13 10:57:20 +00:00
case VALUE:
2017-03-23 13:30:41 +00:00
switch (getValueResult ())
2017-03-03 10:24:23 +00:00
{
2017-03-23 13:30:41 +00:00
case ERROR:
case NA:
if (fmtChar == ' ')
fmtChar = 'R';
return " " + Format.justify (value.getText (), colWidth - 1, fmtChar);
case VALID:
switch (getValueType ())
{
case BOOLEAN:
if (fmtChar != 'L')
fmtChar = 'R';
return Format.justify (value.getText (), colWidth, fmtChar);
case NUMBER:
if (colWidth == 1)
return ".";
return " " + Format.format (value, fmtChar, colWidth - 1);
default:
assert false;
return "Impossible";
}
default:
assert false;
return "Impossible";
2017-03-03 10:24:23 +00:00
}
2017-02-25 03:56:22 +00:00
default:
assert false;
2017-03-23 13:30:41 +00:00
return "impossible";
2016-03-11 22:32:19 +00:00
}
2016-03-09 10:38:53 +00:00
}
2016-03-05 02:25:15 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
// Sheet convenience methods
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
Cell getCell (Address address)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return parent.getCell (address);
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
Cell getCell (String addressText)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return parent.getCell (addressText);
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
boolean cellExists (Address address)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return parent.cellExists (address);
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
Function getFunction (String text)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return parent.getFunction (this, text);
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
// Value interface methods
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-11 21:56:02 +00:00
@Override
2017-03-23 13:30:41 +00:00
public void calculate ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-11 21:56:02 +00:00
{
2017-03-23 13:30:41 +00:00
if (cellType == CellType.VALUE && !calculated)
{
value.calculate ();
calculated = true;
}
2016-03-11 21:56:02 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-16 19:32:25 +00:00
@Override
2017-03-23 13:30:41 +00:00
public boolean isValid ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-16 19:32:25 +00:00
{
2017-03-23 13:30:41 +00:00
return cellType == CellType.VALUE ? value.isValid () : true;
2016-03-16 19:32:25 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-09 10:38:53 +00:00
@Override
2017-03-24 11:02:52 +00:00
public ValueType getValueType ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-09 10:38:53 +00:00
{
2017-03-24 11:02:52 +00:00
return cellType == CellType.VALUE ? value.getValueType () : ValueType.NUMBER;
2016-03-16 06:15:39 +00:00
}
2016-03-14 20:09:04 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-11 21:56:02 +00:00
@Override
2017-03-24 11:02:52 +00:00
public ValueResult getValueResult ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-11 21:56:02 +00:00
{
2017-03-24 11:02:52 +00:00
return cellType == CellType.VALUE ? value.getValueResult () : ValueResult.VALID;
2016-03-11 21:56:02 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-16 06:15:39 +00:00
@Override
2017-03-23 13:30:41 +00:00
public double getDouble ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-11 21:56:02 +00:00
{
2017-03-23 13:30:41 +00:00
return cellType == CellType.VALUE ? value.getDouble () : 0;
2017-02-25 03:56:22 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
@Override
public boolean getBoolean ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-02-25 03:56:22 +00:00
{
2017-03-23 13:30:41 +00:00
return cellType == CellType.VALUE ? value.getBoolean () : false;
}
2017-02-25 03:56:22 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 04:09:24 +00:00
@Override
2017-03-24 11:02:52 +00:00
public String getText ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 04:09:24 +00:00
{
2017-03-24 11:02:52 +00:00
return cellType == CellType.VALUE ? value.getText () : "???";
2017-03-24 04:09:24 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
@Override
public String getFullText ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
{
2017-02-25 03:56:22 +00:00
switch (cellType)
2016-03-16 19:32:25 +00:00
{
2017-02-25 03:56:22 +00:00
case LABEL:
2017-03-24 02:00:11 +00:00
return "LBL : " + label;
2017-03-24 04:09:24 +00:00
case FILLER:
2017-03-24 02:00:11 +00:00
return "RPT : " + repeatingText;
2017-02-25 03:56:22 +00:00
case EMPTY:
2017-03-23 13:30:41 +00:00
return "Empty Cell";
2017-02-25 03:56:22 +00:00
case VALUE:
2017-03-23 13:30:41 +00:00
return value.getFullText ();
2017-02-25 03:56:22 +00:00
default:
2017-03-23 13:30:41 +00:00
return "impossible";
2016-03-16 19:32:25 +00:00
}
2017-03-23 13:30:41 +00:00
}
2017-02-25 03:56:22 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
@Override
public String getType ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
{
2017-03-24 11:02:52 +00:00
return "Cell " + address.getText ();
2017-02-25 03:56:22 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
@Override
2017-03-24 11:02:52 +00:00
public int size ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
{
2017-03-24 11:02:52 +00:00
return cellType == CellType.VALUE ? value.size () : 0;
}
2017-03-23 13:30:41 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
@Override
public Iterator<Value> iterator ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return cellType == CellType.VALUE ? value.iterator () : null;
2017-03-23 13:30:41 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
// end of Value interface methods
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
private void setTestData (int choice)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-23 13:30:41 +00:00
{
2017-03-24 11:02:52 +00:00
// FUTURE.VC
if (choice == 1)
{
System.out.println ("****** Hardcoded values ******");
if (address.getRowKey () == 67)
fullText = "1000";
else if (address.getRowKey () == 131)
fullText = "10.5";
else if (address.getRowKey () == 195)
fullText = "12";
else if (address.getRowKey () == 259)
fullText = "8";
}
// IRA.VC
if (choice == 2)
{
System.out.println ("****** Hardcoded values ******");
if (address.getRowKey () == 66)
fullText = "10";
else if (address.getRowKey () == 130)
fullText = "30";
else if (address.getRowKey () == 194)
fullText = "65";
else if (address.getRowKey () == 258)
fullText = "1000";
else if (address.getRowKey () == 386)
fullText = "15";
}
// CARLOAN.VC
if (choice == 3)
{
System.out.println ("****** Hardcoded values ******");
if (address.getRowKey () == 67)
fullText = "9375";
else if (address.getRowKey () == 131)
fullText = "4500";
else if (address.getRowKey () == 195)
fullText = "24";
else if (address.getRowKey () == 259)
fullText = "11.9";
}
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
@Override
public int compareTo (Cell o)
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2017-03-24 11:02:52 +00:00
{
return address.compareTo (o.address);
2017-03-23 13:30:41 +00:00
}
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-04 03:56:28 +00:00
@Override
public String toString ()
2020-02-10 11:05:40 +00:00
// ---------------------------------------------------------------------------------//
2016-03-04 03:56:28 +00:00
{
2016-03-19 05:31:30 +00:00
String contents = "";
2017-03-24 04:09:24 +00:00
String contents2 = "";
2017-03-25 21:58:10 +00:00
String valueTypeText = "";
2017-03-24 02:00:11 +00:00
String valueText = "";
2017-03-24 04:09:24 +00:00
String line2 = "";
2017-03-24 11:02:52 +00:00
String rest = "";
2016-03-19 05:31:30 +00:00
2016-08-01 01:22:34 +00:00
switch (cellType)
2016-03-19 05:31:30 +00:00
{
case LABEL:
2017-03-24 02:00:11 +00:00
contents = label;
2016-03-19 05:31:30 +00:00
break;
2017-03-24 04:09:24 +00:00
case FILLER:
2017-03-24 02:00:11 +00:00
contents = repeatingText;
2016-03-19 05:31:30 +00:00
break;
2017-02-25 03:56:22 +00:00
case EMPTY:
2017-03-24 02:00:11 +00:00
contents = "";
2017-03-23 13:30:41 +00:00
break;
case VALUE:
2017-03-24 02:00:11 +00:00
contents = fullText;
2017-03-25 21:58:10 +00:00
valueTypeText = value.getValueType () + "";
2017-03-24 11:02:52 +00:00
rest = value.toString ();
2017-03-25 21:58:10 +00:00
valueText = value.getText ();
2017-03-23 13:30:41 +00:00
break;
2016-03-19 05:31:30 +00:00
}
2016-03-13 10:57:20 +00:00
2017-03-25 21:58:10 +00:00
if (contents.length () > 39)
2017-03-24 04:09:24 +00:00
{
2017-03-25 21:58:10 +00:00
contents2 = contents.substring (39);
contents = contents.substring (0, 39);
2017-03-24 11:02:52 +00:00
line2 = String.format ("| %-70.70s|%n", contents2);
2017-03-24 04:09:24 +00:00
}
2016-03-04 03:56:28 +00:00
2017-03-25 21:58:10 +00:00
String single = String.format (AbstractValue.FMT5, address.getText (), contents,
cellType, valueTypeText, valueText);
return String.format ("%s%n%s%s%s", AbstractValue.LINE, single, line2, rest);
2016-03-04 03:56:28 +00:00
}
}