mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-06-13 21:29:31 +00:00
refactoring
This commit is contained in:
parent
fd1ba9c15f
commit
2417e0aa07
|
@ -13,10 +13,9 @@ class Cell implements Comparable<Cell>
|
|||
|
||||
private String label;
|
||||
private double value;
|
||||
private String formula;
|
||||
private String formulaText;
|
||||
|
||||
private char format = ' ';
|
||||
private int width;
|
||||
private char repeatingChar;
|
||||
private String repeat = "";
|
||||
private boolean valid;
|
||||
|
@ -27,35 +26,31 @@ class Cell implements Comparable<Cell>
|
|||
this.address = address;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -64,7 +59,7 @@ class Cell implements Comparable<Cell>
|
|||
if (command.matches ("^[0-9.]+$")) // contains only numbers or .
|
||||
this.value = Float.parseFloat (command);
|
||||
else
|
||||
formula = command;
|
||||
formulaText = command;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,19 +75,30 @@ class Cell implements Comparable<Cell>
|
|||
|
||||
double getValue ()
|
||||
{
|
||||
if (valid || formula == null)
|
||||
if (valid || formulaText == null)
|
||||
return value;
|
||||
|
||||
double result = 0.0;
|
||||
double interim = 0.0;
|
||||
|
||||
if (formula.startsWith ("@LOOKUP("))
|
||||
if (formulaText.startsWith ("@LOOKUP("))
|
||||
{
|
||||
Lookup lookup = new Lookup (parent, formula);
|
||||
Lookup lookup = new Lookup (parent, formulaText);
|
||||
return lookup.getValue ();
|
||||
}
|
||||
|
||||
Matcher m = cellContents.matcher (formula);
|
||||
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);
|
||||
while (m.find ())
|
||||
{
|
||||
valid = true;
|
||||
|
@ -112,7 +118,7 @@ class Cell implements Comparable<Cell>
|
|||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.printf ("NFE: %s [%s]%n", m.group (4), formula);
|
||||
System.out.printf ("NFE: %s [%s]%n", m.group (4), formulaText);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -138,7 +144,7 @@ class Cell implements Comparable<Cell>
|
|||
return result;
|
||||
}
|
||||
|
||||
System.out.println ("?? " + formula);
|
||||
System.out.println ("?? " + formulaText);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -149,24 +155,22 @@ class Cell implements Comparable<Cell>
|
|||
return label;
|
||||
if (repeatingChar > 0)
|
||||
return repeat;
|
||||
if (formula != null)
|
||||
if (formula.length () >= 12)
|
||||
return formula.substring (0, 12);
|
||||
if (formulaText != null)
|
||||
if (formulaText.length () >= 12)
|
||||
return formulaText.substring (0, 12);
|
||||
else
|
||||
return formula;
|
||||
return formulaText;
|
||||
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);
|
||||
return String.format ("[Cell:%5s%s%s]", address, format, value);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,14 +29,21 @@ public class Lookup extends Function
|
|||
{
|
||||
// source could be a formula - @LOOKUP(.2*K8+K7,H3...H16)
|
||||
source = parent.getCell (new Address (sourceText));
|
||||
if (source == null)
|
||||
{
|
||||
System.out.println ("Null source:" + sourceText);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double sourceValue = source.getValue ();
|
||||
range = getRange (rangeText);
|
||||
|
||||
Address target = null;
|
||||
for (Address address : range)
|
||||
{
|
||||
System.out.printf ("%s : %s%n", source, address);
|
||||
// System.out.printf ("%s : %s%n", source, address);
|
||||
Cell cell = parent.getCell (address);
|
||||
if (cell != null && cell.getValue () > source.getValue ())
|
||||
if (cell != null && cell.getValue () > sourceValue)
|
||||
break;
|
||||
target = address;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package com.bytezone.diskbrowser.visicalc;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -9,20 +13,23 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
|
|||
|
||||
public class Sheet implements Iterable<Cell>
|
||||
{
|
||||
private static char[] tokens = { '"', '@', '+' }; // label, function, formula/value
|
||||
private static final Pattern addressPattern =
|
||||
Pattern.compile ("([A-B]?[A-Z])([0-9]{1,3}):");
|
||||
Pattern.compile ("([AB]?[A-Z])([0-9]{1,3}):");
|
||||
// private static final Pattern functionPattern = Pattern
|
||||
// .compile ("\\(([A-B]?[A-Z])([0-9]{1,3})\\.\\.\\.([A-B]?[A-Z])([0-9]{1,3})\\)?");
|
||||
// private static final Pattern addressList = Pattern.compile ("\\(([^,]+(,[^,]+)*)\\)");
|
||||
|
||||
private final Map<Integer, Cell> sheet = new TreeMap<Integer, Cell> ();
|
||||
private final Map<String, Double> functions = new HashMap<String, Double> ();
|
||||
// private final Map<String, Double> functions = new HashMap<String, Double> ();
|
||||
|
||||
Cell currentCell = null;
|
||||
char defaultFormat;
|
||||
|
||||
private final Map<Integer, Integer> columnWidths = new TreeMap<Integer, Integer> ();
|
||||
int columnWidth = 12;
|
||||
private int columnWidth = 12;
|
||||
private char recalculation = ' ';
|
||||
private char recalculationOrder = ' ';
|
||||
|
||||
// Maximum cell = BK254
|
||||
|
||||
|
@ -49,9 +56,9 @@ public class Sheet implements Iterable<Cell>
|
|||
// /GF$ Global Format Currency
|
||||
// /GC Global Column <width>
|
||||
// /GR Global
|
||||
// /GRA
|
||||
// /GRA Recalculation Auto
|
||||
// /GO Global
|
||||
// /GOC
|
||||
// /GOC Calculation Order - Columns first
|
||||
|
||||
// /T Titles (HVBN)
|
||||
// /TH fix Horizontal Titles
|
||||
|
@ -175,231 +182,128 @@ public class Sheet implements Iterable<Cell>
|
|||
return ptr - offset;
|
||||
}
|
||||
|
||||
private void processLine (String command)
|
||||
private void processLine (String line)
|
||||
{
|
||||
// NB no closing bracket: [>K11:@SUM(J11...F11]
|
||||
|
||||
if (command.isEmpty ())
|
||||
// >B10:/F$+B4+B7+B8+B9
|
||||
// >F2:/FR"INCOME
|
||||
|
||||
if (line.isEmpty ())
|
||||
{
|
||||
System.out.println ("empty command");
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.startsWith (">")) // GOTO cell
|
||||
if (line.startsWith ("/"))
|
||||
{
|
||||
Matcher m = addressPattern.matcher (command);
|
||||
if (m.find ())
|
||||
switch (line.charAt (1))
|
||||
{
|
||||
Address address = new Address (m.group (1), m.group (2));
|
||||
currentCell = sheet.get (address.sortValue);
|
||||
int pos = command.indexOf (':'); // end of cell address
|
||||
command = command.substring (pos + 1);
|
||||
|
||||
if (currentCell == null)
|
||||
{
|
||||
currentCell = new Cell (this, address);
|
||||
if (!command.startsWith ("/GCC"))
|
||||
sheet.put (currentCell.address.sortValue, currentCell);
|
||||
}
|
||||
}
|
||||
else
|
||||
System.out.printf ("Invalid cell address: %s%n", command);
|
||||
}
|
||||
|
||||
if (command.startsWith ("/")) // command
|
||||
{
|
||||
String data = command.substring (1);
|
||||
char subCommand = command.charAt (1);
|
||||
switch (subCommand)
|
||||
{
|
||||
case 'W': // Window control
|
||||
// System.out.println (" Window command: " + data);
|
||||
case 'W':
|
||||
System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
|
||||
case 'G': // Global command
|
||||
// System.out.println (" Global command: " + data);
|
||||
try
|
||||
case 'G':
|
||||
switch (line.charAt (2))
|
||||
{
|
||||
if (data.charAt (1) == 'C')
|
||||
{
|
||||
if (data.charAt (2) == 'C')
|
||||
{
|
||||
int width = Integer.parseInt (data.substring (3));
|
||||
int column = currentCell.address.column;
|
||||
columnWidths.put (column, width);
|
||||
}
|
||||
else
|
||||
columnWidth = Integer.parseInt (data.substring (2));
|
||||
}
|
||||
else if (data.charAt (1) == 'F')
|
||||
defaultFormat = data.charAt (2);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.printf ("NFE: %s%n", data.substring (2));
|
||||
case 'R':
|
||||
recalculation = line.charAt (3);
|
||||
break;
|
||||
case 'O':
|
||||
recalculationOrder = line.charAt (3);
|
||||
break;
|
||||
case 'P':
|
||||
System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
case 'C':
|
||||
columnWidth = Integer.parseInt (line.substring (3));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T': // Set title area
|
||||
// System.out.println (" Title command: " + data);
|
||||
case 'X':
|
||||
System.out.printf ("Skipping [%s]%n", line);
|
||||
break;
|
||||
|
||||
case 'X': // Position cursor?
|
||||
break;
|
||||
|
||||
default:
|
||||
currentCell.doCommand (command);
|
||||
System.out.printf ("Skipping [%s]%n", line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith ("@")) // function
|
||||
|
||||
if (!line.startsWith (">")) // GOTO cell
|
||||
{
|
||||
currentCell.doCommand (command);
|
||||
System.out.printf ("Error [%s]%n", line);
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith ("\""))
|
||||
|
||||
currentCell = null;
|
||||
|
||||
Matcher m = addressPattern.matcher (line);
|
||||
if (m.find ())
|
||||
{
|
||||
currentCell.doCommand (command);
|
||||
}
|
||||
else if (command.startsWith ("+"))
|
||||
{
|
||||
currentCell.doCommand (command);
|
||||
}
|
||||
else if (command.matches ("^[0-9.]+$")) // value
|
||||
{
|
||||
currentCell.doCommand (command);
|
||||
}
|
||||
else if (command.matches ("^[-A-Z]+$")) // label
|
||||
{
|
||||
currentCell.doCommand (command);
|
||||
Address address = new Address (m.group (1), m.group (2));
|
||||
currentCell = sheet.get (address.sortValue);
|
||||
|
||||
int pos = line.indexOf (':'); // end of cell address
|
||||
line = line.substring (pos + 1); // remove address from line
|
||||
|
||||
if (currentCell == null)
|
||||
{
|
||||
currentCell = new Cell (this, address);
|
||||
if (!line.startsWith ("/G"))
|
||||
sheet.put (currentCell.address.sortValue, currentCell);
|
||||
}
|
||||
}
|
||||
else
|
||||
currentCell.doCommand (command); // formula
|
||||
{
|
||||
System.out.printf ("Invalid cell address: %s%n", line);
|
||||
return;
|
||||
}
|
||||
|
||||
assert currentCell != null;
|
||||
|
||||
if (line.startsWith ("/G")) // global column widths
|
||||
{
|
||||
if (line.charAt (2) == 'C' && line.charAt (3) == 'C')
|
||||
{
|
||||
int width = Integer.parseInt (line.substring (4));
|
||||
columnWidths.put (currentCell.address.column, width);
|
||||
}
|
||||
else
|
||||
System.out.printf ("Unknown Global:[%s]%n", line);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// check for formatting commands before a token
|
||||
String command = "";
|
||||
if (line.startsWith ("/"))
|
||||
{
|
||||
for (char token : tokens)
|
||||
{
|
||||
int pos = line.indexOf (token);
|
||||
if (pos > 0)
|
||||
{
|
||||
command = line.substring (0, pos);
|
||||
line = line.substring (pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith ("/")) // no token found
|
||||
{
|
||||
command = line;
|
||||
line = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (true)
|
||||
System.out.printf ("[%s][%-3s][%s]%n", currentCell.address, command, line);
|
||||
|
||||
if (!command.isEmpty ())
|
||||
currentCell.format (command); // formatting command
|
||||
if (!line.isEmpty ())
|
||||
currentCell.doCommand (line); // expression
|
||||
}
|
||||
|
||||
// private double evaluateFunction (String function)
|
||||
// {
|
||||
// if (functions.containsKey (function))
|
||||
// return functions.get (function);
|
||||
//
|
||||
// // System.out.println (function);
|
||||
// double result = 0;
|
||||
//
|
||||
// if (function.startsWith ("@IF("))
|
||||
// {
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// if (function.startsWith ("@LOOKUP("))
|
||||
// {
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// // Range range = getRange (function);
|
||||
// // if (range == null)
|
||||
// // return result;
|
||||
//
|
||||
// if (function.startsWith ("@SUM("))
|
||||
// {
|
||||
// // for (Address address : range)
|
||||
// // result += getValue (address);
|
||||
// String text = function.substring (4, function.length () - 1);
|
||||
// Sum sum = new Sum (this, text);
|
||||
// result = sum.getValue ();
|
||||
// }
|
||||
// else if (function.startsWith ("@COUNT("))
|
||||
// {
|
||||
// // int count = 0;
|
||||
// // for (Address address : range)
|
||||
// // {
|
||||
// // VisicalcCell cell = getCell (address);
|
||||
// // if (cell != null && cell.hasValue () && cell.getValue () != 0.0)
|
||||
// // ++count;
|
||||
// // }
|
||||
// // result = count;
|
||||
// String text = function.substring (7, function.length () - 1);
|
||||
// Count count = new Count (this, text);
|
||||
// result = count.getValue ();
|
||||
// }
|
||||
// else if (function.startsWith ("@MIN("))
|
||||
// {
|
||||
// // double min = Double.MAX_VALUE;
|
||||
// // for (Address address : range)
|
||||
// // if (min > getValue (address))
|
||||
// // min = getValue (address);
|
||||
// String text = function.substring (5, function.length () - 1);
|
||||
// Min min = new Min (this, text);
|
||||
// result = min.getValue ();
|
||||
// }
|
||||
// else if (function.startsWith ("@MAX("))
|
||||
// {
|
||||
// // double max = Double.MIN_VALUE;
|
||||
// // for (Address address : range)
|
||||
// // if (max < getValue (address))
|
||||
// // max = getValue (address);
|
||||
// // result = max;
|
||||
// String text = function.substring (5, function.length () - 1);
|
||||
// Max max = new Max (this, text);
|
||||
// result = max.getValue ();
|
||||
// }
|
||||
// else
|
||||
// System.out.println ("Unimplemented function: " + function);
|
||||
//
|
||||
// functions.put (function, result);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// Range getRange (String text)
|
||||
// {
|
||||
// Range range = null;
|
||||
// Matcher m = functionPattern.matcher (text);
|
||||
// while (m.find ())
|
||||
// {
|
||||
// Address fromAddress = new Address (m.group (1), m.group (2));
|
||||
// Address toAddress = new Address (m.group (3), m.group (4));
|
||||
// range = new Range (fromAddress, toAddress);
|
||||
// }
|
||||
//
|
||||
// if (range != null)
|
||||
// return range;
|
||||
//
|
||||
// m = addressList.matcher (text);
|
||||
// while (m.find ())
|
||||
// {
|
||||
// String[] cells = m.group (1).split (",");
|
||||
// range = new Range (cells);
|
||||
// }
|
||||
//
|
||||
// if (range != null)
|
||||
// return range;
|
||||
//
|
||||
// int pos = text.indexOf ("...");
|
||||
// if (pos > 0)
|
||||
// {
|
||||
// String from = text.substring (0, pos);
|
||||
// String to = text.substring (pos + 3);
|
||||
// Address fromAddress = new Address (from);
|
||||
// Address toAddress = new Address (to);
|
||||
// range = new Range (fromAddress, toAddress);
|
||||
// }
|
||||
//
|
||||
// if (range != null)
|
||||
// return range;
|
||||
// System.out.println ("null range : " + text);
|
||||
//
|
||||
// return range;
|
||||
// }
|
||||
|
||||
// private double getValue (Address address)
|
||||
// {
|
||||
// Cell cell = sheet.get (address.sortValue);
|
||||
// return cell == null ? 0.0 : cell.getValue ();
|
||||
// }
|
||||
|
||||
// private double getValue (String cellName)
|
||||
// {
|
||||
// Address address = new Address (cellName);
|
||||
// return getValue (address);
|
||||
// }
|
||||
|
||||
Cell getCell (Address address)
|
||||
{
|
||||
return sheet.get (address.sortValue);
|
||||
|
|
Loading…
Reference in New Issue
Block a user