Fix table opening bug, Fix Table1D axis label bug; Fix double loaded documents; Improve XDF support

This commit is contained in:
Robin K 2022-11-13 20:06:24 +01:00
parent 9112bb2b82
commit 33bcb31c7d
7 changed files with 215 additions and 172 deletions

View File

@ -379,9 +379,40 @@ public class ECUEditor extends AbstractFrame {
INFORMATION_MESSAGE);
}
}
public TableView createTableView(Table t)
private void handleAlreadyOpenTable(TableFrame frame)
{
// table is already open.
if(1 == settings.getTableClickBehavior()) { // open/focus frame
// table is already open, so set focus on the frame.
boolean selected = true;
frame.toFront();
try {
frame.setSelected(true);
} catch (PropertyVetoException e) {
frame.toBack();
selected = false;
}
if(selected) {
frame.requestFocusInWindow();
}
} else {
// default to open/close frame
// table is already open, so close the frame.
rightPanel.remove(frame);
frame.getTable().setTableFrame(null);
try {
frame.setClosed(true);
} catch (PropertyVetoException e) {
// Do nothing.
}
frame.dispose();
}
}
private void openClosedTable(TableTreeNode node)
{
Table t = node.getTable();
TableView v = null;
try {
if (t != null) {
@ -390,11 +421,22 @@ public class ECUEditor extends AbstractFrame {
else if(t instanceof TableBitwiseSwitch)
v = new TableBitwiseSwitchView((TableBitwiseSwitch)t);
else if(t instanceof Table1D)
v = new Table1DView((Table1D)t, Table1DType.NO_AXIS);
v = new Table1DView((Table1D)node.getTable(), Table1DType.NO_AXIS);
else if(t instanceof Table2D)
v = new Table2DView((Table2D)t);
else if(t instanceof Table3D)
v = new Table3DView((Table3D)t);
else
return;
v.populateTableVisual();
v.drawTable();
Rom rom = RomTree.getRomNode(node);
TableFrame frame = new TableFrame(node.getTable().getName() + " | " + rom.getFileName(), v);
frame.pack();
rightPanel.add(frame);
}
}
catch(Exception e) {
@ -406,63 +448,26 @@ public class ECUEditor extends AbstractFrame {
new DebugPanel(ex, settings.getSupportURL()),
rb.getString("EXCEPTION"),
ERROR_MESSAGE);
}
return v;
}
}
public void displayTable(TableTreeNode node) {
TableFrame frame = node.getFrame();
try {
// check if frame has been added.
for(JInternalFrame curFrame : getRightPanel().getAllFrames()) {
if(curFrame.equals(frame)) {
// table is already open.
if(1 == settings.getTableClickBehavior()) { // open/focus frame
// table is already open, so set focus on the frame.
boolean selected = true;
frame.toFront();
try {
frame.setSelected(true);
} catch (PropertyVetoException e) {
frame.toBack();
selected = false;
}
if(selected) {
frame.requestFocusInWindow();
}
} else { // default to open/close frame
// table is already open, so close the frame.
rightPanel.remove(frame);
frame.setVisible(false);
try {
frame.setClosed(true);
} catch (PropertyVetoException e) {
// Do nothing.
}
frame.dispose();
}
frame.pack();
rightPanel.repaint();
return;
}
}
if(frame == null) {
Rom rom = RomTree.getRomNode(node);
TableView v = createTableView(node.getTable());
frame = new TableFrame(node.getTable().getName() + " | " + rom.getFileName(), v);
v.populateTableVisual();
v.drawTable();
rightPanel.add(frame);
rightPanel.repaint();
refreshTableCompareMenus();
}
} catch (IllegalArgumentException ex) {
// Do nothing.
// check if frame has been added.
if (frame != null)
{
handleAlreadyOpenTable(frame);
}
else
{
openClosedTable(node);
}
rightPanel.repaint();
refreshTableCompareMenus();
}
public void removeDisplayTable(TableFrame frame) {

View File

@ -56,6 +56,7 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
private final File inputFile;
private Rom rom;
private String finalStatus;
public OpenImageWorker(File inputFile) {
this.inputFile = inputFile;
@ -160,19 +161,18 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
else
ex.printStackTrace();
}
private Rom openRomWithDefinition(File f, Node romNode, byte[] input) {
private Rom openRomWithDefinition(File f, Document doc, Node romNode, byte[] input) {
ECUEditor editor = ECUEditorManager.getECUEditor();
final String errorLoading = MessageFormat.format(
ECUEditor.rb.getString("ERRORFILE"),
inputFile.getName());
try {
Document doc = createDocument(f);
Rom rom = new DOMRomUnmarshaller().unmarshallXMLDefinition(f, doc.getDocumentElement(), romNode,
input, editor.getStatusPanel());
rom.setDocument(doc);
rom.setDefinitionPath(f);
loadRom(rom, input);
} catch (StackOverflowError ex) {
@ -233,9 +233,10 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
}
Node romNode = null;
Document doc = null;
try {
Document doc = createDocument(f);
doc = createDocument(f);
romNode = new DOMRomUnmarshaller().checkDefinitionMatch(doc.getDocumentElement(), input);
}
catch(Exception e) {
@ -243,7 +244,7 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
}
if(romNode != null) {
openRomWithDefinition(f, romNode, input);
openRomWithDefinition(f, doc, romNode, input);
found = true;
break;
}
@ -300,11 +301,11 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
if(answerForceLoad == 0) {
Node n = DOMRomUnmarshaller.findFirstRomNode(doc.getDocumentElement());
openRomWithDefinition(file, n, input);
openRomWithDefinition(file, doc, n, input);
}
}
else {
openRomWithDefinition(file, romNode, input);
openRomWithDefinition(file, doc, romNode, input);
}
}
}

View File

@ -824,6 +824,11 @@ public abstract class TableView extends JPanel implements Serializable {
public void setOverlayLog(boolean overlayLog) {
this.overlayLog = overlayLog;
if(!overlayLog)
{
clearLiveDataTrace();
}
}
public boolean getOverlayLog()

View File

@ -329,8 +329,18 @@ public class TableToolBar extends JToolBar implements MouseListener, ItemListene
}
public void updateTableToolBar(Table selectedTable) {
//Select the parent Table always instead?
//if(selectedTable instanceof Table1D)selectedTable = ((Table1D)selectedTable).getAxisParent();
// If the table is a 1D table, we might select an axis
// but we want to change the scales of the entire table
if(selectedTable instanceof Table1D)
{
Table t = ((Table1D)selectedTable).getAxisParent();
// Table will not have a parent if its a standalone 1D table
if(t != null)
{
selectedTable = t;
}
}
if(selectedTable == null && this.selectedTable == null) {
// Skip if the table is the same to avoid multiple updates
@ -752,10 +762,6 @@ public class TableToolBar extends JToolBar implements MouseListener, ItemListene
// scale changed
try {
curTable.setScaleByCategory((String)scaleSelection.getSelectedItem());
if(curTable instanceof Table1D) {
Table parentTable = ((Table1D)curTable).getAxisParent();
parentTable.getTableView().updateTableLabel();
}
updateToolbarIncrementDecrementValues();
} catch (NameNotFoundException e1) {
e1.printStackTrace();
@ -763,9 +769,6 @@ public class TableToolBar extends JToolBar implements MouseListener, ItemListene
} else if (e.getSource() == overlayLog) {
// enable/disable log overlay and live data display
curTable.getTableView().setOverlayLog(overlayLog.isSelected());
if(!overlayLog.isSelected())
curTable.getTableView().clearLiveDataTrace();
}
}

View File

@ -19,10 +19,6 @@
package com.romraider.xml.ConversionLayer;
import static com.romraider.editor.ecu.ECUEditorManager.getECUEditor;
import static com.romraider.swing.LookAndFeelManager.initLookAndFeel;
import static com.romraider.util.LogManager.initDebugLogging;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@ -44,12 +40,8 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import com.romraider.Settings;
import com.romraider.editor.ecu.ECUEditor;
import com.romraider.editor.ecu.OpenImageWorker;
import com.romraider.util.HexUtil;
import com.romraider.util.ResourceUtil;
import com.romraider.util.SettingsManager;;
public class XDFConversionLayer extends ConversionLayer {
protected static final ResourceBundle rb = new ResourceUtil().getBundle(
@ -70,6 +62,12 @@ public class XDFConversionLayer extends ConversionLayer {
// Defaults
String defaultDataType;
private class EmbedInfoData {
Element tableNodeRR;
Node axisNode;
Node flagsNodeTable;
}
@Override
public String getDefinitionPickerInfo() {
return rb.getString("LOADINGWARNING");
@ -131,12 +129,6 @@ public class XDFConversionLayer extends ConversionLayer {
}
}
private class EmbedInfoData {
Element tableNodeRR;
Node axisNode;
Node flagsNodeTable;
}
private Element parseAxis(Document doc, Element tableNodeRR, Node axisNode, Node flagsNodeTable) {
Node idNode = axisNode.getAttributes().getNamedItem("id");
String id = "";
@ -172,18 +164,19 @@ public class XDFConversionLayer extends ConversionLayer {
targetTable.removeAttribute("category");
// Find scaling child and delete child tables
LinkedList < Node > nodesToRemove = new LinkedList <Node> ();
for (int j = 0; j < nodeCountRefTable; j++) {
Node tN = targetTable.getChildNodes().item(j);
if (tN == null)
continue;
if (tN.getNodeName().equalsIgnoreCase("table") ||
tN.getNodeName().equalsIgnoreCase("description")) {
targetTable.removeChild(tN);
nodesToRemove.add(tN);
} else if (tN.getNodeName().equalsIgnoreCase("scaling")) {
scaling = (Element) tN;
}
}
for (Node nodeToRemove: nodesToRemove)
targetTable.removeChild(nodeToRemove);
}
// Referenced Table is not yet parsed
else {
@ -193,8 +186,7 @@ public class XDFConversionLayer extends ConversionLayer {
e.tableNodeRR = tableNodeRR;
embedsToSolve.add(e);
// Return an empty table so we count as an axis...
return doc.createElement("table");
return null;
}
hasEmbedInfo = true;
@ -212,20 +204,23 @@ public class XDFConversionLayer extends ConversionLayer {
}
Node addressNode = null;
int staticCells = 0;
LinkedList<String> staticCells = new LinkedList<String>();
int indexCount = -1;
String lastStaticValue = "";
int numDigitsStatic = -1;
int localNumDigits = -1;
if (!hasEmbedInfo) {
for (int i = 0; i < nodeCountAxis; i++) {
n = axisNode.getChildNodes().item(i);
for (int i = 0; i < nodeCountAxis; i++) {
n = axisNode.getChildNodes().item(i);
if (n.getNodeName().equalsIgnoreCase("indexcount")) {
indexCount = Integer.parseInt(n.getTextContent());
targetTable.setAttribute("size" + id.toLowerCase(), "" + indexCount);
} else if (n.getNodeName().equalsIgnoreCase("embeddeddata")) {
if (n.getNodeName().equalsIgnoreCase("units")) {
scaling.setAttribute("units", n.getTextContent());
} else if (n.getNodeName().equalsIgnoreCase("indexcount")) {
indexCount = Integer.parseInt(n.getTextContent());
targetTable.setAttribute("size" + id.toLowerCase(), "" + indexCount);
}
if (!hasEmbedInfo) {
if (n.getNodeName().equalsIgnoreCase("embeddeddata")) {
addressNode = n.getAttributes().getNamedItem("mmedaddress");
if (addressNode != null) {
@ -277,64 +272,57 @@ public class XDFConversionLayer extends ConversionLayer {
targetTable.setAttribute("storagetype", (signedLocal ? "" : "u") + "int" + sizeBits);
targetTable.setAttribute("endian", lsbFirstLocal ? "big" : "little");
} else if (n.getNodeName().equalsIgnoreCase("units")) {
scaling.setAttribute("units", n.getTextContent());
} else if (n.getNodeName().equalsIgnoreCase("decimalpl")) {
try {
localNumDigits = Math.abs(Integer.parseInt(n.getTextContent()));
} catch (NumberFormatException e) {
//Do nothing
}
} else if (!hasEmbedInfo && n.getNodeName().equalsIgnoreCase("math")) {
String formula = n.getAttributes().getNamedItem("equation").getNodeValue();
formula = formula.replace("X", "x").replace(",", ".");
scaling.setAttribute("expression", formula);
} else if (n.getNodeName().equalsIgnoreCase("decimalpl")) {
try {
localNumDigits = Math.abs(Integer.parseInt(n.getTextContent()));
} catch (NumberFormatException e) {
//Do nothing
}
} else if (n.getNodeName().equalsIgnoreCase("label")) {
String label = n.getAttributes().getNamedItem("value").getNodeValue();
Element data = doc.createElement("data");
data.setTextContent(label);
targetTable.appendChild(data);
lastStaticValue = label;
staticCells++;
if(numDigitsStatic == -1)
{
// Assume the format from the static data
String split[] = label.split("\\.");
if(split.length > 1)
{
numDigitsStatic = split[1].length();
}
else
{
numDigitsStatic = 0;
}
}
staticCells.add(label);
}
}
}
boolean isStatic = staticCells == indexCount && indexCount > 1 && !lastStaticValue.equalsIgnoreCase("0.00");
if (isStatic)
{
boolean isStatic = staticCells.size() == indexCount && indexCount > 1 && !staticCells.peekLast().equalsIgnoreCase("0.00");
if (isStatic) {
staticTable = "Static ";
targetTable.setAttribute("size" + id, "" + staticCells);
targetTable.setAttribute("size" + id, "" + staticCells.size());
targetTable.removeAttribute("endian");
targetTable.removeAttribute("storagetype");
}
// Case 1: Static table and no num digits set == Deduce from text
// Case 2: Non static table and digits are set
// Case 3: Non static table and digits arent sent --> use defaults
int digits = isStatic && localNumDigits == -1 ? numDigitsStatic : (localNumDigits == -1 ? numDigits : localNumDigits);
if (digits == 0)
for(String label : staticCells)
{
Element data = doc.createElement("data");
data.setTextContent(label);
targetTable.appendChild(data);
if (numDigitsStatic == -1) {
// Assume the format from the static data
String split[] = label.split("\\.");
if (split.length > 1) {
numDigitsStatic = split[1].length();
} else {
numDigitsStatic = 0;
}
}
}
}
// Case 1: Static table and no num digits set == Deduce from text
// Case 2: Non static table and digits are set
// Case 3: Non static table and digits arent sent --> use defaults
int digits = isStatic && localNumDigits == -1 ? numDigitsStatic : (localNumDigits == -1 ? numDigits : localNumDigits);
if (digits == 0)
scaling.setAttribute("format", "0");
else
scaling.setAttribute("format", "0." + new String(new char[digits]).replace("\0", "0"));
if (!targetTable.hasAttribute("storageaddress") && staticTable.isEmpty())
return null;
else
scaling.setAttribute("format", "0." + new String(new char[digits]).replace("\0", "0"));
if (id.equalsIgnoreCase("z"))
return null;
@ -358,7 +346,6 @@ public class XDFConversionLayer extends ConversionLayer {
}
LinkedList < String > categories = new LinkedList < String > ();
int numAxis = 0;
for (int i = 0; i < nodeCountTable; i++) {
n = tableNode.getChildNodes().item(i);
@ -377,8 +364,6 @@ public class XDFConversionLayer extends ConversionLayer {
desc.setTextContent(n.getTextContent());
tableNodeRR.appendChild(desc);
} else if (n.getNodeName().equalsIgnoreCase("categorymem")) {
// int index =
// Integer.parseInt(n.getAttributes().getNamedItem("index").getNodeValue());
int category = Integer.parseInt(n.getAttributes().getNamedItem("category").getNodeValue());
if (categoryMap.containsKey(category - 1)) {
@ -388,31 +373,68 @@ public class XDFConversionLayer extends ConversionLayer {
Element axis = parseAxis(doc, tableNodeRR, n, flagsNode);
if (axis != null) {
numAxis++;
// This checks if we have embed info
if (axis.hasAttribute("type")) {
// Use the sizes of the X and Y axis
// for the main table
Attr sizex = axis.getAttributeNode("sizex");
Attr sizey = axis.getAttributeNode("sizey");
if (sizex != null)
tableNodeRR.setAttributeNode((Attr) sizex.cloneNode(false));
else if (sizey != null)
tableNodeRR.setAttributeNode((Attr) sizey.cloneNode(false));
tableNodeRR.appendChild(axis);
}
tableNodeRR.appendChild(axis);
}
}
}
tableNodeRR.setAttribute("category", convertToRRCategoryString(categories));
tableNodeRR.setAttribute("type", (numAxis + 1) + "D");
return tableNodeRR;
}
private Element getScalingNodeForTable(Element tableNodeRR) {
for (int i = 0; i < tableNodeRR.getChildNodes().getLength(); i++) {
Element n = (Element) tableNodeRR.getChildNodes().item(i);
if (n.getNodeName().equalsIgnoreCase("scaling")) {
return n;
}
}
return null;
}
private void postProcessTable(Element tableNodeRR) {
int validAxis = 0;
int nodeCountTable = tableNodeRR.getChildNodes().getLength();
LinkedList <Element> nodesToRemove = new LinkedList <Element> ();
for (int i = 0; i < nodeCountTable; i++) {
Element n = (Element) tableNodeRR.getChildNodes().item(i);
if (n.getNodeName().equalsIgnoreCase("table")) {
if (n.hasAttribute("storageaddress") || n.getAttributeNode("type").getValue().contains("Static")) {
validAxis++;
// Use the sizes of the X and Y axis
// for the main table
Attr sizex = n.getAttributeNode("sizex");
Attr sizey = n.getAttributeNode("sizey");
if (sizex != null)
tableNodeRR.setAttributeNode((Attr) sizex.cloneNode(false));
else if (sizey != null)
tableNodeRR.setAttributeNode((Attr) sizey.cloneNode(false));
} else {
Element scalingNode = getScalingNodeForTable(tableNodeRR);
Element axisScalingNode = getScalingNodeForTable(n);
// 2D Tables work different in XDFs
// We have to use the unit of the "missing" axis for the main table
if (scalingNode != null && axisScalingNode != null && !scalingNode.hasAttribute("units")) {
scalingNode.setAttribute("units", axisScalingNode.getAttribute("units"));
}
nodesToRemove.add(n);
}
}
}
for (Element n: nodesToRemove) {
tableNodeRR.removeChild(n);
}
tableNodeRR.setAttribute("type", (validAxis + 1) + "D");
}
private String convertToRRCategoryString(List < String > categories) {
String category = "";
for (int i = 0; i < categories.size(); i++) {
@ -559,23 +581,26 @@ public class XDFConversionLayer extends ConversionLayer {
throw new SAXException(rb.getString("NOXDFHEADER"));
}
LinkedList <Element> tables = new LinkedList <Element> ();
// Go through all tables and create RR tables
for (int i = 0; i < nodeCount; i++) {
Node n = baseNode.getChildNodes().item(i);
if (n.getNodeName().equalsIgnoreCase("XDFTABLE")) {
Element table = parseTable(doc, romNode, n);
if (table != null)
romNode.appendChild(table);
if (table != null) {
tables.add(table);
}
}
// A constant is a mix between a table and an axis
// So parse it as both
else if (n.getNodeName().equalsIgnoreCase("XDFCONSTANT")) {
Element table = parseTable(doc, romNode, n);
parseAxis(doc, table, n, null);
table.setAttribute("type", "1D");
if (table != null)
romNode.appendChild(table);
if (table != null) {
tables.add(table);
}
}
}
@ -588,10 +613,15 @@ public class XDFConversionLayer extends ConversionLayer {
e.tableNodeRR.appendChild(axis);
}
// Final cleanup and add tables to ROM
for (Element t: tables) {
postProcessTable(t);
romNode.appendChild(t);
}
categoryMap.clear();
tableMap.clear();
embedsToSolve.clear();
return doc;
}
}

View File

@ -68,7 +68,6 @@ public final class DOMRomUnmarshaller {
tableScaleHandler.unmarshallBaseScales(rootNode);
Rom rom = new Rom(new RomID());
rom.setDefinitionPath(definition);
Rom output = unmarshallRom(romNode, rom);
//Set ram offset

View File

@ -118,7 +118,7 @@ public class XDFConversionLayerTest{
Vector<Table> tables = r.getTables();
for (Table table:tables)
{
editor.createTableView(table);
// editor.createTableView(table);
}
}
}