commit 78d990032ebdee6e0a0ec78621ac281b1c03b2da Author: drees Date: Fri Jun 23 06:53:08 2006 +0000 Create trunk, branches and tags directories. Move graphics, ecu_defs and src under trunk. git-svn-id: http://svn.3splooges.com/romraider-arch/trunk@6 d2e2e1cd-ba16-0410-be16-b7c4453c7c2d diff --git a/src/enginuity/ECUEditor.java b/src/enginuity/ECUEditor.java new file mode 100644 index 00000000..13bbdbc3 --- /dev/null +++ b/src/enginuity/ECUEditor.java @@ -0,0 +1,280 @@ +package enginuity; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.Vector; +import javax.swing.ImageIcon; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.tree.DefaultMutableTreeNode; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import com.sun.org.apache.xerces.internal.parsers.DOMParser; +import enginuity.maps.Rom; +import enginuity.maps.Table; +import enginuity.net.URL; +import enginuity.swing.ECUEditorMenuBar; +import enginuity.swing.ECUEditorToolBar; +import enginuity.swing.JProgressPane; +import enginuity.swing.MDIDesktopPane; +import enginuity.swing.RomTree; +import enginuity.swing.RomTreeNode; +import enginuity.swing.TableFrame; +import enginuity.xml.DOMSettingsBuilder; +import enginuity.xml.DOMSettingsUnmarshaller; + +public class ECUEditor extends JFrame implements WindowListener { + + private DefaultMutableTreeNode imageRoot = new DefaultMutableTreeNode("Open Images"); + private RomTree imageList = new RomTree(imageRoot); + private Vector images = new Vector(); + private Settings settings = new Settings(); + private String version = new String("0.2.7.4 Beta"); + private String versionDate = new String("5/09/2006"); + private String titleText = new String("Enginuity v" + version); + private MDIDesktopPane rightPanel = new MDIDesktopPane(); + private Rom lastSelectedRom = null; + private JSplitPane splitPane = new JSplitPane(); + private ECUEditorToolBar toolBar; + private ECUEditorMenuBar menuBar; + + public ECUEditor() { + + // get settings from xml + try { + InputSource src = new InputSource(new FileInputStream(new File("./settings.xml"))); + DOMSettingsUnmarshaller domUms = new DOMSettingsUnmarshaller(); + DOMParser parser = new DOMParser(); + parser.parse(src); + Document doc = parser.getDocument(); + settings = domUms.unmarshallSettings(doc.getDocumentElement()); + } catch (Exception ex) { + JOptionPane.showMessageDialog(this, "Settings file not found.\n" + + "A new file will be created.", "Error Loading Settings", JOptionPane.INFORMATION_MESSAGE); + } + + setSize(getSettings().getWindowSize()); + setLocation(getSettings().getWindowLocation()); + if (getSettings().isWindowMaximized() == true) setExtendedState(JFrame.MAXIMIZED_BOTH); + + JScrollPane rightScrollPane = new JScrollPane(rightPanel, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + JScrollPane leftScrollPane = new JScrollPane(imageList, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScrollPane, rightScrollPane); + splitPane.setDividerSize(4); + splitPane.setDividerLocation(getSettings().getSplitPaneLocation()); + this.getContentPane().add(splitPane); + rightPanel.setBackground(Color.BLACK); + imageList.setScrollsOnExpand(true); + imageList.setContainer(this); + + //create menubar and toolbar + menuBar = new ECUEditorMenuBar(this); + this.setJMenuBar(menuBar); + toolBar = new ECUEditorToolBar(this); + this.add(toolBar, BorderLayout.NORTH); + + //set remaining window properties + setIconImage(new ImageIcon("./graphics/enginuity-ico.gif").getImage()); + setDefaultCloseOperation(EXIT_ON_CLOSE); + addWindowListener(this); + setTitle(titleText); + setVisible(true); + } + + public void windowClosing(WindowEvent e) { + getSettings().setSplitPaneLocation(splitPane.getDividerLocation()); + if (getExtendedState() == JFrame.MAXIMIZED_BOTH) getSettings().setWindowMaximized(true); + else { + getSettings().setWindowMaximized(false); + getSettings().setWindowSize(getSize()); + getSettings().setWindowLocation(getLocation()); + } + + DOMSettingsBuilder builder = new DOMSettingsBuilder(); + try { + JProgressPane progress = new JProgressPane(this, "Saving settings...", "Saving settings..."); + + builder.buildSettings(settings, new File("./settings.xml"), progress); + + } catch (IOException ex) { } + } + public void windowOpened(WindowEvent e) { } + public void windowClosed(WindowEvent e) { } + public void windowIconified(WindowEvent e) { } + public void windowDeiconified(WindowEvent e) { } + public void windowActivated(WindowEvent e) { } + public void windowDeactivated(WindowEvent e) { } + + public static void main(String args[]) { + new ECUEditor(); + } + + public String getVersion() { + return version; + } + + public Settings getSettings() { + return settings; + } + + public void addRom(Rom input) { + // add to image vector + images.add(input); + + // add to ecu image list pane + RomTreeNode romNode = new RomTreeNode(input); + imageRoot.add(romNode); + imageList.updateUI(); + + // add tables + Vector tables = input.getTables(); + for (int i = 0; i < tables.size(); i++) { + romNode.add(tables.get(i)); + } + imageList.expandRow(imageList.getRowCount() - 1); + imageList.updateUI(); + this.setLastSelectedRom(input); + + if (input.getRomID().isObsolete() && settings.isObsoleteWarning()) { + JPanel infoPanel = new JPanel(); + infoPanel.setLayout(new GridLayout(3, 1)); + infoPanel.add(new JLabel("A newer version of this ECU revision exists. " + + "Please visit the following link to download the latest revision:")); + infoPanel.add(new URL(getSettings().getRomRevisionURL())); + + JCheckBox check = new JCheckBox("Always display this message", true); + check.setHorizontalAlignment(JCheckBox.RIGHT); + + check.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + settings.setObsoleteWarning(((JCheckBox)e.getSource()).isSelected()); + } + } + ); + + infoPanel.add(check); + JOptionPane.showMessageDialog(this, infoPanel, "ECU Revision is Obsolete", JOptionPane.INFORMATION_MESSAGE); + } + input.setContainer(this); + } + + public void displayTable(TableFrame frame) { + frame.setVisible(true); + try { + rightPanel.add(frame); + } catch (IllegalArgumentException ex) { + // table is already open, so set focus + frame.requestFocus(); + } + frame.setSize(frame.getTable().getFrameSize()); + rightPanel.repaint(); + } + + public void removeDisplayTable(TableFrame frame) { + rightPanel.remove(frame); + rightPanel.repaint(); + } + + public void closeImage() { + for (int i = 0; i < imageRoot.getChildCount(); i++) { + RomTreeNode romTreeNode = (RomTreeNode)imageRoot.getChildAt(i); + Rom rom = romTreeNode.getRom(); + if (rom == lastSelectedRom) { + Vector
romTables = rom.getTables(); + for (Iterator j = romTables.iterator(); j.hasNext();) { + Table t = (Table)j.next(); + rightPanel.remove(t.getFrame()); + } + rom.closeImage(); + romTreeNode.setRom(null); + romTreeNode.removeAllChildren(); + images.remove(i); + imageRoot.remove(romTreeNode); + break; + } + } + imageList.updateUI(); + try { + setLastSelectedRom(((RomTreeNode)imageRoot.getChildAt(0)).getRom()); + } catch (Exception ex) { + // no other images open + setLastSelectedRom(null); + } + rightPanel.repaint(); + } + + public void closeAllImages() { + while (imageRoot.getChildCount() > 0) { + ((Rom)images.get(0)).closeImage(); + images.remove(0); + imageRoot.remove(0); + } + imageList.updateUI(); + setLastSelectedRom(null); + rightPanel.removeAll(); + rightPanel.repaint(); + } + + public Rom getLastSelectedRom() { + return lastSelectedRom; + } + + public void setLastSelectedRom(Rom lastSelectedRom) { + this.lastSelectedRom = lastSelectedRom; + if (lastSelectedRom == null) { + this.setTitle(titleText); + } else { + this.setTitle(titleText + " - " + lastSelectedRom.getFileName()); + } + + // update filenames + for (int i = 0; i < imageRoot.getChildCount(); i++) { + ((RomTreeNode)imageRoot.getChildAt(i)).updateFileName(); + } + + toolBar.updateButtons(); + menuBar.updateMenu(); + imageList.updateUI(); + } + + public ECUEditorToolBar getToolBar() { + return toolBar; + } + + public void setToolBar(ECUEditorToolBar toolBar) { + this.toolBar = toolBar; + } + + public void setSettings(Settings settings) { + this.settings = settings; + for (int i = 0; i < images.size(); i++) { + images.get(i).setContainer(this); + } + } + + public void repaintPanel() { + rightPanel.repaint(); + rightPanel.update(rightPanel.getGraphics()); + } + + public Vector getImages() { + return images; + } +} \ No newline at end of file diff --git a/src/enginuity/Settings.java b/src/enginuity/Settings.java new file mode 100644 index 00000000..21fc8713 --- /dev/null +++ b/src/enginuity/Settings.java @@ -0,0 +1,206 @@ +package enginuity; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Point; +import java.io.File; +import java.io.Serializable; +import java.util.Vector; + +public class Settings implements Serializable { + + private Dimension windowSize = new Dimension(800, 600); + private Point windowLocation = new Point(); + private int splitPaneLocation = 150; + private boolean windowMaximized = false; + + private String romRevisionURL = "http://www.scoobypedia.co.uk/index.php/Knowledge/ECUVersionCompatibilityList"; + private String supportURL = "http://www.enginuity.org"; + + private Vector ecuDefinitionFiles = new Vector(); + private File lastImageDir = new File("images"); + private boolean obsoleteWarning = true; + private boolean calcConflictWarning = true; + private boolean debug = false; + + private Font tableFont = new Font("Arial", Font.BOLD, 12); + private Dimension cellSize = new Dimension(42, 18); + private Color maxColor = new Color(255, 155, 155); + private Color minColor = new Color(255, 255, 155); + private Color highlightColor = new Color(155, 155, 255); + private Color increaseBorder = new Color(255, 0, 0); + private Color decreaseBorder = new Color(0, 0, 255); + private Color axisColor = new Color(255, 255, 255); + private boolean singleTableView = false; ////// + + public Settings() { + //center window by default + addEcuDefinitionFile(new File("ecu_defs.xml")); + Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + windowLocation.move(((int)(screenSize.getWidth() - windowSize.getWidth()) / 2), + ((int)(screenSize.getHeight() - windowSize.getHeight()) / 2)); + } + + public Dimension getWindowSize() { + return windowSize; + } + + public Point getWindowLocation() { + return windowLocation; + } + + public void setWindowSize(Dimension size) { + windowSize.setSize(size); + } + + public void setWindowLocation(Point location) { + windowLocation.setLocation(location); + } + + public File getEcuDefinitionFile() { + return ecuDefinitionFiles.elementAt(0); + } + + public void addEcuDefinitionFile(File ecuDefinitionFile) { + if (ecuDefinitionFiles.size() == 0) + ecuDefinitionFiles.add(ecuDefinitionFile); + else ecuDefinitionFiles.set(0, ecuDefinitionFile); + } + + public File getLastImageDir() { + return lastImageDir; + } + + public void setLastImageDir(File lastImageDir) { + this.lastImageDir = lastImageDir; + } + + public int getSplitPaneLocation() { + return splitPaneLocation; + } + + public void setSplitPaneLocation(int splitPaneLocation) { + this.splitPaneLocation = splitPaneLocation; + } + + public boolean isWindowMaximized() { + return windowMaximized; + } + + public void setWindowMaximized(boolean windowMaximized) { + this.windowMaximized = windowMaximized; + } + + public String getRomRevisionURL() { + return romRevisionURL; + } + + public void setRomRevisionURL(String romRevisionURL) { + this.romRevisionURL = romRevisionURL; + } + + public String getSupportURL() { + return supportURL; + } + + public void setSupportURL(String supportURL) { + this.supportURL = supportURL; + } + + public Font getTableFont() { + return tableFont; + } + + public void setTableFont(Font tableFont) { + this.tableFont = tableFont; + } + + public boolean isObsoleteWarning() { + return obsoleteWarning; + } + + public void setObsoleteWarning(boolean obsoleteWarning) { + this.obsoleteWarning = obsoleteWarning; + } + + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public Dimension getCellSize() { + return cellSize; + } + + public void setCellSize(Dimension cellSize) { + this.cellSize = cellSize; + } + + public Color getMaxColor() { + return maxColor; + } + + public void setMaxColor(Color maxColor) { + this.maxColor = maxColor; + } + + public Color getMinColor() { + return minColor; + } + + public void setMinColor(Color minColor) { + this.minColor = minColor; + } + + public boolean isSingleTableView() { + return singleTableView; + } + + public void setSingleTableView(boolean singleTableView) { + this.singleTableView = singleTableView; + } + + public Color getHighlightColor() { + return highlightColor; + } + + public void setHighlightColor(Color highlightColor) { + this.highlightColor = highlightColor; + } + + public boolean isCalcConflictWarning() { + return calcConflictWarning; + } + + public void setCalcConflictWarning(boolean calcConflictWarning) { + this.calcConflictWarning = calcConflictWarning; + } + + public Color getIncreaseBorder() { + return increaseBorder; + } + + public void setIncreaseBorder(Color increaseBorder) { + this.increaseBorder = increaseBorder; + } + + public Color getDecreaseBorder() { + return decreaseBorder; + } + + public void setDecreaseBorder(Color decreaseBorder) { + this.decreaseBorder = decreaseBorder; + } + + public Color getAxisColor() { + return axisColor; + } + + public void setAxisColor(Color axisColor) { + this.axisColor = axisColor; + } +} \ No newline at end of file diff --git a/src/enginuity/maps/DataCell.java b/src/enginuity/maps/DataCell.java new file mode 100644 index 00000000..4cc6fd68 --- /dev/null +++ b/src/enginuity/maps/DataCell.java @@ -0,0 +1,268 @@ +package enginuity.maps; + +import com.sun.corba.se.spi.activation._ActivatorImplBase; +import enginuity.maps.Scale; +import enginuity.maps.Table; +import java.awt.Color; +import java.awt.Font; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.Serializable; +import java.text.DecimalFormat; +import javax.swing.JLabel; +import javax.swing.border.LineBorder; +import org.nfunk.jep.*; + +public class DataCell extends JLabel implements MouseListener, Serializable { + + private int binValue = 0; + private int originalValue = 0; + private Scale scale = new Scale(); + private String displayValue = ""; + private Color scaledColor = new Color(0,0,0); + private Color highlightColor = new Color(155,155,255); + private Color increaseBorder = Color.RED; + private Color decreaseBorder = Color.BLUE; + private Boolean selected = false; + private Boolean highlighted = false; + private Table table; + private int x = 0; + private int y = 0; + private int compareValue = 0; + private int compareType = Table.COMPARE_OFF; + private int compareDisplay = Table.COMPARE_ABSOLUTE; + + public DataCell() { } + + public DataCell(Scale scale) { + this.scale = scale; + this.setHorizontalAlignment(CENTER); + this.setVerticalAlignment(CENTER); + this.setFont(new Font("Arial", Font.BOLD, 12)); + this.setBorder(new LineBorder(Color.BLACK, 1)); + this.setOpaque(true); + this.setVisible(true); + this.addMouseListener(this); + } + + public void updateDisplayValue() { + DecimalFormat formatter = new DecimalFormat(scale.getFormat()); + + if (getCompareType() == Table.COMPARE_OFF) { + displayValue = formatter.format(calcDisplayValue(binValue, table.getScale().getExpression())); + + } else { + if (getCompareDisplay() == Table.COMPARE_ABSOLUTE) { + displayValue = formatter.format( + calcDisplayValue(binValue, table.getScale().getExpression()) - + calcDisplayValue(compareValue, table.getScale().getExpression())); + + /*System.out.println(calcDisplayValue(binValue, table.getScale().getExpression()) + " - " + + calcDisplayValue(compareValue, table.getScale().getExpression()) + //" = " + + "(" + compareValue + ") = " + + displayValue);*/ + + } else if (getCompareDisplay() == Table.COMPARE_PERCENT) { + double difference = calcDisplayValue(binValue, table.getScale().getExpression()) - + calcDisplayValue(compareValue, table.getScale().getExpression()); + if (difference == 0) displayValue = "0%"; + else displayValue = (int)(difference / calcDisplayValue(binValue, table.getScale().getExpression()) * 100)+"%"; + } + } + setText(displayValue); + } + + public double calcDisplayValue(int input, String expression) { + JEP parser = new JEP(); + parser.initSymTab(); // clear the contents of the symbol table + parser.addVariable("x", input); + parser.parseExpression(expression); + return parser.getValue(); + } + + public void setColor(Color color) { + scaledColor = color; + if (!selected) super.setBackground(color); + } + + public void setDisplayValue(String displayValue) { + this.displayValue = displayValue; + this.setText(displayValue); + } + + public void setBinValue(int binValue) { + this.binValue = binValue; + // make sure it's in range + if (binValue < 0) { + this.setBinValue(0); + } else if (binValue > Math.pow(256, table.getStorageType()) - 1) { + this.setBinValue((int)(Math.pow(256, table.getStorageType()) - 1)); + } + this.updateDisplayValue(); + } + + public int getBinValue() { + return binValue; + } + + public String toString() { + return displayValue; + } + + public Boolean isSelected() { + return selected; + } + + public void setSelected(Boolean selected) { + this.selected = selected; + if (selected) { + this.setBackground(getHighlightColor()); + table.getFrame().getToolBar().setCoarseValue(Math.abs(table.getScale().getIncrement())); + } else { + this.setBackground(scaledColor); + } + requestFocus(); + } + + public void setHighlighted(Boolean highlighted) { + if (!table.isStatic()) { + this.highlighted = highlighted; + if (highlighted) { + this.setBackground(getHighlightColor()); + } else { + if (!selected) this.setBackground(scaledColor); + } + } + } + + public boolean isHighlighted() { + return highlighted; + } + + public void mouseEntered(MouseEvent e) { + table.highlight(x, y); + } + + public void mousePressed(MouseEvent e) { + if (!table.isStatic()) { + if (!e.isControlDown()) table.clearSelection(); + table.startHighlight(x, y); + } + requestFocus(); + } + + public void mouseReleased(MouseEvent e) { + if (!table.isStatic()) { + table.stopHighlight(); + } + } + + public void mouseClicked(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } + + public void increment(int increment) { + if (table.getScale().getIncrement() < 0) increment = 0 - increment; + this.setBinValue(binValue + increment); + table.colorize(); + } + + public void setTable(Table table) { + this.table = table; + } + + public void setXCoord(int x) { + this.x = x; + } + + public void setYCoord(int y) { + this.y = y; + } + + public int getOriginalValue() { + return originalValue; + } + + public void setOriginalValue(int originalValue) { + this.originalValue = originalValue; + if (binValue != getOriginalValue()) { + this.setBorder(new LineBorder(Color.RED, 3)); + } else { + this.setBorder(new LineBorder(Color.BLACK, 1)); + } + } + + public void undo() { + this.setBinValue(originalValue); + } + + public void setRevertPoint() { + this.setOriginalValue(binValue); + } + + public void setRealValue(String input) { + // create parser + if (!input.equalsIgnoreCase("x")) { + JEP parser = new JEP(); + parser.initSymTab(); // clear the contents of the symbol table + parser.addVariable("x", Double.parseDouble(input)); + parser.parseExpression(table.getScale().getByteExpression()); + this.setBinValue((int)Math.round(parser.getValue())); + } + } + + public Color getHighlightColor() { + return highlightColor; + } + + public void setHighlightColor(Color highlightColor) { + this.highlightColor = highlightColor; + } + + public Color getIncreaseBorder() { + return increaseBorder; + } + + public void setIncreaseBorder(Color increaseBorder) { + this.increaseBorder = increaseBorder; + } + + public Color getDecreaseBorder() { + return decreaseBorder; + } + + public void setDecreaseBorder(Color decreaseBorder) { + this.decreaseBorder = decreaseBorder; + } + + public int getCompareValue() { + return compareValue; + } + + public void setCompareValue(int compareValue) { + this.compareValue = compareValue; + } + + public int getCompareType() { + return compareType; + } + + public void setCompareType(int compareType) { + this.compareType = compareType; + } + + public int getCompareDisplay() { + return compareDisplay; + } + + public void setCompareRealValue(String input) { + JEP parser = new JEP(); + parser.initSymTab(); // clear the contents of the symbol table + parser.addVariable("x", Double.parseDouble(input)); + parser.parseExpression(table.getScale().getByteExpression()); + this.setCompareValue((int)Math.round(parser.getValue())); + } + + public void setCompareDisplay(int compareDisplay) { + this.compareDisplay = compareDisplay; + } +} \ No newline at end of file diff --git a/src/enginuity/maps/Rom.java b/src/enginuity/maps/Rom.java new file mode 100644 index 00000000..b8c4b3fe --- /dev/null +++ b/src/enginuity/maps/Rom.java @@ -0,0 +1,153 @@ +package enginuity.maps; + +import enginuity.ECUEditor; +import enginuity.swing.JProgressPane; +import enginuity.xml.TableNotFoundException; +import java.io.File; +import java.io.Serializable; +import java.util.Vector; +import javax.swing.JOptionPane; + +//import Enginuity. + +public class Rom implements Serializable { + + private RomID romID = new RomID(); + private String fileName = ""; + private File fullFileName = new File("."); + private Vector
tables = new Vector
(); + private ECUEditor container; + private byte[] binData; + + public Rom() { + } + + public void addTable(Table table) { + for (int i = 0; i < tables.size(); i++) { + if (tables.get(i).getName().equalsIgnoreCase(table.getName())) { + tables.remove(i); + break; + } + } + tables.add(table); + } + + public Table getTable(String tableName) throws TableNotFoundException { + for (int i = 0; i < tables.size(); i++) { + if (tables.get(i).getName().equalsIgnoreCase(tableName)) { + return tables.get(i); + } + } + throw new TableNotFoundException(); + } + + public void removeTable(String tableName) { + for (int i = 0; i < tables.size(); i++) { + if (tables.get(i).getName().equalsIgnoreCase(tableName)) { + tables.remove(i); + } + } + } + + public void populateTables(byte[] binData, JProgressPane progress) { + this.binData = binData; + for (int i = 0; i < getTables().size(); i++) { + + // update progress + int currProgress = (int)((double)i / (double)getTables().size() * 40); + progress.update("Populating " + tables.get(i).getName() + " table...", 40 + currProgress); + + try { + // if storageaddress has not been set (or is set to 0) omit table + if (tables.get(i).getStorageAddress() != 0) { + tables.get(i).populateTable(binData); + } else { + tables.remove(i); + // decrement i because length of vector has changed + i--; + } + } catch (ArrayIndexOutOfBoundsException ex) { + new JOptionPane().showMessageDialog(container, "Storage address for table \"" + tables.get(i).getName() + + "\" is out of bounds.\nPlease check ECU definition file.", "ECU Definition Error", JOptionPane.ERROR_MESSAGE); + tables.removeElementAt(i); + } catch (NullPointerException ex) { + new JOptionPane().showMessageDialog(container, "There was an error loading table " + tables.get(i).getName(), "ECU Definition Error", JOptionPane.ERROR_MESSAGE); + tables.removeElementAt(i); + } + } + } + + public void setRomID(RomID romID) { + this.romID = romID; + } + + public RomID getRomID() { + return romID; + } + + public String getRomIDString() { + return romID.getXmlid(); + } + + public String toString() { + String output = ""; + output = output + "\n---- Rom ----" + romID.toString(); + for (int i = 0; i < getTables().size(); i++) { + output = output + getTables().get(i); + } + output = output + "\n---- End Rom ----"; + + return output; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Vector
getTables() { + return tables; + } + + public ECUEditor getContainer() { + return container; + } + + public void setContainer(ECUEditor container) { + this.container = container; + // apply settings to tables + for (int i = 0; i < tables.size(); i++) { + tables.get(i).finalize(container.getSettings()); + tables.get(i).resize(); + } + } + + public byte[] saveFile() { + for (int i = 0; i < tables.size(); i++) { + tables.get(i).saveFile(binData); + } + return binData; + } + + public void closeImage() { + for (int i = 0; i < tables.size(); i++) { + tables.get(i).getFrame().dispose(); + } + } + + public int getRealFileSize() { + return binData.length; + } + + public File getFullFileName() { + return fullFileName; + } + + public void setFullFileName(File fullFileName) { + this.fullFileName = fullFileName; + this.setFileName(fullFileName.getName()); + } +} \ No newline at end of file diff --git a/src/enginuity/maps/RomID.java b/src/enginuity/maps/RomID.java new file mode 100644 index 00000000..d245df0e --- /dev/null +++ b/src/enginuity/maps/RomID.java @@ -0,0 +1,173 @@ +//ECU version definition + +package enginuity.maps; + +import java.io.Serializable; + +public class RomID implements Serializable { + + private String xmlid = "";//ID stored in XML + private int internalIdAddress = 0;//address of ECU version in image + private String internalIdString = "";//ID stored in image + private String caseId = "";//ECU hardware version + private String ecuId = ""; + private String make = "";//manufacturer + private String market = ""; + private String model = ""; + private String subModel = "";//trim, ie WRX + private String transmission = ""; + private int year = 0; + private String flashMethod = "";//flash method string used for ecuflash + private String memModel = "";//model used for reflashing with ecuflash + private int fileSize = 0; + private int ramOffset = 0; + private boolean obsolete = false; // whether a more recent revision exists + + public String toString() { + return "\n ---- RomID " + xmlid + " ----" + + "\n Internal ID Address: " + internalIdAddress + + "\n Internal ID String: " + internalIdString + + "\n Case ID: " + caseId + + "\n ECU ID: " + ecuId + + "\n Make: " + make + + "\n Market: " + market + + "\n Model: " + model + + "\n Submodel: " + subModel + + "\n Transmission: " + transmission + + "\n Year: " + year + + "\n Flash Method: " + flashMethod + + "\n Memory Model: " + memModel + + "\n ---- End RomID " + xmlid + " ----"; + } + + public RomID() { + } + + public String getXmlid() { + return xmlid; + } + + public void setXmlid(String xmlid) { + this.xmlid = xmlid; + } + + public int getInternalIdAddress() { + return internalIdAddress; + } + + public void setInternalIdAddress(int internalIdAddress) { + this.internalIdAddress = internalIdAddress; + } + + public String getInternalIdString() { + return internalIdString; + } + + public void setInternalIdString(String internalIdString) { + this.internalIdString = internalIdString; + } + + public String getCaseId() { + return caseId; + } + + public void setCaseId(String caseId) { + this.caseId = caseId; + } + + public String getEcuId() { + return ecuId; + } + + public void setEcuId(String ecuId) { + this.ecuId = ecuId; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public String getMarket() { + return market; + } + + public void setMarket(String market) { + this.market = market; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getSubModel() { + return subModel; + } + + public void setSubModel(String subModel) { + this.subModel = subModel; + } + + public String getTransmission() { + return transmission; + } + + public void setTransmission(String transmission) { + this.transmission = transmission; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public String getFlashMethod() { + return flashMethod; + } + + public void setFlashMethod(String flashMethod) { + this.flashMethod = flashMethod; + } + + public String getMemModel() { + return memModel; + } + + public void setMemModel(String memModel) { + this.memModel = memModel; + } + + public int getRamOffset() { + return ramOffset; + } + + public void setRamOffset(int ramOffset) { + this.ramOffset = ramOffset; + } + + public int getFileSize() { + return fileSize; + } + + public void setFileSize(int fileSize) { + this.fileSize = fileSize; + } + + public boolean isObsolete() { + return obsolete; + } + + public void setObsolete(boolean obsolete) { + this.obsolete = obsolete; + } +} \ No newline at end of file diff --git a/src/enginuity/maps/Scale.java b/src/enginuity/maps/Scale.java new file mode 100644 index 00000000..51cd2fad --- /dev/null +++ b/src/enginuity/maps/Scale.java @@ -0,0 +1,77 @@ +//This object defines the scaling factor and offset for calculating real values + +package enginuity.maps; + +import java.io.Serializable; + +public class Scale implements Serializable { + + public static final int LINEAR = 1; + public static final int INVERSE = 2; + + private String unit; + private String expression = "x"; + private String byteExpression = "x"; + private String format; + private int increment; + + public Scale() { + } + + public String toString() { + return "\n ---- Scale ----" + + "\n Expression: " + getExpression() + + "\n Unit: " + getUnit() + + "\n ---- End Scale ----"; + + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getExpression() { + return expression; + } + + public void setExpression(String expression) { + this.expression = expression; + } + + public int getIncrement() { + return increment; + } + + public void setIncrement(int increment) { + this.increment = increment; + } + + public boolean isReady() { + if (unit == null) return false; + else if (expression == null) return false; + else if (format == null) return false; + else if (increment < 1) return false; + + return true; + } + + public String getByteExpression() { + return byteExpression; + } + + public void setByteExpression(String byteExpression) { + this.byteExpression = byteExpression; + } +} \ No newline at end of file diff --git a/src/enginuity/maps/Table.java b/src/enginuity/maps/Table.java new file mode 100644 index 00000000..d76f4ccb --- /dev/null +++ b/src/enginuity/maps/Table.java @@ -0,0 +1,868 @@ +package enginuity.maps; + +import enginuity.Settings; +import enginuity.xml.RomAttributeParser; +import enginuity.swing.TableFrame; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.io.IOException; +import java.io.Serializable; +import java.util.StringTokenizer; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.InputMap; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.border.LineBorder; +import org.nfunk.jep.JEP; + +public abstract class Table extends JPanel implements Serializable { + + public static final int ENDIAN_LITTLE= 1; + public static final int ENDIAN_BIG = 2; + public static final int TABLE_1D = 1; + public static final int TABLE_2D = 2; + public static final int TABLE_3D = 3; + public static final int TABLE_X_AXIS = 4; + public static final int TABLE_Y_AXIS = 5; + + public static final int COMPARE_OFF = 0; + public static final int COMPARE_ORIGINAL = 1; + public static final int COMPARE_TABLE = 2; + public static final int COMPARE_PERCENT = 0; + public static final int COMPARE_ABSOLUTE = 1; + + protected String name; + protected int type; + protected String category = "Other"; + protected String description = ""; + protected Scale scale = new Scale(); + protected int storageAddress; + protected int storageType;//number of bytes per cell + protected int endian; + protected boolean flip; + protected DataCell[] data = new DataCell[0]; + protected boolean isStatic = false; + protected boolean beforeRam = false; + protected int ramOffset = 0; + protected BorderLayout borderLayout = new BorderLayout(); + protected GridLayout centerLayout = new GridLayout(1,1,0,0); + protected JPanel centerPanel = new JPanel(centerLayout); + protected TableFrame frame; + protected int verticalOverhead = 103; + protected int horizontalOverhead = 2; + protected int cellHeight = 18; + protected int cellWidth = 42; + protected int minHeight = 100; + protected int minWidth = 370; + protected Rom container; + protected int highlightX; + protected int highlightY; + protected boolean highlight = false; + protected Table axisParent; + protected Color maxColor; + protected Color minColor; + protected boolean isAxis = false; + protected int compareType = 0; + protected int compareDisplay = 1; + + public Table() { + this.setLayout(borderLayout); + this.add(centerPanel, BorderLayout.CENTER); + centerPanel.setVisible(true); + + // key binding actions + Action rightAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + cursorRight(); + } + }; + Action leftAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + cursorLeft(); + } + }; + Action downAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + cursorDown(); + } + }; + Action upAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + cursorUp(); + } + }; + Action incCoarseAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + frame.getToolBar().incrementCoarse(); + } + }; + Action decCoarseAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + frame.getToolBar().decrementCoarse(); + } + }; + Action incFineAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + frame.getToolBar().incrementFine(); + } + }; + Action decFineAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + frame.getToolBar().decrementFine(); + } + }; + Action num0Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('0'); + } + }; + Action num1Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('1'); + } + }; + Action num2Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('2'); + } + }; + Action num3Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('3'); + } + }; + Action num4Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('4'); + } + }; + Action num5Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('5'); + } + }; + Action num6Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('6'); + } + }; + Action num7Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('7'); + } + }; + Action num8Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('8'); + } + }; + Action num9Action = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getFrame().getToolBar().focusSetValue('9'); + } + }; + Action copyAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + copySelection(); + } + }; + Action pasteAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + paste(); + } + }; + + // set input mapping + InputMap im = getInputMap(this.WHEN_IN_FOCUSED_WINDOW); + + KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0); + KeyStroke left = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0); + KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0); + KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); + KeyStroke decrement = KeyStroke.getKeyStroke('-'); + KeyStroke increment = KeyStroke.getKeyStroke('+'); + KeyStroke decrement2 = KeyStroke.getKeyStroke("control DOWN"); + KeyStroke increment2 = KeyStroke.getKeyStroke("control UP"); + KeyStroke decrement3 = KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, KeyEvent.CTRL_DOWN_MASK); + KeyStroke increment3 = KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.CTRL_DOWN_MASK); + KeyStroke num0 = KeyStroke.getKeyStroke('0'); + KeyStroke num1 = KeyStroke.getKeyStroke('1'); + KeyStroke num2 = KeyStroke.getKeyStroke('2'); + KeyStroke num3 = KeyStroke.getKeyStroke('3'); + KeyStroke num4 = KeyStroke.getKeyStroke('4'); + KeyStroke num5 = KeyStroke.getKeyStroke('5'); + KeyStroke num6 = KeyStroke.getKeyStroke('6'); + KeyStroke num7 = KeyStroke.getKeyStroke('7'); + KeyStroke num8 = KeyStroke.getKeyStroke('8'); + KeyStroke num9 = KeyStroke.getKeyStroke('9'); + KeyStroke copy = KeyStroke.getKeyStroke("control C"); + KeyStroke paste = KeyStroke.getKeyStroke("control V"); + + im.put(right, "right"); + im.put(left, "left"); + im.put(up, "up"); + im.put(down, "down"); + im.put(increment, "incCoarseAction"); + im.put(decrement, "decCoarseAction"); + im.put(increment2, "incCoarseAction"); + im.put(decrement2, "decCoarseAction"); + im.put(increment3, "incFineAction"); + im.put(decrement3, "decFineAction"); + im.put(num0, "num0Action"); + im.put(num1, "num1Action"); + im.put(num2, "num2Action"); + im.put(num3, "num3Action"); + im.put(num4, "num4Action"); + im.put(num5, "num5Action"); + im.put(num6, "num6Action"); + im.put(num7, "num7Action"); + im.put(num8, "num8Action"); + im.put(num9, "num9Action"); + im.put(copy, "copyAction"); + im.put(paste, "pasteAction"); + + getActionMap().put(im.get(right), rightAction); + getActionMap().put(im.get(left), leftAction); + getActionMap().put(im.get(up), upAction); + getActionMap().put(im.get(down), downAction); + getActionMap().put(im.get(increment), incCoarseAction); + getActionMap().put(im.get(decrement), decCoarseAction); + getActionMap().put(im.get(increment2), incCoarseAction); + getActionMap().put(im.get(decrement2), decCoarseAction); + getActionMap().put(im.get(increment3), incFineAction); + getActionMap().put(im.get(decrement3), decFineAction); + getActionMap().put(im.get(num0), num0Action); + getActionMap().put(im.get(num1), num1Action); + getActionMap().put(im.get(num2), num2Action); + getActionMap().put(im.get(num3), num3Action); + getActionMap().put(im.get(num4), num4Action); + getActionMap().put(im.get(num5), num5Action); + getActionMap().put(im.get(num6), num6Action); + getActionMap().put(im.get(num7), num7Action); + getActionMap().put(im.get(num8), num8Action); + getActionMap().put(im.get(num9), num9Action); + getActionMap().put(im.get(copy), copyAction); + getActionMap().put(im.get(paste), pasteAction); + + this.setInputMap(this.WHEN_FOCUSED, im); + } + + public DataCell[] getData() { + return data; + } + + public void setData(DataCell[] data) { + this.data = data; + } + + public void populateTable(byte[] input) throws ArrayIndexOutOfBoundsException { + if (!isStatic) { + if (!beforeRam) ramOffset = container.getRomID().getRamOffset(); + + for (int i = 0; i < data.length; i++) { + if (data[i] == null) { + data[i] = new DataCell(scale); + data[i].setTable(this); + data[i].setBinValue(RomAttributeParser.parseByteValue(input, endian, storageAddress + i * storageType - ramOffset, storageType)); + data[i].setPreferredSize(new Dimension(cellWidth, cellHeight)); + centerPanel.add(data[i]); + data[i].setYCoord(i); + data[i].setOriginalValue(data[i].getBinValue()); + } + } + } + //this.colorize(); + } + + public int getType() { + return type; + } + + public DataCell getDataCell(int location) { + return data[location]; + } + + public void setType(int type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Scale getScale() { + return scale; + } + + public void setScale(Scale scale) { + this.scale = scale; + } + + public int getStorageAddress() { + return storageAddress; + } + + public void setStorageAddress(int storageAddress) { + this.storageAddress = storageAddress; + } + + public int getStorageType() { + return storageType; + } + + public void setStorageType(int storageType) { + this.storageType = storageType; + } + + public int getEndian() { + return endian; + } + + public void setEndian(int endian) { + this.endian = endian; + } + + public void setDataSize(int size) { + data = new DataCell[size]; + } + + public int getDataSize() { + return data.length; + } + + public boolean getFlip() { + return flip; + } + + public void setFlip(boolean flipY) { + this.flip = flip; + } + public String toString() { + /*String output = "\n ---- Table " + name + " ----" + + scale + + "\n Category: " + category + + "\n Type: " + type + + "\n Description: " + description + + "\n Storage Address: " + Integer.toHexString(storageAddress) + + "\n Storage Type: " + storageType + + "\n Endian: " + endian + + "\n Flip: " + flip + + "\n ---- End Table " + name + " ----"; + for (int i = 0; i < data.length; i++) { + if (data[i] != null) { + output = output + "\nData: " + data[i]; + } + } + + return output;*/ + return name; + } + + public boolean isStatic() { + return isStatic; + } + + public void setIsStatic(boolean isStatic) { + this.isStatic = isStatic; + } + + public void addStaticDataCell(DataCell input) { + if (isStatic) { + for (int i = 0; i < data.length; i++) { + if (data[i] == null) { + data[i] = input; + break; + } + } + } + } + + public void colorize() { + if (compareType == COMPARE_OFF) { + if (!isStatic && !isAxis) { + int high = 0; + int low = 999999999; + + for (int i = 0; i < getDataSize(); i++) { + if (data[i].getBinValue() > high) { + high = data[i].getBinValue(); + } + if (data[i].getBinValue() < low) { + low = data[i].getBinValue(); + } + } + for (int i = 0; i < getDataSize(); i++) { + double scale = (double)(data[i].getBinValue() - low) / (high - low); + int r = (int)((maxColor.getRed() - minColor.getRed()) * scale) + minColor.getRed(); + int g = (int)((maxColor.getGreen() - minColor.getGreen()) * scale) + minColor.getGreen(); + int b = (int)((maxColor.getBlue() - minColor.getBlue()) * scale) + minColor.getBlue(); + + data[i].setColor(new Color(r, g, b)); + } + } else { // is static/axis + for (int i = 0; i < getDataSize(); i++) { + data[i].setColor(axisParent.getRom().getContainer().getSettings().getAxisColor()); + data[i].setOpaque(true); + data[i].setBorder(new LineBorder(Color.BLACK, 1)); + data[i].setHorizontalAlignment(data[i].CENTER); + } + } + + } else { // comparing is on + if (!isStatic) { + int high = 0; + + // determine ratios + for (int i = 0; i < getDataSize(); i++) { + if (Math.abs(data[i].getBinValue() - data[i].getOriginalValue()) > high) { + high = Math.abs(data[i].getBinValue() - data[i].getOriginalValue()); + } + } + + // colorize + for (int i = 0; i < getDataSize(); i++) { + int cellDifference = Math.abs(data[i].getBinValue() - data[i].getOriginalValue()); + double scale; + if (high == 0) scale = 0; + else scale = (double)cellDifference / (double)high; + + int r = (int)((maxColor.getRed() - minColor.getRed()) * scale) + minColor.getRed(); + int g = (int)((maxColor.getGreen() - minColor.getGreen()) * scale) + minColor.getGreen(); + int b = (int)((maxColor.getBlue() - minColor.getBlue()) * scale) + minColor.getBlue(); + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + if (scale != 0) data[i].setColor(new Color(r, g, b)); + else data[i].setColor(new Color(160,160,160)); + + // set border + if (data[i].getBinValue() > data[i].getOriginalValue()) { + data[i].setBorder(new LineBorder(getRom().getContainer().getSettings().getIncreaseBorder())); + } else if (data[i].getBinValue() < data[i].getOriginalValue()) { + data[i].setBorder(new LineBorder(getRom().getContainer().getSettings().getDecreaseBorder())); + } else { + data[i].setBorder(new LineBorder(Color.BLACK, 1)); + } + } + } + } + + // colorize border + if (!isStatic) { + for (int i = 0; i < getDataSize(); i++) { + if (data[i].getBinValue() > data[i].getOriginalValue()) { + data[i].setBorder(new LineBorder(getRom().getContainer().getSettings().getIncreaseBorder())); + } else if (data[i].getBinValue() < data[i].getOriginalValue()) { + data[i].setBorder(new LineBorder(getRom().getContainer().getSettings().getDecreaseBorder())); + } else { + data[i].setBorder(new LineBorder(Color.BLACK, 1)); + } + } + } + } + + public void setFrame(TableFrame frame) { + this.frame = frame; + frame.setSize(getFrameSize()); + } + + public Dimension getFrameSize() { + int height = verticalOverhead + cellHeight; + int width = horizontalOverhead + data.length * cellWidth; + if (height < minHeight) height = minHeight; + if (width < minWidth) width = minWidth; + return new Dimension(width, height); + } + + public TableFrame getFrame() { + return frame; + } + + public void increment(int increment) { + if (!isStatic) { + for (int i = 0; i < data.length; i++) { + if (data[i].isSelected()) data[i].increment(increment); + } + } + } + + public void setRealValue(String realValue) { + if (!isStatic) { + for (int i = 0; i < data.length; i++) { + if (data[i].isSelected()) data[i].setRealValue(realValue); + } + } + colorize(); + } + + public Rom getRom() { + return container; + } + + public void setRom(Rom container) { + this.container = container; + } + + public void clearSelection() { + for (int i = 0; i < data.length; i++) { + data[i].setSelected(false); + } + } + + public void startHighlight(int x, int y) { + this.highlightY = y; + this.highlightX = x; + highlight = true; + highlight(x, y); + } + + public void highlight(int x, int y) { + if (highlight) { + for (int i = 0; i < data.length; i++) { + if ((i >= highlightY && i <= y) || (i <= highlightY && i >= y)) { + data[i].setHighlighted(true); + } else { + data[i].setHighlighted(false); + } + } + } + } + + public void stopHighlight() { + highlight = false; + // loop through, selected and un-highlight + for (int i = 0; i < data.length; i++) { + if (data[i].isHighlighted()) { + data[i].setSelected(true); + data[i].setHighlighted(false); + } + } + } + + public abstract void cursorUp(); + public abstract void cursorDown(); + public abstract void cursorLeft(); + public abstract void cursorRight(); + + public Table getAxisParent() { + return axisParent; + } + + public void setAxisParent(Table axisParent) { + this.axisParent = axisParent; + } + + public void setRevertPoint() { + if (!isStatic) { + for (int i = 0; i < data.length; i++) { + data[i].setOriginalValue(data[i].getBinValue()); + } + } + colorize(); + } + + public void undoAll() { + if (!isStatic) { + for (int i = 0; i < data.length; i++) { + data[i].setBinValue(data[i].getOriginalValue()); + } + } + colorize(); + } + + public void undoSelected() { + if (!isStatic) { + for (int i = 0; i < data.length; i++) { + if (data[i].isSelected()) data[i].setBinValue(data[i].getOriginalValue()); + } + } + colorize(); + } + + public byte[] saveFile(byte[] binData) { + if (!isStatic) { + for (int i = 0; i < data.length; i++) { + // need to deal with storage type (num bytes) + byte[] output = RomAttributeParser.parseIntegerValue(data[i].getBinValue(), endian, storageType); + for (int z = 0; z < storageType; z++) { + binData[i * storageType + z + storageAddress - ramOffset] = output[z]; + } + } + } + return binData; + } + + public boolean isBeforeRam() { + return beforeRam; + } + + public void setBeforeRam(boolean beforeRam) { + this.beforeRam = beforeRam; + } + + public void addKeyListener(KeyListener listener) { + super.addKeyListener(listener); + for (int i = 0; i < data.length; i++) { + byte[] output = RomAttributeParser.parseIntegerValue(data[i].getBinValue(), endian, storageType); + for (int z = 0; z < storageType; z++) { + data[i].addKeyListener(listener); + } + } + } + + public void selectCellAt(int y) { + if (type == TABLE_X_AXIS || type == TABLE_Y_AXIS) axisParent.clearSelection(); + else clearSelection(); + data[y].setSelected(true); + highlightY = y; + } + + public void copySelection() { + // find bounds of selection + // coords[0] = x min, y min, x max, y max + String newline = System.getProperty("line.separator"); + String output ="[Selection1D]" + newline; + boolean copy = false; + int[] coords = new int[2]; + coords[0] = this.getDataSize(); + + for (int i = 0; i < this.getDataSize(); i++) { + if (data[i].isSelected()) { + if (i < coords[0]) { + coords[0] = i; + copy = true; + } + if (i > coords[1]) { + coords[1] = i; + copy = true; + } + } + } + //make a string of the selection + for (int i = coords[0]; i <= coords[1]; i++) { + if (data[i].isSelected()) output = output + data[i].getText(); + else output = output + "x"; // x represents non-selected cell + if (i < coords[1]) output = output + "\t"; + } + //copy to clipboard + if (copy) Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(output), null); + } + + public StringBuffer getTableAsString() { + //make a string of the selection + StringBuffer output = new StringBuffer(""); + for (int i = 0; i < getDataSize(); i++) { + output.append(data[i].getText()); + if (i < getDataSize() - 1) output.append("\t"); + } + return output; + } + + public void copyTable() { + String newline = System.getProperty("line.separator"); + StringBuffer output = new StringBuffer("[Table1D]" + newline); + for (int i = 0; i < getDataSize(); i++) { + output.append(data[i].getText()); + if (i < getDataSize() - 1) output.append("\t"); + } + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(output+""), null); + } + + public String getCellAsString(int index) { + return data[index].getText(); + } + + public void pasteValues(String[] input) { + //set real values + for (int i = 0; i < input.length; i++) { + try { + Double.parseDouble(input[i]); + data[i].setRealValue(input[i]); + } catch (NumberFormatException ex) { /* not a number, do nothing */ } + } + } + + public void paste() { + StringTokenizer st = new StringTokenizer(""); + try { + String input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + if (pasteType.equalsIgnoreCase("[Table1D]")) { // copied entire table + int i = 0; + while (st.hasMoreTokens()) { + String currentToken = st.nextToken(); + try { + if (!data[i].getText().equalsIgnoreCase(currentToken)) data[i].setRealValue(currentToken); + } catch (ArrayIndexOutOfBoundsException ex) { /* table larger than target, ignore*/ } + i++; + } + } else if (pasteType.equalsIgnoreCase("[Selection1D]")) { // copied selection + if (data[highlightY].isSelected()) { + int i = 0; + while (st.hasMoreTokens()) { + try { + data[highlightY + i].setRealValue(st.nextToken()); + } catch (ArrayIndexOutOfBoundsException ex) { /* paste larger than target, ignore */ } + i++; + } + } + } + } + + public void pasteCompare() { + StringTokenizer st = new StringTokenizer(""); + try { + String input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + if (pasteType.equalsIgnoreCase("[Table1D]")) { // copied entire table + int i = 0; + while (st.hasMoreTokens()) { + String currentToken = st.nextToken(); + try { + if (!data[i].getText().equalsIgnoreCase(currentToken)) data[i].setCompareRealValue(currentToken); + } catch (ArrayIndexOutOfBoundsException ex) { /* table larger than target, ignore*/ } + i++; + } + } + } + + public void finalize(Settings settings) { + // apply settings to cells + for (int i = 0; i < getDataSize(); i++) { + this.setMaxColor(settings.getMaxColor()); + this.setMinColor(settings.getMinColor()); + data[i].setHighlightColor(settings.getHighlightColor()); + data[i].setIncreaseBorder(settings.getIncreaseBorder()); + data[i].setDecreaseBorder(settings.getDecreaseBorder()); + data[i].setFont(settings.getTableFont()); + data[i].repaint(); + } + cellHeight = (int)settings.getCellSize().getHeight(); + cellWidth = (int)settings.getCellSize().getWidth(); + colorize(); + validateScaling(); + } + + public void resize() { + frame.setSize(getFrameSize()); + } + + public Color getMaxColor() { + return maxColor; + } + + public void setMaxColor(Color maxColor) { + this.maxColor = maxColor; + } + + public Color getMinColor() { + return minColor; + } + + public void setMinColor(Color minColor) { + this.minColor = minColor; + } + + public abstract void setAxisColor(Color color); + + public void validateScaling() { + JEP parser = new JEP(); + parser.initSymTab(); // clear the contents of the symbol table + parser.addVariable("x", 5); + parser.parseExpression(scale.getExpression()); + double toReal = parser.getValue(); + + parser.addVariable("x", toReal); + parser.parseExpression(scale.getByteExpression()); + + if ((int)Math.round(parser.getValue()) != 5 && container.getContainer().getSettings().isCalcConflictWarning()) { + + JPanel panel = new JPanel(); + panel.setLayout(new GridLayout(3, 1)); + panel.add(new JLabel("The real value and byte value conversion expressions for table " + name + " are invalid.")); + panel.add(new JLabel("To real value: " + scale.getExpression() + "\n" + + "To byte: " + scale.getByteExpression())); + + JCheckBox check = new JCheckBox("Always display this message", true); + check.setHorizontalAlignment(check.RIGHT); + panel.add(check); + + check.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + getRom().getContainer().getSettings().setCalcConflictWarning(((JCheckBox)e.getSource()).isSelected()); + } + } + ); + + new JOptionPane().showMessageDialog(container.getContainer(), panel, + "Warning", JOptionPane.ERROR_MESSAGE); + } + } + + public void compare(int compareType) { + this.compareType = compareType; + + for (int i = 0; i < getDataSize(); i++) { + if (compareType == this.COMPARE_ORIGINAL) data[i].setCompareValue(data[i].getOriginalValue()); + data[i].setCompareType(compareType); + data[i].setCompareDisplay(compareDisplay); + data[i].updateDisplayValue(); + } + colorize(); + } + + public void setCompareDisplay(int compareDisplay) { + this.compareDisplay = compareDisplay; + compare(compareType); + colorize(); + } +} \ No newline at end of file diff --git a/src/enginuity/maps/Table1D.java b/src/enginuity/maps/Table1D.java new file mode 100644 index 00000000..a1bd43a1 --- /dev/null +++ b/src/enginuity/maps/Table1D.java @@ -0,0 +1,131 @@ +package enginuity.maps; + +import enginuity.maps.Table; +import enginuity.maps.Table3D; +import java.awt.BorderLayout; +import java.awt.Color; +import java.io.Serializable; +import javax.swing.JLabel; + +public class Table1D extends Table implements Serializable { + + private Color axisColor = new Color(255, 255, 255); + + public Table1D() { + super(); + } + + public void populateTable(byte[] input) { + centerLayout.setRows(1); + centerLayout.setColumns(this.getDataSize()); + super.populateTable(input); + + // add to table + for (int i = 0; i < this.getDataSize(); i++) { + centerPanel.add(this.getDataCell(i)); + } + this.add(new JLabel(name + " (" + scale.getUnit() + ")", JLabel.CENTER), BorderLayout.NORTH); + } + + public String toString() { + return super.toString() + " (1D)"; + } + + public boolean isIsAxis() { + return isAxis; + } + + public void setIsAxis(boolean isAxis) { + this.isAxis = isAxis; + } + + public void clearSelection() { + super.clearSelection(); + //if (isAxis) axisParent.clearSelection(); + } + + public void clearSelection(boolean calledByParent) { + if (calledByParent) { + super.clearSelection(); + } else { + this.clearSelection(); + } + } + + public void colorize() { + super.colorize(); + } + + public void cursorUp() { + if (type == Table.TABLE_Y_AXIS) { + if (highlightY > 0 && data[highlightY].isSelected()) selectCellAt(highlightY - 1); + } else if (type == Table.TABLE_X_AXIS) { + // Y axis is on top.. nothing happens + } else if (type == Table.TABLE_1D) { + // no where to move up to + } + } + public void cursorDown() { + if (type == Table.TABLE_Y_AXIS) { + if (axisParent.getType() == Table.TABLE_3D) { + if (highlightY < getDataSize() - 1 && data[highlightY].isSelected()) selectCellAt(highlightY + 1); + } else if (axisParent.getType() == Table.TABLE_2D) { + if (data[highlightY].isSelected()) axisParent.selectCellAt(highlightY); + } + } else if (type == Table.TABLE_X_AXIS && data[highlightY].isSelected()) { + ((Table3D)axisParent).selectCellAt(highlightY, this); + } else if (type == Table.TABLE_1D) { + // no where to move down to + } + } + + public void cursorLeft() { + if (type == Table.TABLE_Y_AXIS) { + // X axis is on left.. nothing happens + if (axisParent.getType() == Table.TABLE_2D) { + if (data[highlightY].isSelected()) selectCellAt(highlightY - 1); + } + } else if (type == Table.TABLE_X_AXIS && data[highlightY].isSelected()) { + if (highlightY > 0) selectCellAt(highlightY - 1); + } else if (type == Table.TABLE_1D && data[highlightY].isSelected()) { + if (highlightY > 0) selectCellAt(highlightY - 1); + } + } + + public void cursorRight() { + if (type == Table.TABLE_Y_AXIS && data[highlightY].isSelected()) { + if (axisParent.getType() == Table.TABLE_3D) ((Table3D)axisParent).selectCellAt(highlightY, this); + else if (axisParent.getType() == Table.TABLE_2D) selectCellAt(highlightY + 1); + } else if (type == Table.TABLE_X_AXIS && data[highlightY].isSelected()) { + if (highlightY < getDataSize() - 1) selectCellAt(highlightY + 1); + } else if (type == Table.TABLE_1D && data[highlightY].isSelected()) { + if (highlightY < getDataSize() - 1) selectCellAt(highlightY + 1); + } + } + + public void startHighlight(int x, int y) { + if (isAxis) axisParent.clearSelection(); + super.startHighlight(x, y); + } + + public StringBuffer getTableAsString() { + StringBuffer output = new StringBuffer(""); + for (int i = 0; i < getDataSize(); i++) { + output.append(data[i].getText()); + if (i < getDataSize() - 1) output.append("\t"); + } + return output; + } + + public String getCellAsString(int index) { + return data[index].getText(); + } + + public Color getAxisColor() { + return axisColor; + } + + public void setAxisColor(Color axisColor) { + this.axisColor = axisColor; + } +} \ No newline at end of file diff --git a/src/enginuity/maps/Table2D.java b/src/enginuity/maps/Table2D.java new file mode 100644 index 00000000..f0e3be88 --- /dev/null +++ b/src/enginuity/maps/Table2D.java @@ -0,0 +1,244 @@ +package enginuity.maps; + +import enginuity.maps.Table; +import enginuity.maps.Table1D; +import enginuity.Settings; +import enginuity.swing.TableFrame; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.KeyListener; +import java.io.IOException; +import java.io.Serializable; +import java.util.StringTokenizer; +import javax.swing.JLabel; + +public class Table2D extends Table implements Serializable { + + private Table1D axis = new Table1D(); + + public Table2D() { + super(); + verticalOverhead += 18; + } + + public Table1D getAxis() { + return axis; + } + + public void setAxis(Table1D axis) { + this.axis = axis; + } + + public String toString() { + return super.toString() + " (2D)";// + axis; + } + + public void colorize() { + super.colorize(); + axis.colorize(); + } + + public void setFrame(TableFrame frame) { + this.frame = frame; + axis.setFrame(frame); + frame.setSize(getFrameSize()); + } + + public Dimension getFrameSize() { + int height = verticalOverhead + cellHeight * 2; + int width = horizontalOverhead + data.length * cellWidth; + if (height < minHeight) height = minHeight; + if (width < minWidth) width = minWidth; + return new Dimension(width, height); + } + + public void finalize(Settings settings) { + this.setAxisColor(settings.getAxisColor()); + axis.finalize(settings); + super.finalize(settings); + } + + public void populateTable(byte[] input) throws ArrayIndexOutOfBoundsException { + centerLayout.setRows(2); + centerLayout.setColumns(this.getDataSize()); + + try { + axis.setRom(container); + axis.populateTable(input); + super.populateTable(input); + } catch (ArrayIndexOutOfBoundsException ex) { + throw new ArrayIndexOutOfBoundsException(); + } + + // add to table + for (int i = 0; i < this.getDataSize(); i++) { + centerPanel.add(axis.getDataCell(i)); + } + for (int i = 0; i < this.getDataSize(); i++) { + centerPanel.add(this.getDataCell(i)); + } + this.add(new JLabel(axis.getName() + " (" + axis.getScale().getUnit() + ")", JLabel.CENTER), BorderLayout.NORTH); + this.add(new JLabel(name + " (" + scale.getUnit() + ")", JLabel.CENTER), BorderLayout.SOUTH); + //this.colorize(); + } + + public void increment(int increment) { + super.increment(increment); + axis.increment(increment); + } + + public void clearSelection() { + axis.clearSelection(true); + for (int i = 0; i < data.length; i++) { + data[i].setSelected(false); + } + } + + public void setRevertPoint() { + super.setRevertPoint(); + axis.setRevertPoint(); + } + + public void undoAll() { + super.undoAll(); + axis.undoAll(); + } + + public void undoSelected() { + super.undoSelected(); + axis.undoSelected(); + } + + public byte[] saveFile(byte[] binData) { + binData = super.saveFile(binData); + binData = axis.saveFile(binData); + return binData; + } + + public void setRealValue(String realValue) { + axis.setRealValue(realValue); + super.setRealValue(realValue); + } + + public void addKeyListener(KeyListener listener) { + super.addKeyListener(listener); + axis.addKeyListener(listener); + } + + public void selectCellAt(int y, Table1D axisType) { + selectCellAt(y); + } + + public void cursorUp() { + if (!axis.isStatic() && data[highlightY].isSelected()) axis.selectCellAt(highlightY); + } + public void cursorDown() { + axis.cursorDown(); + } + + public void cursorLeft() { + if (highlightY > 0 && data[highlightY].isSelected()) selectCellAt(highlightY - 1); + else axis.cursorLeft(); + } + + public void cursorRight() { + if (highlightY < data.length - 1 && data[highlightY].isSelected()) selectCellAt(highlightY + 1); + else axis.cursorRight(); + } + + public void startHighlight(int x, int y) { + axis.clearSelection(); + super.startHighlight(x, y); + } + + public void copySelection() { + super.copySelection(); + axis.copySelection(); + } + + public void copyTable() { + // create string + String newline = System.getProperty("line.separator"); + StringBuffer output = new StringBuffer("[Table2D]" + newline); + output.append(axis.getTableAsString() + newline); + output.append(super.getTableAsString()); + //copy to clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(output+""), null); + } + + public void paste() { + StringTokenizer st = new StringTokenizer(""); + String input = ""; + try { + input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + if (pasteType.equalsIgnoreCase("[Table2D]")) { // Paste table + String newline = System.getProperty("line.separator"); + String axisValues = "[Table1D]" + newline + st.nextToken(newline); + String dataValues = "[Table1D]" + newline + st.nextToken(newline); + + // put axis in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(axisValues+""), null); + axis.paste(); + // put datavalues in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(dataValues+""), null); + super.paste(); + // reset clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(input+""), null); + + } else if (pasteType.equalsIgnoreCase("[Selection1D]")) { // paste selection + if (data[highlightY].isSelected()) { + super.paste(); + } else { + axis.paste(); + } + } + } + + public void pasteCompare() { + StringTokenizer st = new StringTokenizer(""); + String input = ""; + try { + input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + if (pasteType.equalsIgnoreCase("[Table2D]")) { // Paste table + String newline = System.getProperty("line.separator"); + String axisValues = "[Table1D]" + newline + st.nextToken(newline); + String dataValues = "[Table1D]" + newline + st.nextToken(newline); + + // put axis in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(axisValues+""), null); + axis.pasteCompare(); + // put datavalues in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(dataValues+""), null); + super.pasteCompare(); + // reset clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(input+""), null); + + } + } + + public void setAxisColor(Color axisColor) { + axis.setAxisColor(axisColor); + } + + public void validateScaling() { + super.validateScaling(); + axis.validateScaling(); + } +} \ No newline at end of file diff --git a/src/enginuity/maps/Table3D.java b/src/enginuity/maps/Table3D.java new file mode 100644 index 00000000..40f666b7 --- /dev/null +++ b/src/enginuity/maps/Table3D.java @@ -0,0 +1,731 @@ +package enginuity.maps; + +import enginuity.Settings; +import enginuity.xml.RomAttributeParser; +import enginuity.swing.TableFrame; +import enginuity.swing.VTextIcon; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.KeyListener; +import java.io.IOException; +import java.io.Serializable; +import java.util.StringTokenizer; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.LineBorder; + +public class Table3D extends Table implements Serializable { + + private Table1D xAxis = new Table1D(); + private Table1D yAxis = new Table1D(); + private DataCell[][] data = new DataCell[1][1]; + private boolean swapXY = false; + private boolean flipX = false; + private boolean flipY = false; + + public Table3D() { + super(); + verticalOverhead += 39; + horizontalOverhead += 5; + } + + public Table1D getXAxis() { + return xAxis; + } + + public void setXAxis(Table1D xAxis) { + this.xAxis = xAxis; + } + + public Table1D getYAxis() { + return yAxis; + } + + public void setYAxis(Table1D yAxis) { + this.yAxis = yAxis; + } + + public boolean isSwapXY() { + return swapXY; + } + + public void setSwapXY(boolean swapXY) { + this.swapXY = swapXY; + } + + public boolean getFlipX() { + return flipX; + } + + public void setFlipX(boolean flipX) { + this.flipX = flipX; + } + + public boolean getFlipY() { + return flipY; + } + + public void setFlipY(boolean flipY) { + this.flipY = flipY; + } + + public void setSizeX(int size) { + data = new DataCell[size][data[0].length]; + centerLayout.setColumns(size + 1); + } + + public int getSizeX() { + return data.length; + } + + public void setSizeY(int size) { + data = new DataCell[data.length][size]; + centerLayout.setRows(size + 1); + } + + public int getSizeY() { + return data[0].length; + } + + public void populateTable(byte[] input) throws NullPointerException, ArrayIndexOutOfBoundsException { + // fill first empty cell + centerPanel.add(new JLabel()); + if (!beforeRam) ramOffset = container.getRomID().getRamOffset(); + + // populate axiis + try { + xAxis.setRom(container); + xAxis.populateTable(input); + yAxis.setRom(container); + yAxis.populateTable(input); + } catch (ArrayIndexOutOfBoundsException ex) { + throw new ArrayIndexOutOfBoundsException(); + } + + for (int i = 0; i < xAxis.getDataSize(); i++) { + centerPanel.add(xAxis.getDataCell(i)); + } + + int offset = 0; + + for (int x = 0; x < yAxis.getDataSize(); x++) { + centerPanel.add(yAxis.getDataCell(x)); + for (int y = 0; y < xAxis.getDataSize(); y++) { + data[y][x] = new DataCell(scale); + data[y][x].setTable(this); + try { + data[y][x].setBinValue( + RomAttributeParser.parseByteValue(input, + endian, + storageAddress + offset * storageType - ramOffset, + storageType)); + } catch (ArrayIndexOutOfBoundsException ex) { + throw new ArrayIndexOutOfBoundsException(); + } + + centerPanel.add(data[y][x]); + data[y][x].setXCoord(y); + data[y][x].setYCoord(x); + data[y][x].setOriginalValue(data[y][x].getBinValue()); + offset++; + } + } + //this.colorize(); + + GridLayout topLayout = new GridLayout(2,1); + JPanel topPanel = new JPanel(topLayout); + this.add(topPanel, BorderLayout.NORTH); + topPanel.add(new JLabel(name + " (" + scale.getUnit() + ")", JLabel.CENTER), BorderLayout.NORTH); + topPanel.add(new JLabel(xAxis.getName() + " (" + xAxis.getScale().getUnit() + ")", JLabel.CENTER), BorderLayout.NORTH); + JLabel yLabel = new JLabel(); + yLabel.setFont(new Font("Arial", Font.BOLD, 12)); + VTextIcon icon = new VTextIcon(yLabel, yAxis.getName() + " (" + yAxis.getScale().getUnit()+ ")", VTextIcon.ROTATE_LEFT); + yLabel.setIcon(icon); + this.add(yLabel, BorderLayout.WEST); + } + + public void colorize() { + if (compareType == COMPARE_OFF) { + if (!isStatic && !isAxis) { + int high = 0; + int low = 999999999; + for (int x = 0; x < data.length; x++) { + for (int y = 0; y < data[0].length; y++) { + if (data[x][y].getBinValue() > high) { + high = data[x][y].getBinValue(); + } + if (data[x][y].getBinValue() < low) { + low = data[x][y].getBinValue(); + } + } + } + for (int x = 0; x < data.length; x++) { + for (int y = 0; y < data[0].length; y++) { + double scale = Math.abs((double)(data[x][y].getBinValue() - low) / (high - low)); + + int r = (int)((maxColor.getRed() - minColor.getRed()) * scale) + minColor.getRed(); + int g = (int)((maxColor.getGreen() - minColor.getGreen()) * scale) + minColor.getGreen(); + int b = (int)((maxColor.getBlue() - minColor.getBlue()) * scale) + minColor.getBlue(); + data[x][y].setColor(new Color(r, g, b)); + } + } + } + } else { // comparing is on + if (!isStatic) { + int high = 0; + int low = 99999999; + + // determine ratios + for (int x = 0; x < data.length; x++) { + for (int y = 0; y < data[0].length; y++) { + if (Math.abs(data[x][y].getBinValue() - data[x][y].getOriginalValue()) > high) { + high = Math.abs(data[x][y].getBinValue() - data[x][y].getOriginalValue()); + } else if (Math.abs(data[x][y].getBinValue() - data[x][y].getOriginalValue()) < low) { + low = Math.abs(data[x][y].getBinValue() - data[x][y].getOriginalValue()); + } + } + } + + // colorize + for (int x = 0; x < data.length; x++) { + for (int y = 0; y < data[0].length; y++) { + + int cellDifference = Math.abs(data[x][y].getBinValue() - data[x][y].getOriginalValue()); + + double scale; + if (high == 0) scale = 0; + else scale = (double)cellDifference / ((double)high - (double)low); + + int r = (int)((maxColor.getRed() - minColor.getRed()) * scale) + minColor.getRed(); + int g = (int)((maxColor.getGreen() - minColor.getGreen()) * scale) + minColor.getGreen(); + int b = (int)((maxColor.getBlue() - minColor.getBlue()) * scale) + minColor.getBlue(); + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + if (scale != 0) data[x][y].setColor(new Color(r, g, b)); + else data[x][y].setColor(new Color(160,160,160)); + + // set border + if (data[x][y].getBinValue() > data[x][y].getOriginalValue()) { + data[x][y].setBorder(new LineBorder(getRom().getContainer().getSettings().getIncreaseBorder())); + } else if (data[x][y].getBinValue() < data[x][y].getOriginalValue()) { + data[x][y].setBorder(new LineBorder(getRom().getContainer().getSettings().getDecreaseBorder())); + } else { + data[x][y].setBorder(new LineBorder(Color.BLACK, 1)); + } + + } + } + } + xAxis.colorize(); + yAxis.colorize(); + } + + // colorize borders + if (!isStatic) { + for (int x = 0; x < data.length; x++) { + for (int y = 0; y < data[0].length; y++) { + + if (data[x][y].getBinValue() > data[x][y].getOriginalValue()) { + data[x][y].setBorder(new LineBorder(getRom().getContainer().getSettings().getIncreaseBorder())); + } else if (data[x][y].getBinValue() < data[x][y].getOriginalValue()) { + data[x][y].setBorder(new LineBorder(getRom().getContainer().getSettings().getDecreaseBorder())); + } else { + data[x][y].setBorder(new LineBorder(Color.BLACK, 1)); + } + } + } + } + } + + public void compare(int compareType) { + this.compareType = compareType; + + for (int x = 0; x < data.length; x++) { + for (int y = 0; y < data[0].length; y++) { + if (compareType == this.COMPARE_ORIGINAL) data[x][y].setCompareValue(data[x][y].getOriginalValue()); + data[x][y].setCompareType(compareType); + data[x][y].setCompareDisplay(compareDisplay); + data[x][y].updateDisplayValue(); + } + } + colorize(); + } + + public void setFrame(TableFrame frame) { + this.frame = frame; + xAxis.setFrame(frame); + yAxis.setFrame(frame); + frame.setSize(getFrameSize()); + } + + public Dimension getFrameSize() { + int height = verticalOverhead + cellHeight * data[0].length; + int width = horizontalOverhead + data.length * cellWidth; + if (height < minHeight) height = minHeight; + if (width < minWidth) width = minWidth; + return new Dimension(width, height); + } + + public String toString() { + return super.toString() + " (3D)";/* + + "\n Flip X: " + flipX + + "\n Size X: " + data.length + + "\n Flip Y: " + flipY + + "\n Size Y: " + data[0].length + + "\n Swap X/Y: " + swapXY + + xAxis + + yAxis;*/ + } + + public void increment(int increment) { + if (!isStatic) { + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + if (data[x][y].isSelected()) data[x][y].increment(increment); + } + } + } + xAxis.increment(increment); + yAxis.increment(increment); + } + + public void clearSelection() { + xAxis.clearSelection(true); + yAxis.clearSelection(true); + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + data[x][y].setSelected(false); + } + } + } + + public void highlight(int xCoord, int yCoord) { + if (highlight) { + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + if (((y >= highlightY && y <= yCoord) || + (y <= highlightY && y >= yCoord)) && + ((x >= highlightX && x <= xCoord) || + (x <= highlightX && x >= xCoord)) ) { + data[x][y].setHighlighted(true); + } else { + data[x][y].setHighlighted(false); + } + } + } + } + } + + public void stopHighlight() { + highlight = false; + // loop through, selected and un-highlight + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + if (data[x][y].isHighlighted()) { + data[x][y].setSelected(true); + data[x][y].setHighlighted(false); + } + } + } + } + + public void setRevertPoint() { + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + data[x][y].setOriginalValue(data[x][y].getBinValue()); + } + } + yAxis.setRevertPoint(); + xAxis.setRevertPoint(); + colorize(); + } + + public void undoAll() { + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + data[x][y].setBinValue(data[x][y].getOriginalValue()); + } + } + yAxis.undoAll(); + xAxis.undoAll(); + colorize(); + } + + public void undoSelected() { + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + if (data[x][y].isSelected()) data[x][y].setBinValue(data[x][y].getOriginalValue()); + } + } + yAxis.undoSelected(); + xAxis.undoSelected(); + colorize(); + } + + + public byte[] saveFile(byte[] binData) { + binData = xAxis.saveFile(binData); + binData = yAxis.saveFile(binData); + int offset = 0; + + for (int x = 0; x < yAxis.getDataSize(); x++) { + for (int y = 0; y < xAxis.getDataSize(); y++) { + byte[] output = RomAttributeParser.parseIntegerValue(data[y][x].getBinValue(), endian, storageType); + for (int z = 0; z < storageType; z++) { + binData[offset * storageType + z + storageAddress - ramOffset] = output[z]; + } + offset++; + } + } + return binData; + } + + public void setRealValue(String realValue) { + if (!isStatic) { + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + if (data[x][y].isSelected()) data[x][y].setRealValue(realValue); + } + } + } + xAxis.setRealValue(realValue); + yAxis.setRealValue(realValue); + colorize(); + } + + public void addKeyListener(KeyListener listener) { + xAxis.addKeyListener(listener); + yAxis.addKeyListener(listener); + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + data[x][y].addKeyListener(listener); + } + } + } + + public void selectCellAt(int y, Table1D axisType) { + if (axisType.getType() == TABLE_Y_AXIS) { + selectCellAt(0, y); + } else { // y axis + selectCellAt(y, 0); + } + } + + public void selectCellAt(int x, int y) { + clearSelection(); + data[x][y].setSelected(true); + highlightX = x; + highlightY = y; + } + + public void cursorUp() { + if (highlightY > 0 && data[highlightX][highlightY].isSelected()) selectCellAt(highlightX, highlightY - 1); + else if (!xAxis.isStatic() && data[highlightX][highlightY].isSelected()) xAxis.selectCellAt(highlightX); + else { + xAxis.cursorUp(); + yAxis.cursorUp(); + } + } + + public void cursorDown() { + if (highlightY < getSizeY() - 1 && data[highlightX][highlightY].isSelected()) selectCellAt(highlightX, highlightY + 1); + else { + xAxis.cursorDown(); + yAxis.cursorDown(); + } + } + + public void cursorLeft() { + if (highlightX > 0 && data[highlightX][highlightY].isSelected()) selectCellAt(highlightX - 1, highlightY); + else if (!yAxis.isStatic() && data[highlightX][highlightY].isSelected()) yAxis.selectCellAt(highlightY); + else { + xAxis.cursorLeft(); + yAxis.cursorLeft(); + } + } + + public void cursorRight() { + if (highlightX < getSizeX() - 1 && data[highlightX][highlightY].isSelected()) selectCellAt(highlightX + 1, highlightY); + else { + xAxis.cursorRight(); + yAxis.cursorRight(); + } + } + + public void startHighlight(int x, int y) { + xAxis.clearSelection(); + yAxis.clearSelection(); + super.startHighlight(x, y); + } + + public void copySelection() { + // find bounds of selection + // coords[0] = x min, y min, x max, y max + boolean copy = false; + int[] coords = new int[4]; + coords[0] = this.getSizeX(); + coords[1] = this.getSizeY(); + + for (int x = 0; x < this.getSizeX(); x++) { + for (int y = 0; y < this.getSizeY(); y++) { + if (data[x][y].isSelected()) { + if (x < coords[0]) { + coords[0] = x; + copy = true; + } + if (x > coords[2]) { + coords[2] = x; + copy = true; + } + if (y < coords[1]) { + coords[1] = y; + copy = true; + } + if (y > coords[3]) { + coords[3] = y; + copy = true; + } + } + } + } + // make string of selection + if (copy) { + String newline = System.getProperty("line.separator"); + StringBuffer output = new StringBuffer("[Selection3D]" + newline); + for (int y = coords[1]; y <= coords[3]; y++) { + for (int x = coords[0]; x <= coords[2]; x++) { + if (data[x][y].isSelected()) output.append(data[x][y].getText()); + else output.append("x"); // x represents non-selected cell + if (x < coords[2]) output.append("\t"); + } + if (y < coords[3]) output.append(newline); + //copy to clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(output+""), null); + } + } else { + xAxis.copySelection(); + yAxis.copySelection(); + } + } + + public void copyTable() { + // create string + String newline = System.getProperty("line.separator"); + StringBuffer output = new StringBuffer("[Table3D]" + newline); + output.append(xAxis.getTableAsString() + newline); + + for (int y = 0; y < getSizeY(); y++) { + output.append(yAxis.getCellAsString(y) + "\t"); + for (int x = 0; x < getSizeX(); x++) { + output.append(data[x][y].getText()); + if (x < getSizeX() - 1) output.append("\t"); + } + if (y < getSizeY() - 1) output.append(newline); + } + //copy to clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(output+""), null); + } + + public void paste() { + StringTokenizer st = new StringTokenizer(""); + String input = ""; + try { + input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + if (pasteType.equalsIgnoreCase("[Table3D]")) { // Paste table + String newline = System.getProperty("line.separator"); + String xAxisValues = "[Table1D]" + newline + st.nextToken(newline); + + // build y axis and data values + StringBuffer yAxisValues = new StringBuffer("[Table1D]" + newline + st.nextToken("\t")); + StringBuffer dataValues = new StringBuffer("[Table3D]" + newline + st.nextToken("\t") + st.nextToken(newline)); + while (st.hasMoreTokens()) { + yAxisValues.append("\t" + st.nextToken("\t")); + dataValues.append(newline + st.nextToken("\t") + st.nextToken(newline)); + } + + // put x axis in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(xAxisValues+""), null); + xAxis.paste(); + // put y axis in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(yAxisValues+""), null); + yAxis.paste(); + // put datavalues in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(dataValues+""), null); + pasteValues(); + // reset clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(input+""), null); + + } else if (pasteType.equalsIgnoreCase("[Selection3D]")) { // paste selection + pasteValues(); + } else if (pasteType.equalsIgnoreCase("[Selection1D]")) { // paste selection + xAxis.paste(); + yAxis.paste(); + } + } + + public void pasteCompare() { + StringTokenizer st = new StringTokenizer(""); + String input = ""; + try { + input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + if (pasteType.equalsIgnoreCase("[Table3D]")) { // Paste table + String newline = System.getProperty("line.separator"); + String xAxisValues = "[Table1D]" + newline + st.nextToken(newline); + + // build y axis and data values + StringBuffer yAxisValues = new StringBuffer("[Table1D]" + newline + st.nextToken("\t")); + StringBuffer dataValues = new StringBuffer("[Table3D]" + newline + st.nextToken("\t") + st.nextToken(newline)); + while (st.hasMoreTokens()) { + yAxisValues.append("\t" + st.nextToken("\t")); + dataValues.append(newline + st.nextToken("\t") + st.nextToken(newline)); + } + + // put x axis in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(xAxisValues+""), null); + xAxis.pasteCompare(); + // put y axis in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(yAxisValues+""), null); + yAxis.pasteCompare(); + // put datavalues in clipboard and paste + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(dataValues+""), null); + pasteCompareValues(); + // reset clipboard + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(input+""), null); + } + colorize(); + } + + public void pasteValues() { + StringTokenizer st = new StringTokenizer(""); + try { + String input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + // figure paste start cell + int startX = 0; + int startY = 0; + // if pasting a table, startX and Y at 0, else highlight is start + if (pasteType.equalsIgnoreCase("[Selection3D]")) { + startX = highlightX; + startY = highlightY; + } + + // set values + String newline = System.getProperty("line.separator"); + for (int y = startY; y < getSizeY(); y++) { + if (st.hasMoreTokens()) { + StringTokenizer currentLine = new StringTokenizer(st.nextToken(newline)); + for (int x = startX; x < getSizeX(); x++) { + if (currentLine.hasMoreTokens()) { + String currentToken = currentLine.nextToken(); + boolean tableLarger = false; + try { + if (!data[x][y].getText().equalsIgnoreCase(currentToken)) { + data[x][y].setRealValue(currentToken); + } + } catch (ArrayIndexOutOfBoundsException ex) { /* copied table is larger than current table*/ } + } + } + } + } + } + + public void pasteCompareValues() { + StringTokenizer st = new StringTokenizer(""); + try { + String input = (String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor); + st = new StringTokenizer(input); + System.out.println(input); + } catch (UnsupportedFlavorException ex) { /* wrong paste type -- do nothing */ + } catch (IOException ex) { } + + String pasteType = st.nextToken(); + + // figure paste start cell + int startX = 0; + int startY = 0; + + + // set values + String newline = System.getProperty("line.separator"); + for (int y = startY; y < getSizeY(); y++) { + if (st.hasMoreTokens()) { + StringTokenizer currentLine = new StringTokenizer(st.nextToken(newline)); + for (int x = startX; x < getSizeX(); x++) { + if (currentLine.hasMoreTokens()) { + String currentToken = currentLine.nextToken(); + boolean tableLarger = false; + try { + if (!data[x][y].getText().equalsIgnoreCase(currentToken)) { + data[x][y].setCompareRealValue(currentToken); + System.out.println(data[x][y].getCompareValue()); + } + } catch (ArrayIndexOutOfBoundsException ex) { /* copied table is larger than current table*/ } + } + } + } + } + } + + public void finalize(Settings settings) { + // apply settings to cells + for (int y = 0; y < getSizeY(); y++) { + for (int x = 0; x < getSizeX(); x++) { + + this.setMaxColor(settings.getMaxColor()); + this.setMinColor(settings.getMinColor()); + data[x][y].setHighlightColor(settings.getHighlightColor()); + data[x][y].setIncreaseBorder(settings.getIncreaseBorder()); + data[x][y].setDecreaseBorder(settings.getDecreaseBorder()); + data[x][y].setFont(settings.getTableFont()); + data[x][y].repaint(); + } + } + this.setAxisColor(settings.getAxisColor()); + xAxis.finalize(settings); + yAxis.finalize(settings); + cellHeight = (int)settings.getCellSize().getHeight(); + cellWidth = (int)settings.getCellSize().getWidth(); + resize(); + colorize(); + } + + public void setAxisColor(Color axisColor) { + xAxis.setAxisColor(axisColor); + yAxis.setAxisColor(axisColor); + } + + public void validateScaling() { + super.validateScaling(); + xAxis.validateScaling(); + yAxis.validateScaling(); + } +} \ No newline at end of file diff --git a/src/enginuity/net/BrowserControl.java b/src/enginuity/net/BrowserControl.java new file mode 100644 index 00000000..06a2876d --- /dev/null +++ b/src/enginuity/net/BrowserControl.java @@ -0,0 +1,53 @@ +package enginuity.net; +import java.io.IOException; + +public class BrowserControl { + + public static void displayURL(String url) { + boolean windows = isWindowsPlatform(); + String cmd = null; + try { + if (windows) { + // cmd = 'rundll32 url.dll,FileProtocolHandler http://...' + cmd = WIN_PATH + " " + WIN_FLAG + " " + url; + Process p = Runtime.getRuntime().exec(cmd); + } + else { + cmd = UNIX_PATH + " " + UNIX_FLAG + "(" + url + ")"; + Process p = Runtime.getRuntime().exec(cmd); + try { + int exitCode = p.waitFor(); + if (exitCode != 0) + { + cmd = UNIX_PATH + " " + url; + p = Runtime.getRuntime().exec(cmd); + } + } + catch(InterruptedException x) { + System.err.println("Error bringing up browser, cmd='" + + cmd + "'"); + System.err.println("Caught: " + x); + } + } + } + catch(IOException x) { + // couldn't exec browser + System.err.println("Could not invoke browser, command=" + cmd); + System.err.println("Caught: " + x); + } + } + + public static boolean isWindowsPlatform() { + String os = System.getProperty("os.name"); + if ( os != null && os.startsWith(WIN_ID)) + return true; + else + return false; + } + + private static final String WIN_ID = "Windows"; + private static final String WIN_PATH = "rundll32"; + private static final String WIN_FLAG = "url.dll,FileProtocolHandler"; + private static final String UNIX_PATH = "netscape"; + private static final String UNIX_FLAG = "-remote openURL"; +} \ No newline at end of file diff --git a/src/enginuity/net/URL.java b/src/enginuity/net/URL.java new file mode 100644 index 00000000..7015edb1 --- /dev/null +++ b/src/enginuity/net/URL.java @@ -0,0 +1,41 @@ +package enginuity.net; + +import enginuity.net.BrowserControl; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.JLabel; + +public class URL extends JLabel implements MouseListener { + + String url = ""; + + public URL(String url) { + super(url); + this.url = url; + this.setFont(new Font("Arial", Font.PLAIN, 12)); + this.addMouseListener(this); + } + + public void paint (Graphics g) { + super.paint(g); + Font f = getFont(); + FontMetrics fm = getFontMetrics(f); + int x1 = 0; + int y1 = fm.getHeight() + 3; + int x2 = fm.stringWidth(getText()); + if (getText().length() > 0) + g.drawLine(x1, y1, x2, y1); + } + + public void mouseClicked(MouseEvent e) { + BrowserControl.displayURL(url); + } + + public void mousePressed(MouseEvent e) { } + public void mouseReleased(MouseEvent e) { } + public void mouseEntered(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } +} \ No newline at end of file diff --git a/src/enginuity/swing/CategoryTreeNode.java b/src/enginuity/swing/CategoryTreeNode.java new file mode 100644 index 00000000..950f0777 --- /dev/null +++ b/src/enginuity/swing/CategoryTreeNode.java @@ -0,0 +1,22 @@ +package enginuity.swing; + +import enginuity.maps.Rom; +import javax.swing.tree.DefaultMutableTreeNode; + +public class CategoryTreeNode extends DefaultMutableTreeNode { + + private Rom rom; + + public CategoryTreeNode(String name, Rom rom) { + super(name); + this.setRom(rom); + } + + public Rom getRom() { + return rom; + } + + public void setRom(Rom rom) { + this.rom = rom; + } +} \ No newline at end of file diff --git a/src/enginuity/swing/DebugPanel.java b/src/enginuity/swing/DebugPanel.java new file mode 100644 index 00000000..bec5cb47 --- /dev/null +++ b/src/enginuity/swing/DebugPanel.java @@ -0,0 +1,31 @@ +package enginuity.swing; + +import enginuity.net.URL; +import java.awt.BorderLayout; +import java.awt.GridLayout; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; + +public class DebugPanel extends JPanel { + + public DebugPanel(Exception ex, String url) { + setLayout(new BorderLayout()); + + JPanel top = new JPanel(new GridLayout(7, 1)); + top.add(new JLabel("Enginuity has encountered an exception. Please review the details below.")); + top.add(new JLabel("If you are unable to fix this problem please visit the following website")); + top.add(new JLabel("and provide these details and the steps that lead to this error.")); + top.add(new JLabel()); + top.add(new URL(url)); + top.add(new JLabel()); + top.add(new JLabel("Details:")); + add(top, BorderLayout.NORTH); + + JTextArea output = new JTextArea(ex.getMessage()); + add(output, BorderLayout.CENTER); + output.setAutoscrolls(true); + output.setRows(10); + output.setColumns(40); + } +} \ No newline at end of file diff --git a/src/enginuity/swing/ECUEditorMenuBar.java b/src/enginuity/swing/ECUEditorMenuBar.java new file mode 100644 index 00000000..b7a73652 --- /dev/null +++ b/src/enginuity/swing/ECUEditorMenuBar.java @@ -0,0 +1,239 @@ +package enginuity.swing; + +import enginuity.xml.RomNotFoundException; +import enginuity.maps.Rom; +import enginuity.xml.DOMRomUnmarshaller; +import com.sun.org.apache.xerces.internal.parsers.DOMParser; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import javax.management.modelmbean.XMLParseException; +import javax.swing.JFileChooser; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JSeparator; +import enginuity.ECUEditor; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +public class ECUEditorMenuBar extends JMenuBar implements ActionListener { + + private JMenu fileMenu = new JMenu("File"); + private JMenuItem openImage = new JMenuItem("Open Image"); + private JMenuItem saveImage = new JMenuItem("Save Image"); + private JMenuItem refreshImage = new JMenuItem("Refresh Image"); + private JMenuItem closeImage = new JMenuItem("Close Image"); + private JMenuItem closeAll = new JMenuItem("Close All Images"); + private JMenuItem exit = new JMenuItem("Exit"); + private JMenu editMenu = new JMenu("Edit"); + private JMenuItem settings = new JMenuItem("Settings"); + private JMenu viewMenu = new JMenu("View"); + private JMenuItem romProperties = new JMenuItem("ECU Image Properties"); + private ECUEditor parent; + + public ECUEditorMenuBar(ECUEditor parent) { + this.parent = parent; + + add(fileMenu); + fileMenu.setMnemonic('F'); + openImage.setMnemonic('O'); + saveImage.setMnemonic('S'); + refreshImage.setMnemonic('R'); + closeImage.setMnemonic('C'); + closeAll.setMnemonic('A'); + exit.setMnemonic('X'); + + fileMenu.add(openImage); + fileMenu.add(saveImage); + fileMenu.add(refreshImage); + fileMenu.add(new JSeparator()); + fileMenu.add(closeImage); + fileMenu.add(closeAll); + fileMenu.add(new JSeparator()); + fileMenu.add(exit); + + openImage.addActionListener(this); + saveImage.addActionListener(this); + refreshImage.addActionListener(this); + closeImage.addActionListener(this); + closeAll.addActionListener(this); + exit.addActionListener(this); + + add(editMenu); + editMenu.setMnemonic('E'); + settings.setMnemonic('S'); + editMenu.add(new JSeparator()); + editMenu.add(settings); + settings.addActionListener(this); + + + add(viewMenu); + viewMenu.setMnemonic('V'); + romProperties.setMnemonic('P'); + viewMenu.add(romProperties); + romProperties.addActionListener(this); + + this.updateMenu(); + } + + public void updateMenu() { + String file = ""; + try { + file = " " + parent.getLastSelectedRom().getFileName() + " "; + } catch (NullPointerException ex) { } + if (file.equals("")) { + saveImage.setEnabled(false); + closeImage.setEnabled(false); + closeAll.setEnabled(false); + romProperties.setEnabled(false); + } else { + saveImage.setEnabled(true); + closeImage.setEnabled(true); + closeAll.setEnabled(true); + romProperties.setEnabled(true); + } + + saveImage.setText("Save" + file); + refreshImage.setText("Refresh" + file); + closeImage.setText("Close" + file); + romProperties.setText(file + "Properties"); + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == openImage) { + try { + this.openImageDialog(); + } catch (Exception ex) { + new JOptionPane().showMessageDialog(parent, new DebugPanel(ex, + parent.getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE); + } + + } else if (e.getSource() == saveImage) { + try { + this.saveImage(parent.getLastSelectedRom()); + } catch (Exception ex) { + new JOptionPane().showMessageDialog(parent, new DebugPanel(ex, + parent.getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE); + } + + } else if (e.getSource() == closeImage) { + this.closeImage(); + + } else if (e.getSource() == closeAll) { + this.closeAllImages(); + + } else if (e.getSource() == exit) { + System.exit(0); + + } else if (e.getSource() == romProperties) { + new JOptionPane().showMessageDialog(parent, (Object)(new RomPropertyPanel(parent.getLastSelectedRom())), + parent.getLastSelectedRom().getRomIDString() + " Properties", JOptionPane.INFORMATION_MESSAGE); + + } else if (e.getSource() == refreshImage) { + try { + refreshImage(); + throw new Exception(); + } catch (Exception ex) { + new JOptionPane().showMessageDialog(parent, new DebugPanel(ex, + parent.getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE); + } + + } else if (e.getSource() == settings) { + SettingsForm form = new SettingsForm(parent); + form.setLocationRelativeTo(parent); + form.setVisible(true); + } + } + + public void refreshImage() throws Exception { + File file = parent.getLastSelectedRom().getFullFileName(); + parent.closeImage(); + openImage(file); + } + + public void closeImage() { + parent.closeImage(); + } + + public void closeAllImages() { + parent.closeAllImages(); + } + + public void saveImage(Rom input) throws XMLParseException, Exception { + if (parent.getLastSelectedRom() != null) { + JFileChooser fc = new JFileChooser(parent.getSettings().getLastImageDir()); + fc.setFileFilter(new ECUImageFilter()); + + if (fc.showSaveDialog(parent) == fc.APPROVE_OPTION) { + boolean save = true; + if (fc.getSelectedFile().exists()) { + if (new JOptionPane().showConfirmDialog(parent, fc.getSelectedFile().getName() + " already exists! Overwrite?") == JOptionPane.CANCEL_OPTION) { + save = false; + } + } + if (save) { + byte[] output = parent.getLastSelectedRom().saveFile(); + FileOutputStream fos = new FileOutputStream(fc.getSelectedFile()); + fos.write(output); + fos.close(); + fos = null; + + parent.getLastSelectedRom().setFullFileName(fc.getSelectedFile().getAbsoluteFile()); + parent.setLastSelectedRom(parent.getLastSelectedRom()); + } + } + } + } + + public void openImageDialog() throws XMLParseException, Exception { + JFileChooser fc = new JFileChooser(parent.getSettings().getLastImageDir()); + fc.setFileFilter(new ECUImageFilter()); + + if (fc.showOpenDialog(parent) == fc.APPROVE_OPTION) { + openImage(fc.getSelectedFile()); + parent.getSettings().setLastImageDir(fc.getCurrentDirectory()); + } + } + + public void openImage(File inputFile) throws XMLParseException, Exception { + try { + parent.repaintPanel(); + JProgressPane progress = new JProgressPane(parent, "Opening file...", "Parsing ECU definitions..."); + progress.update("Parsing ECU definitions...", 0); + + InputSource src = new InputSource(new FileInputStream(parent.getSettings().getEcuDefinitionFile())); + DOMRomUnmarshaller domUms = new DOMRomUnmarshaller(); + DOMParser parser = new DOMParser(); + parser.parse(src); + Document doc = parser.getDocument(); + FileInputStream fis = new FileInputStream(inputFile); + byte[] input = new byte[fis.available()]; + fis.read(input); + fis.close(); + + progress.update("Finding ECU definition...", 10); + + Rom rom = domUms.unmarshallXMLDefinition(doc.getDocumentElement(), input, progress); + progress.update("Populating tables...", 50); + rom.populateTables(input, progress); + rom.setFileName(inputFile.getName()); + + progress.update("Finalizing...", 90); + parent.addRom(rom); + rom.setFullFileName(inputFile); + + progress.dispose(); + + } catch (RomNotFoundException ex) { + new JOptionPane().showMessageDialog(parent, "ECU Definition Not Found", "Error Loading " + inputFile.getName(), JOptionPane.ERROR_MESSAGE); + + } catch (StackOverflowError ex) { + new JOptionPane().showMessageDialog(parent, "Looped \"base\" attribute in XML definitions.", "Error Loading ROM", JOptionPane.ERROR_MESSAGE); + + } + } +} \ No newline at end of file diff --git a/src/enginuity/swing/ECUEditorToolBar.java b/src/enginuity/swing/ECUEditorToolBar.java new file mode 100644 index 00000000..8aee7e5f --- /dev/null +++ b/src/enginuity/swing/ECUEditorToolBar.java @@ -0,0 +1,99 @@ +package enginuity.swing; + +import enginuity.swing.DebugPanel; +import enginuity.swing.ECUEditorMenuBar; +import enginuity.ECUEditor; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.management.modelmbean.XMLParseException; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JOptionPane; +import javax.swing.JToolBar; +import javax.swing.border.LineBorder; + +public class ECUEditorToolBar extends JToolBar implements ActionListener { + + private ECUEditor parent; + private JButton openImage = new JButton(new ImageIcon("./graphics/icon-open.png")); + private JButton saveImage = new JButton(new ImageIcon("./graphics/icon-save.png")); + private JButton refreshImage = new JButton(new ImageIcon("./graphics/icon-refresh.png")); + private JButton closeImage = new JButton(new ImageIcon("./graphics/icon-close.png")); + + public ECUEditorToolBar(ECUEditor parent) { + super(); + this.parent = parent; + this.setFloatable(false); + this.add(openImage); + this.add(saveImage); + this.add(closeImage); + this.add(refreshImage); + + openImage.setMaximumSize(new Dimension(58,50)); + openImage.setBorder(new LineBorder(new Color(150,150,150), 1)); + saveImage.setMaximumSize(new Dimension(50,50)); + saveImage.setBorder(new LineBorder(new Color(150,150,150), 1)); + closeImage.setMaximumSize(new Dimension(50,50)); + closeImage.setBorder(new LineBorder(new Color(150,150,150), 1)); + refreshImage.setMaximumSize(new Dimension(50,50)); + refreshImage.setBorder(new LineBorder(new Color(150,150,150), 1)); + + updateButtons(); + + openImage.addActionListener(this); + saveImage.addActionListener(this); + closeImage.addActionListener(this); + refreshImage.addActionListener(this); + } + + public void updateButtons() { + String file = ""; + try { + file = " " + parent.getLastSelectedRom().getFileName(); + } catch (NullPointerException ex) { } + + openImage.setToolTipText("Open Image"); + saveImage.setToolTipText("Save" + file); + refreshImage.setToolTipText("Refresh" + file + " from saved copy"); + closeImage.setToolTipText("Close" + file); + + if (file.equals("")) { + saveImage.setEnabled(false); + refreshImage.setEnabled(false); + closeImage.setEnabled(false); + } else { + saveImage.setEnabled(true); + refreshImage.setEnabled(true); + closeImage.setEnabled(true); + } + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == openImage) { + try { + ((ECUEditorMenuBar)parent.getJMenuBar()).openImageDialog(); + } catch (Exception ex) { + new JOptionPane().showMessageDialog(parent, new DebugPanel(ex, + parent.getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE); + } + } else if (e.getSource() == saveImage) { + try { + ((ECUEditorMenuBar)parent.getJMenuBar()).saveImage(parent.getLastSelectedRom()); + } catch (Exception ex) { + new JOptionPane().showMessageDialog(parent, new DebugPanel(ex, + parent.getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE); + } + } else if (e.getSource() == closeImage) { + ((ECUEditorMenuBar)parent.getJMenuBar()).closeImage(); + } else if (e.getSource() == refreshImage) { + try { + ((ECUEditorMenuBar)parent.getJMenuBar()).refreshImage(); + } catch (Exception ex) { + new JOptionPane().showMessageDialog(parent, new DebugPanel(ex, + parent.getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE); + } + } + } +} \ No newline at end of file diff --git a/src/enginuity/swing/ECUImageFilter.java b/src/enginuity/swing/ECUImageFilter.java new file mode 100644 index 00000000..81352afe --- /dev/null +++ b/src/enginuity/swing/ECUImageFilter.java @@ -0,0 +1,91 @@ +package enginuity.swing; + +import java.io.File; +import java.util.Hashtable; +import java.util.Enumeration; +import javax.swing.*; +import javax.swing.filechooser.*; + +public class ECUImageFilter extends FileFilter { + + private static String TYPE_UNKNOWN = "Type Unknown"; + private static String HIDDEN_FILE = "Hidden File"; + + private Hashtable filters = null; + private String description = null; + private String fullDescription = null; + private boolean useExtensionsInDescription = true; + + public ECUImageFilter() { + this.filters = new Hashtable(); + this.addExtension("bin"); + this.addExtension("hex"); + this.setDescription("ECU Image Files"); + } + + public boolean accept(File f) { + if(f != null) { + if(f.isDirectory()) { + return true; + } + String extension = getExtension(f); + if(extension != null && filters.get(getExtension(f)) != null) { + return true; + }; + } + return false; + } + + public String getExtension(File f) { + if(f != null) { + String filename = f.getName(); + int i = filename.lastIndexOf('.'); + if(i>0 && i roms, Component parent, Table targetTable) { + + for (int i = 0; i < roms.size(); i++) { + Rom rom = roms.get(i); + DefaultMutableTreeNode romNode = new DefaultMutableTreeNode(rom.getFileName()); + rootNode.add(romNode); + + for (int j = 0; j < rom.getTables().size(); j++) { + Table table = rom.getTables().get(j); + TableChooserTreeNode tableNode = new TableChooserTreeNode(table.getName(), table); + + // categories + boolean categoryExists = false; + for (int k = 0; k < romNode.getChildCount(); k++) { + if (romNode.getChildAt(k).toString().equalsIgnoreCase(table.getCategory())) { + ((DefaultMutableTreeNode)romNode.getChildAt(k)).add(tableNode); + categoryExists = true; + break; + } + } + + if (!categoryExists) { + DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(table.getCategory()); + romNode.add(categoryNode); + categoryNode.add(tableNode); + } + } + } + + displayPanel.setPreferredSize(new Dimension(350, 400)); + displayTree.setMinimumSize(new Dimension(330, 400)); + + displayTree.setRootVisible(false); + displayTree.updateUI(); + displayPanel.add(new JScrollPane(displayTree)); + + Object[] values = { "Compare", "Cancel" }; + + if ((showOptionDialog(parent, displayPanel, "Select a Map", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, values, values[0]) == 0 && + (displayTree.getLastSelectedPathComponent() instanceof TableChooserTreeNode))) { + ((TableChooserTreeNode)displayTree.getLastSelectedPathComponent()).getTable().copyTable(); + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/src/enginuity/swing/MDIDesktopPane.java b/src/enginuity/swing/MDIDesktopPane.java new file mode 100644 index 00000000..f78a232b --- /dev/null +++ b/src/enginuity/swing/MDIDesktopPane.java @@ -0,0 +1,210 @@ +package enginuity.swing; + +import enginuity.swing.MDIDesktopPane; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.beans.*; + +/** + * An extension of WDesktopPane that supports often used MDI functionality. This + * class also handles setting scroll bars for when windows move too far to the left or + * bottom, providing the MDIDesktopPane is in a ScrollPane. + */ +public class MDIDesktopPane extends JDesktopPane { + private static int FRAME_OFFSET=20; + private MDIDesktopManager manager; + + public MDIDesktopPane() { + manager=new MDIDesktopManager(this); + setDesktopManager(manager); + setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); + } + + public void setBounds(int x, int y, int w, int h) { + super.setBounds(x,y,w,h); + checkDesktopSize(); + } + + public Component add(JInternalFrame frame) { + JInternalFrame[] array = getAllFrames(); + Point p; + int w; + int h; + + Component retval=super.add(frame); + checkDesktopSize(); + if (array.length > 0) { + p = array[0].getLocation(); + p.x = p.x + FRAME_OFFSET; + p.y = p.y + FRAME_OFFSET; + } + else { + p = new Point(0, 0); + } + frame.setLocation(p.x, p.y); + if (frame.isResizable()) { + w = getWidth() - (getWidth()/3); + h = getHeight() - (getHeight()/3); + if (w < frame.getMinimumSize().getWidth()) w = (int)frame.getMinimumSize().getWidth(); + if (h < frame.getMinimumSize().getHeight()) h = (int)frame.getMinimumSize().getHeight(); + frame.setSize(w, h); + } + moveToFront(frame); + frame.setVisible(true); + try { + frame.setSelected(true); + } catch (PropertyVetoException e) { + frame.toBack(); + } + return retval; + } + + public void remove(Component c) { + super.remove(c); + checkDesktopSize(); + } + + /** + * Cascade all internal frames + */ + public void cascadeFrames() { + int x = 0; + int y = 0; + JInternalFrame allFrames[] = getAllFrames(); + + manager.setNormalSize(); + int frameHeight = (getBounds().height - 5) - allFrames.length * FRAME_OFFSET; + int frameWidth = (getBounds().width - 5) - allFrames.length * FRAME_OFFSET; + for (int i = allFrames.length - 1; i >= 0; i--) { + allFrames[i].setSize(frameWidth,frameHeight); + allFrames[i].setLocation(x,y); + x = x + FRAME_OFFSET; + y = y + FRAME_OFFSET; + } + } + + /** + * Tile all internal frames + */ + public void tileFrames() { + java.awt.Component allFrames[] = getAllFrames(); + manager.setNormalSize(); + int frameHeight = getBounds().height/allFrames.length; + int y = 0; + for (int i = 0; i < allFrames.length; i++) { + allFrames[i].setSize(getBounds().width,frameHeight); + allFrames[i].setLocation(0,y); + y = y + frameHeight; + } + } + + /** + * Sets all component size properties ( maximum, minimum, preferred) + * to the given dimension. + */ + public void setAllSize(Dimension d){ + setMinimumSize(d); + setMaximumSize(d); + setPreferredSize(d); + } + + /** + * Sets all component size properties ( maximum, minimum, preferred) + * to the given width and height. + */ + public void setAllSize(int width, int height){ + setAllSize(new Dimension(width,height)); + } + + private void checkDesktopSize() { + if (getParent()!=null&&isVisible()) manager.resizeDesktop(); + } +} + +/** + * Private class used to replace the standard DesktopManager for JDesktopPane. + * Used to provide scrollbar functionality. + */ +class MDIDesktopManager extends DefaultDesktopManager { + private MDIDesktopPane desktop; + + public MDIDesktopManager(MDIDesktopPane desktop) { + this.desktop = desktop; + } + + public void endResizingFrame(JComponent f) { + super.endResizingFrame(f); + resizeDesktop(); + } + + public void endDraggingFrame(JComponent f) { + super.endDraggingFrame(f); + resizeDesktop(); + } + + public void setNormalSize() { + JScrollPane scrollPane=getScrollPane(); + int x = 0; + int y = 0; + Insets scrollInsets = getScrollPaneInsets(); + + if (scrollPane != null) { + Dimension d = scrollPane.getVisibleRect().getSize(); + if (scrollPane.getBorder() != null) { + d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, + d.getHeight() - scrollInsets.top - scrollInsets.bottom); + } + + d.setSize(d.getWidth() - 20, d.getHeight() - 20); + desktop.setAllSize(x,y); + scrollPane.invalidate(); + scrollPane.validate(); + } + } + + private Insets getScrollPaneInsets() { + JScrollPane scrollPane=getScrollPane(); + if (scrollPane==null) return new Insets(0,0,0,0); + else return getScrollPane().getBorder().getBorderInsets(scrollPane); + } + + private JScrollPane getScrollPane() { + if (desktop.getParent() instanceof JViewport) { + JViewport viewPort = (JViewport)desktop.getParent(); + if (viewPort.getParent() instanceof JScrollPane) + return (JScrollPane)viewPort.getParent(); + } + return null; + } + + protected void resizeDesktop() { + int x = 0; + int y = 0; + JScrollPane scrollPane = getScrollPane(); + Insets scrollInsets = getScrollPaneInsets(); + + if (scrollPane != null) { + JInternalFrame allFrames[] = desktop.getAllFrames(); + for (int i = 0; i < allFrames.length; i++) { + if (allFrames[i].getX()+allFrames[i].getWidth()>x) { + x = allFrames[i].getX() + allFrames[i].getWidth(); + } + if (allFrames[i].getY()+allFrames[i].getHeight()>y) { + y = allFrames[i].getY() + allFrames[i].getHeight(); + } + } + Dimension d=scrollPane.getVisibleRect().getSize(); + if (scrollPane.getBorder() != null) { + d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, + d.getHeight() - scrollInsets.top - scrollInsets.bottom); + } + + if (x <= d.getWidth()) x = ((int)d.getWidth()) - 20; + if (y <= d.getHeight()) y = ((int)d.getHeight()) - 20; + desktop.setAllSize(x,y); + scrollPane.invalidate(); + scrollPane.validate(); + } + } +} \ No newline at end of file diff --git a/src/enginuity/swing/RomPropertyPanel.form b/src/enginuity/swing/RomPropertyPanel.form new file mode 100644 index 00000000..f00a3ce6 --- /dev/null +++ b/src/enginuity/swing/RomPropertyPanel.form @@ -0,0 +1,307 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/enginuity/swing/RomPropertyPanel.java b/src/enginuity/swing/RomPropertyPanel.java new file mode 100644 index 00000000..236fb359 --- /dev/null +++ b/src/enginuity/swing/RomPropertyPanel.java @@ -0,0 +1,264 @@ +package enginuity.swing; + +import enginuity.maps.Rom; + +public class RomPropertyPanel extends javax.swing.JPanel { + + Rom rom = new Rom(); + + public RomPropertyPanel(Rom rom) { + initComponents(); + + // populate fields + fileName.setText(rom.getFileName()); + xmlID.setText(rom.getRomID().getXmlid()); + ecuVersion.setText(rom.getRomID().getCaseId()); + fileSize.setText((rom.getRealFileSize() / 1024) + "kb"); + internalID.setText(rom.getRomID().getInternalIdString()); + storageAddress.setText("0x" + Integer.toHexString(rom.getRomID().getInternalIdAddress())); + + make.setText(rom.getRomID().getMake()); + market.setText(rom.getRomID().getMarket()); + year.setText(rom.getRomID().getYear()+""); + model.setText(rom.getRomID().getModel()); + submodel.setText(rom.getRomID().getSubModel()); + transmission.setText(rom.getRomID().getTransmission()); + + tableList.setListData(rom.getTables()); + } + + //prevent bad constructor + private RomPropertyPanel() { } + // //GEN-BEGIN:initComponents + private void initComponents() { + lblFilename = new javax.swing.JLabel(); + fileName = new javax.swing.JLabel(); + lblECURevision = new javax.swing.JLabel(); + xmlID = new javax.swing.JLabel(); + lblFilesize = new javax.swing.JLabel(); + fileSize = new javax.swing.JLabel(); + lblEcuVersion = new javax.swing.JLabel(); + ecuVersion = new javax.swing.JLabel(); + lblInternalId = new javax.swing.JLabel(); + internalID = new javax.swing.JLabel(); + lblStorageAddress = new javax.swing.JLabel(); + storageAddress = new javax.swing.JLabel(); + lblMake = new javax.swing.JLabel(); + lblMarket = new javax.swing.JLabel(); + lblTransmission = new javax.swing.JLabel(); + lblModel = new javax.swing.JLabel(); + lblSubmodel = new javax.swing.JLabel(); + lblYear = new javax.swing.JLabel(); + make = new javax.swing.JLabel(); + market = new javax.swing.JLabel(); + year = new javax.swing.JLabel(); + model = new javax.swing.JLabel(); + submodel = new javax.swing.JLabel(); + transmission = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + tableList = new javax.swing.JList(); + lblTables = new javax.swing.JLabel(); + + lblFilename.setText("Filename:"); + + fileName.setText("Filename"); + + lblECURevision.setText("ECU Revision:"); + + xmlID.setText("XMLID"); + + lblFilesize.setText("Filesize:"); + + fileSize.setText("999kb"); + + lblEcuVersion.setText("ECU Version:"); + + ecuVersion.setText("ECUVER"); + + lblInternalId.setText("Internal ID:"); + + internalID.setText("INTERNAL"); + + lblStorageAddress.setText("ID Storage Address:"); + + storageAddress.setText("0x00"); + + lblMake.setText("Make:"); + + lblMarket.setText("Market:"); + + lblTransmission.setText("Transmission:"); + + lblModel.setText("Model:"); + + lblSubmodel.setText("Submodel:"); + + lblYear.setText("Year:"); + + make.setText("Make"); + + market.setText("Market"); + + year.setText("Year"); + + model.setText("Model"); + + submodel.setText("Submodel"); + + transmission.setText("Transmission"); + + tableList.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + jScrollPane1.setViewportView(tableList); + + lblTables.setText("Tables:"); + + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(lblFilename) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(fileName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 302, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblECURevision) + .add(lblEcuVersion) + .add(lblFilesize)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(fileSize) + .add(ecuVersion) + .add(xmlID))) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblYear) + .add(lblModel) + .add(lblSubmodel) + .add(lblTransmission) + .add(lblMarket) + .add(lblMake)) + .add(7, 7, 7) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(make) + .add(market) + .add(year) + .add(layout.createSequentialGroup() + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(transmission) + .add(submodel))) + .add(model)))) + .add(32, 32, 32) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblInternalId) + .add(lblStorageAddress)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 53, Short.MAX_VALUE) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(internalID) + .add(storageAddress)) + .add(36, 36, 36)) + .add(lblTables) + .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 226, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .add(21, 21, 21) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblFilename) + .add(fileName)) + .add(layout.createSequentialGroup() + .add(40, 40, 40) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblECURevision) + .add(xmlID) + .add(lblInternalId) + .add(internalID)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(ecuVersion) + .add(lblEcuVersion) + .add(storageAddress) + .add(lblStorageAddress)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblFilesize) + .add(fileSize)))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(lblTables) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblMake) + .add(make)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblMarket) + .add(market)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblYear) + .add(year)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblModel) + .add(model)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblSubmodel) + .add(submodel)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblTransmission) + .add(transmission))) + .add(jScrollPane1, 0, 0, Short.MAX_VALUE)) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel ecuVersion; + private javax.swing.JLabel fileName; + private javax.swing.JLabel fileSize; + private javax.swing.JLabel internalID; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel lblECURevision; + private javax.swing.JLabel lblEcuVersion; + private javax.swing.JLabel lblFilename; + private javax.swing.JLabel lblFilesize; + private javax.swing.JLabel lblInternalId; + private javax.swing.JLabel lblMake; + private javax.swing.JLabel lblMarket; + private javax.swing.JLabel lblModel; + private javax.swing.JLabel lblStorageAddress; + private javax.swing.JLabel lblSubmodel; + private javax.swing.JLabel lblTables; + private javax.swing.JLabel lblTransmission; + private javax.swing.JLabel lblYear; + private javax.swing.JLabel make; + private javax.swing.JLabel market; + private javax.swing.JLabel model; + private javax.swing.JLabel storageAddress; + private javax.swing.JLabel submodel; + private javax.swing.JList tableList; + private javax.swing.JLabel transmission; + private javax.swing.JLabel xmlID; + private javax.swing.JLabel year; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/enginuity/swing/RomTree.java b/src/enginuity/swing/RomTree.java new file mode 100644 index 00000000..72fb3550 --- /dev/null +++ b/src/enginuity/swing/RomTree.java @@ -0,0 +1,55 @@ +package enginuity.swing; + +import enginuity.ECUEditor; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; + +public class RomTree extends JTree implements MouseListener { + + private ECUEditor container; + + public RomTree (DefaultMutableTreeNode input) { + super(input); + this.setRootVisible(false); + this.addMouseListener(this); + } + + public ECUEditor getContainer() { + return container; + } + + public void setContainer(ECUEditor container) { + this.container = container; + } + + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + try { + TableTreeNode node = (TableTreeNode)this.getLastSelectedPathComponent(); + container.displayTable(node.getFrame()); + } catch (ClassCastException ex) { + } catch (NullPointerException ex) { } + } if (e.getClickCount() == 1) { + + + if (getLastSelectedPathComponent() instanceof TableTreeNode) { + TableTreeNode node = (TableTreeNode)this.getLastSelectedPathComponent(); + container.setLastSelectedRom(node.getTable().getRom()); + } else if (getLastSelectedPathComponent() instanceof CategoryTreeNode) { + CategoryTreeNode node = (CategoryTreeNode)this.getLastSelectedPathComponent(); + container.setLastSelectedRom(node.getRom()); + } else if (getLastSelectedPathComponent() instanceof RomTreeNode) { + RomTreeNode node = (RomTreeNode)this.getLastSelectedPathComponent(); + container.setLastSelectedRom(node.getRom()); + } + } + } + + public void mousePressed(MouseEvent e) { } + public void mouseReleased(MouseEvent e) { } + public void mouseEntered(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } + +} \ No newline at end of file diff --git a/src/enginuity/swing/RomTreeNode.java b/src/enginuity/swing/RomTreeNode.java new file mode 100644 index 00000000..516eaa44 --- /dev/null +++ b/src/enginuity/swing/RomTreeNode.java @@ -0,0 +1,59 @@ +package enginuity.swing; + +import enginuity.maps.Rom; +import enginuity.maps.Table; +import javax.swing.tree.DefaultMutableTreeNode; + +public class RomTreeNode extends DefaultMutableTreeNode { + + private Rom rom = new Rom(); + + public RomTreeNode(Rom rom) { + super(rom.getFileName()); + this.setRom(rom); + } + + public void updateFileName() { + this.setUserObject(rom.getFileName()); + } + + public void add(Table table) { + boolean categoryExists = false; + for (int i = 0; i < this.getChildCount(); i++) { + if (this.getChildAt(i).toString().equals(table.getCategory())) { + + TableFrame frame = new TableFrame(table); + table.setFrame(frame); + TableTreeNode tableNode = new TableTreeNode(table); + + this.getChildAt(i).add(tableNode); + categoryExists = true; + break; + } + } + if (!categoryExists) { + this.add(new CategoryTreeNode(table.getCategory(), table.getRom())); + + TableFrame frame = new TableFrame(table); + table.setFrame(frame); + TableTreeNode tableNode = new TableTreeNode(table); + this.getLastChild().add(tableNode); + } + } + + public DefaultMutableTreeNode getChildAt(int i) { + return (DefaultMutableTreeNode)super.getChildAt(i); + } + + public DefaultMutableTreeNode getLastChild() { + return (DefaultMutableTreeNode)super.getLastChild(); + } + + public Rom getRom() { + return rom; + } + + public void setRom(Rom rom) { + this.rom = rom; + } +} \ No newline at end of file diff --git a/src/enginuity/swing/SettingsForm.form b/src/enginuity/swing/SettingsForm.form new file mode 100644 index 00000000..7629a1ac --- /dev/null +++ b/src/enginuity/swing/SettingsForm.form @@ -0,0 +1,464 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/enginuity/swing/SettingsForm.java b/src/enginuity/swing/SettingsForm.java new file mode 100644 index 00000000..ff96f677 --- /dev/null +++ b/src/enginuity/swing/SettingsForm.java @@ -0,0 +1,503 @@ +package enginuity.swing; + +import ZoeloeSoft.projects.JFontChooser.JFontChooser; +import enginuity.ECUEditor; +import enginuity.Settings; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.File; +import javax.swing.JColorChooser; +import javax.swing.JFileChooser; +import javax.swing.JFrame; + +public class SettingsForm extends JFrame implements MouseListener { + + Settings settings; + ECUEditor parent; + + public SettingsForm(ECUEditor parent) { + this.parent = parent; + settings = parent.getSettings(); + initComponents(); + initSettings(); + + maxColor.addMouseListener(this); + minColor.addMouseListener(this); + highlightColor.addMouseListener(this); + axisColor.addMouseListener(this); + increaseColor.addMouseListener(this); + decreaseColor.addMouseListener(this); + + btnOk.addMouseListener(this); + btnApply.addMouseListener(this); + btnCancel.addMouseListener(this); + btnEcuDefinitionBrowse.addMouseListener(this); + btnChooseFont.addMouseListener(this); + reset.addMouseListener(this); + } + + private void initSettings() { + + ecuDefinitionFile.setText(this.settings.getEcuDefinitionFile().getAbsolutePath()); + + obsoleteWarning.setSelected(settings.isObsoleteWarning()); + calcConflictWarning.setSelected(settings.isCalcConflictWarning()); + singleTableView.setSelected(settings.isSingleTableView()); + debug.setSelected(settings.isDebug()); + + maxColor.setBackground(settings.getMaxColor()); + minColor.setBackground(settings.getMinColor()); + highlightColor.setBackground(settings.getHighlightColor()); + axisColor.setBackground(settings.getAxisColor()); + increaseColor.setBackground(settings.getIncreaseBorder()); + decreaseColor.setBackground(settings.getDecreaseBorder()); + + cellWidth.setText(((int)settings.getCellSize().getWidth())+""); + cellHeight.setText(((int)settings.getCellSize().getHeight())+""); + + btnChooseFont.setFont(settings.getTableFont()); + btnChooseFont.setText(settings.getTableFont().getFontName()); + } + + // //GEN-BEGIN:initComponents + private void initComponents() { + lblEcuDef = new javax.swing.JLabel(); + ecuDefinitionFile = new javax.swing.JTextField(); + btnEcuDefinitionBrowse = new javax.swing.JButton(); + lblMax = new javax.swing.JLabel(); + lblMin = new javax.swing.JLabel(); + lblHighlight = new javax.swing.JLabel(); + lblAxis = new javax.swing.JLabel(); + maxColor = new javax.swing.JLabel(); + minColor = new javax.swing.JLabel(); + highlightColor = new javax.swing.JLabel(); + axisColor = new javax.swing.JLabel(); + lblIncrease = new javax.swing.JLabel(); + lblDecrease = new javax.swing.JLabel(); + lblBackgrounds = new javax.swing.JLabel(); + increaseColor = new javax.swing.JLabel(); + obsoleteWarning = new javax.swing.JCheckBox(); + calcConflictWarning = new javax.swing.JCheckBox(); + debug = new javax.swing.JCheckBox(); + btnCancel = new javax.swing.JButton(); + btnOk = new javax.swing.JButton(); + btnApply = new javax.swing.JButton(); + decreaseColor = new javax.swing.JLabel(); + lblBorders = new javax.swing.JLabel(); + lblCellSize = new javax.swing.JLabel(); + lblCellHeight = new javax.swing.JLabel(); + lblCellWidth = new javax.swing.JLabel(); + cellWidth = new javax.swing.JTextField(); + cellHeight = new javax.swing.JTextField(); + singleTableView = new javax.swing.JCheckBox(); + lblFont = new javax.swing.JLabel(); + btnChooseFont = new javax.swing.JButton(); + reset = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Enginuity Settings"); + setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + lblEcuDef.setText("ECU Definition File:"); + + btnEcuDefinitionBrowse.setText("Browse"); + + lblMax.setText("Maximum Value:"); + + lblMin.setText("Minimum Value:"); + + lblHighlight.setText("Highlighted Cell:"); + + lblAxis.setText("Axis Cell:"); + + maxColor.setBackground(new java.awt.Color(255, 0, 0)); + maxColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + maxColor.setOpaque(true); + + minColor.setBackground(new java.awt.Color(255, 0, 0)); + minColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + minColor.setOpaque(true); + + highlightColor.setBackground(new java.awt.Color(255, 0, 0)); + highlightColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + highlightColor.setOpaque(true); + + axisColor.setBackground(new java.awt.Color(255, 0, 0)); + axisColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + axisColor.setOpaque(true); + + lblIncrease.setText("Increased Value:"); + + lblDecrease.setText("Decreased Value:"); + + lblBackgrounds.setText("Backgrounds"); + + increaseColor.setBackground(new java.awt.Color(255, 0, 0)); + increaseColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + increaseColor.setOpaque(true); + + obsoleteWarning.setText("Warn me when opening out of date ECU image revision"); + obsoleteWarning.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + obsoleteWarning.setMargin(new java.awt.Insets(0, 0, 0, 0)); + + calcConflictWarning.setText("Warn me when real and byte value calculations conflict"); + calcConflictWarning.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + calcConflictWarning.setMargin(new java.awt.Insets(0, 0, 0, 0)); + + debug.setText("Debug mode"); + debug.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + debug.setEnabled(false); + debug.setMargin(new java.awt.Insets(0, 0, 0, 0)); + + btnCancel.setMnemonic('C'); + btnCancel.setText("Cancel"); + + btnOk.setMnemonic('O'); + btnOk.setText("OK"); + + btnApply.setMnemonic('A'); + btnApply.setText("Apply"); + + decreaseColor.setBackground(new java.awt.Color(255, 0, 0)); + decreaseColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + decreaseColor.setOpaque(true); + + lblBorders.setText("Borders"); + + lblCellSize.setText("Cell Size"); + + lblCellHeight.setText("Height:"); + + lblCellWidth.setText("Width:"); + + singleTableView.setText("Open tables in place of existing tables"); + singleTableView.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + singleTableView.setEnabled(false); + singleTableView.setMargin(new java.awt.Insets(0, 0, 0, 0)); + + lblFont.setText("Font"); + + btnChooseFont.setText("Choose"); + + reset.setText("Restore Defaults"); + + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(10, 10, 10) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblEcuDef) + .add(layout.createSequentialGroup() + .add(ecuDefinitionFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 257, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(btnEcuDefinitionBrowse)))) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(calcConflictWarning) + .add(obsoleteWarning) + .add(singleTableView) + .add(debug))) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(lblAxis) + .add(lblHighlight) + .add(lblMin)) + .add(lblMax)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(org.jdesktop.layout.GroupLayout.TRAILING, maxColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, minColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, highlightColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, axisColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(layout.createSequentialGroup() + .add(53, 53, 53) + .add(lblCellSize))) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(57, 57, 57) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblDecrease) + .add(layout.createSequentialGroup() + .add(3, 3, 3) + .add(lblIncrease))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(increaseColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(decreaseColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(layout.createSequentialGroup() + .add(47, 47, 47) + .add(lblBorders)) + .add(btnChooseFont, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE))) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(lblFont) + .add(65, 65, 65)))) + .add(layout.createSequentialGroup() + .add(47, 47, 47) + .add(lblBackgrounds)))) + .add(layout.createSequentialGroup() + .add(20, 20, 20) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(lblCellWidth) + .add(lblCellHeight)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(layout.createSequentialGroup() + .add(10, 10, 10) + .add(cellWidth, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(cellHeight, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .add(reset) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 34, Short.MAX_VALUE) + .add(btnApply) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(btnOk) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(btnCancel))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(lblEcuDef) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(btnEcuDefinitionBrowse) + .add(ecuDefinitionFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(27, 27, 27) + .add(obsoleteWarning) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(calcConflictWarning) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(singleTableView) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(debug) + .add(31, 31, 31) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(lblBorders) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(increaseColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(lblIncrease)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblDecrease) + .add(decreaseColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(layout.createSequentialGroup() + .add(lblBackgrounds) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblMax) + .add(maxColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblMin) + .add(minColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblHighlight) + .add(highlightColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblAxis) + .add(axisColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) + .add(29, 29, 29) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblCellSize) + .add(lblFont)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblCellWidth) + .add(cellWidth, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(btnChooseFont, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblCellHeight) + .add(cellHeight, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 8, Short.MAX_VALUE) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(btnCancel) + .add(btnOk) + .add(btnApply) + .add(reset)) + .addContainerGap()) + ); + pack(); + }// //GEN-END:initComponents + + public void mouseClicked(MouseEvent e) { + if (e.getSource() == maxColor) { + JColorChooser chooser = new JColorChooser(); + Color color = chooser.showDialog(this.getContentPane(), "Background Color", settings.getMaxColor()); + + if (color != null) { + maxColor.setBackground(color); + } + + } else if (e.getSource() == minColor) { + JColorChooser chooser = new JColorChooser(); + Color color = chooser.showDialog(this.getContentPane(), "Background Color", settings.getMinColor()); + + if (color != null) { + minColor.setBackground(color); + } + + } else if (e.getSource() == highlightColor) { + JColorChooser chooser = new JColorChooser(); + Color color = chooser.showDialog(this.getContentPane(), "Background Color", settings.getHighlightColor()); + + if (color != null) { + highlightColor.setBackground(color); + } + + } else if (e.getSource() == axisColor) { + JColorChooser chooser = new JColorChooser(); + Color color = chooser.showDialog(this.getContentPane(), "Background Color", settings.getAxisColor()); + + if (color != null) { + axisColor.setBackground(color); + } + + } else if (e.getSource() == increaseColor) { + JColorChooser chooser = new JColorChooser(); + Color color = chooser.showDialog(this.getContentPane(), "Background Color", settings.getIncreaseBorder()); + + if (color != null) { + increaseColor.setBackground(color); + } + + } else if (e.getSource() == decreaseColor) { + JColorChooser chooser = new JColorChooser(); + Color color = chooser.showDialog(this.getContentPane(), "Background Color", settings.getDecreaseBorder()); + + if (color != null) { + decreaseColor.setBackground(color); + } + + } else if (e.getSource() == btnApply) { + applySettings(); + + } else if (e.getSource() == btnOk) { + applySettings(); + this.dispose(); + + } else if (e.getSource() == btnCancel) { + this.dispose(); + + } else if (e.getSource() == btnEcuDefinitionBrowse) { + JFileChooser fc = new JFileChooser(new File(ecuDefinitionFile.getText())); + fc.setFileFilter(new XMLFilter()); + + if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) { + ecuDefinitionFile.setText(fc.getSelectedFile().getAbsolutePath()); + } + + } else if (e.getSource() == btnChooseFont) { + JFontChooser fc = new JFontChooser(this); + fc.setLocationRelativeTo(this); + if (fc.showDialog(settings.getTableFont()) == fc.OK_OPTION) { + btnChooseFont.setFont(fc.getFont()); + btnChooseFont.setText(fc.getFont().getFontName()); + } + + } else if (e.getSource() == reset) { + settings = new Settings(); + initSettings(); + + } + } + + public void applySettings() { + try { + Integer.parseInt(cellHeight.getText()); + } catch (NumberFormatException ex) { + //number formatted imporperly, reset + cellHeight.setText((int)(settings.getCellSize().getHeight())+""); + } + try { + Integer.parseInt(cellWidth.getText()); + } catch (NumberFormatException ex) { + //number formatted imporperly, reset + cellWidth.setText((int)(settings.getCellSize().getWidth())+""); + } + + settings.addEcuDefinitionFile(new File(ecuDefinitionFile.getText())); + + settings.setObsoleteWarning(obsoleteWarning.isSelected()); + settings.setCalcConflictWarning(calcConflictWarning.isSelected()); + settings.setSingleTableView(singleTableView.isSelected()); + settings.setDebug(debug.isSelected()); + + settings.setMaxColor(maxColor.getBackground()); + settings.setMinColor(minColor.getBackground()); + settings.setHighlightColor(highlightColor.getBackground()); + settings.setAxisColor(axisColor.getBackground()); + settings.setIncreaseBorder(increaseColor.getBackground()); + settings.setDecreaseBorder(decreaseColor.getBackground()); + + settings.setCellSize(new Dimension(Integer.parseInt(cellWidth.getText()), + Integer.parseInt(cellHeight.getText()))); + + settings.setTableFont(btnChooseFont.getFont()); + + parent.setSettings(settings); + } + + public void mousePressed(MouseEvent e) { } + public void mouseReleased(MouseEvent e) { } + public void mouseEntered(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel axisColor; + private javax.swing.JButton btnApply; + private javax.swing.JButton btnCancel; + private javax.swing.JButton btnChooseFont; + private javax.swing.JButton btnEcuDefinitionBrowse; + private javax.swing.JButton btnOk; + private javax.swing.JCheckBox calcConflictWarning; + private javax.swing.JTextField cellHeight; + private javax.swing.JTextField cellWidth; + private javax.swing.JCheckBox debug; + private javax.swing.JLabel decreaseColor; + private javax.swing.JTextField ecuDefinitionFile; + private javax.swing.JLabel highlightColor; + private javax.swing.JLabel increaseColor; + private javax.swing.JLabel lblAxis; + private javax.swing.JLabel lblBackgrounds; + private javax.swing.JLabel lblBorders; + private javax.swing.JLabel lblCellHeight; + private javax.swing.JLabel lblCellSize; + private javax.swing.JLabel lblCellWidth; + private javax.swing.JLabel lblDecrease; + private javax.swing.JLabel lblEcuDef; + private javax.swing.JLabel lblFont; + private javax.swing.JLabel lblHighlight; + private javax.swing.JLabel lblIncrease; + private javax.swing.JLabel lblMax; + private javax.swing.JLabel lblMin; + private javax.swing.JLabel maxColor; + private javax.swing.JLabel minColor; + private javax.swing.JCheckBox obsoleteWarning; + private javax.swing.JButton reset; + private javax.swing.JCheckBox singleTableView; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/enginuity/swing/TableChooserTreeNode.java b/src/enginuity/swing/TableChooserTreeNode.java new file mode 100644 index 00000000..fac7bf74 --- /dev/null +++ b/src/enginuity/swing/TableChooserTreeNode.java @@ -0,0 +1,20 @@ +package enginuity.swing; + +import enginuity.maps.Table; +import javax.swing.tree.DefaultMutableTreeNode; + +public class TableChooserTreeNode extends DefaultMutableTreeNode { + + private Table table; + + public TableChooserTreeNode(String text, Table table) { + super(text); + this.table = table; + } + + private TableChooserTreeNode() { } + + public Table getTable() { + return table; + } +} \ No newline at end of file diff --git a/src/enginuity/swing/TableFrame.java b/src/enginuity/swing/TableFrame.java new file mode 100644 index 00000000..325beac7 --- /dev/null +++ b/src/enginuity/swing/TableFrame.java @@ -0,0 +1,57 @@ +package enginuity.swing; + +import enginuity.swing.TableMenuBar; +import enginuity.swing.TableToolBar; +import enginuity.maps.Table; +import java.awt.BorderLayout; +import javax.swing.BorderFactory; +import javax.swing.JInternalFrame; +import javax.swing.event.InternalFrameEvent; +import javax.swing.event.InternalFrameListener; + +public class TableFrame extends JInternalFrame implements InternalFrameListener { + + private Table table; + private TableToolBar toolBar; + + public TableFrame(Table table) { + super(table.getRom().getFileName() + " - " + table.getName(), true, true); + this.setTable(table); + this.add(table); + this.setFrameIcon(null); + this.setBorder(BorderFactory.createBevelBorder(0)); + this.setVisible(false); + toolBar = new TableToolBar(table, this); + this.add(toolBar, BorderLayout.NORTH); + this.setJMenuBar(new TableMenuBar(table)); + this.setDefaultCloseOperation(this.HIDE_ON_CLOSE); + table.setFrame(this); + this.addInternalFrameListener(this); + } + + public TableToolBar getToolBar() { + return toolBar; + } + + public void internalFrameActivated(InternalFrameEvent e) { + getTable().getRom().getContainer().setLastSelectedRom(getTable().getRom()); + } + + + public void internalFrameOpened(InternalFrameEvent e) { } + public void internalFrameClosing(InternalFrameEvent e) { + getTable().getRom().getContainer().removeDisplayTable(this); + } + public void internalFrameClosed(InternalFrameEvent e) { } + public void internalFrameIconified(InternalFrameEvent e) { } + public void internalFrameDeiconified(InternalFrameEvent e) { } + public void internalFrameDeactivated(InternalFrameEvent e) { } + + public Table getTable() { + return table; + } + + public void setTable(Table table) { + this.table = table; + } +} \ No newline at end of file diff --git a/src/enginuity/swing/TableMenuBar.java b/src/enginuity/swing/TableMenuBar.java new file mode 100644 index 00000000..f80250ee --- /dev/null +++ b/src/enginuity/swing/TableMenuBar.java @@ -0,0 +1,177 @@ +package enginuity.swing; + +import enginuity.maps.Table; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.ButtonGroup; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JSeparator; + +public class TableMenuBar extends JMenuBar implements ActionListener { + + private Table table; + private JMenu fileMenu = new JMenu("Table"); + private JMenuItem graph = new JMenuItem("View Graph"); + private JMenuItem overlay = new JMenuItem("Overlay Log"); + + private JMenu compareMenu = new JMenu("Compare"); + private JRadioButtonMenuItem compareOriginal = new JRadioButtonMenuItem("Show Changes"); + private JRadioButtonMenuItem compareMap = new JRadioButtonMenuItem("Compare to Another Map"); + private JRadioButtonMenuItem compareOff = new JRadioButtonMenuItem("Off"); + private JMenu compareDisplay = new JMenu("Display"); + private JRadioButtonMenuItem comparePercent = new JRadioButtonMenuItem("Percent Difference"); + private JRadioButtonMenuItem compareAbsolute = new JRadioButtonMenuItem("Absolute Difference"); + + private JMenuItem close = new JMenuItem("Close Table"); + private JMenu editMenu = new JMenu("Edit"); + private JMenuItem undoSel = new JMenuItem("Undo Selected Changes"); + private JMenuItem undoAll = new JMenuItem("Undo All Changes"); + private JMenuItem revert = new JMenuItem("Set Revert Point"); + private JMenuItem copySel = new JMenuItem("Copy Selection"); + private JMenuItem copyTable = new JMenuItem("Copy Table"); + private JMenuItem paste = new JMenuItem("Paste"); + private JMenu viewMenu = new JMenu("View"); + private JMenuItem tableProperties = new JMenuItem("Table Properties"); + + private ButtonGroup compareGroup = new ButtonGroup(); + private ButtonGroup compareDisplayGroup = new ButtonGroup(); + + public TableMenuBar(Table table) { + super(); + this.table = table; + this.add(fileMenu); + fileMenu.add(graph); + fileMenu.add(overlay); + fileMenu.add(compareMenu); + compareMenu.add(compareOriginal); + compareMenu.add(compareMap); + compareMenu.add(compareOff); + compareMenu.add(new JSeparator()); + compareMenu.add(compareDisplay); + compareDisplay.add(comparePercent); + compareDisplay.add(compareAbsolute); + fileMenu.add(new JSeparator()); + fileMenu.add(close); + close.setText("Close " + table.getName()); + + compareMenu.setMnemonic('C'); + compareOriginal.setMnemonic('C'); + compareMap.setMnemonic('M'); + compareOff.setMnemonic('O'); + compareOff.setSelected(true); + compareDisplay.setMnemonic('D'); + comparePercent.setMnemonic('P'); + compareAbsolute.setMnemonic('A'); + compareAbsolute.setSelected(true); + + compareGroup.add(compareOriginal); + compareGroup.add(compareMap); + compareGroup.add(compareOff); + + compareDisplayGroup.add(comparePercent); + compareDisplayGroup.add(compareAbsolute); + + compareOriginal.addActionListener(this); + compareMap.addActionListener(this); + compareOff.addActionListener(this); + comparePercent.addActionListener(this); + compareAbsolute.addActionListener(this); + + // FOR 0.2.7.4b ONLY!! DELETE FOR 0.2.8b! + //compareMap.setEnabled(false); + + + this.add(editMenu); + editMenu.add(undoSel); + editMenu.add(undoAll); + editMenu.add(revert); + editMenu.add(new JSeparator()); + editMenu.add(copySel); + editMenu.add(copyTable); + editMenu.add(new JSeparator()); + editMenu.add(paste); + editMenu.setMnemonic('E'); + copySel.setMnemonic('C'); + copyTable.setMnemonic('T'); + paste.setMnemonic('P'); + copySel.addActionListener(this); + copyTable.addActionListener(this); + paste.addActionListener(this); + + this.add(viewMenu); + viewMenu.add(tableProperties); + viewMenu.setMnemonic('V'); + tableProperties.setMnemonic('P'); + tableProperties.addActionListener(this); + + graph.addActionListener(this); + overlay.addActionListener(this); + undoSel.addActionListener(this); + undoAll.addActionListener(this); + revert.addActionListener(this); + close.addActionListener(this); + + fileMenu.setMnemonic('F'); + fileMenu.setMnemonic('T'); + graph.setMnemonic('G'); + overlay.setMnemonic('L'); + undoSel.setMnemonic('U'); + undoAll.setMnemonic('A'); + revert.setMnemonic('R'); + close.setMnemonic('X'); + + graph.setEnabled(false); + overlay.setEnabled(false); + } + public void actionPerformed(ActionEvent e) { + if (e.getSource() == undoAll) { + table.undoAll(); + + } else if (e.getSource() == revert) { + table.setRevertPoint(); + + } else if (e.getSource() == undoSel) { + table.undoSelected(); + + } else if (e.getSource() == close) { + table.getFrame().dispose(); + + } else if (e.getSource() == tableProperties) { + new JOptionPane().showMessageDialog(table, (Object)(new TablePropertyPanel(table)), + table.getName() + " Table Properties", JOptionPane.INFORMATION_MESSAGE); + + } else if (e.getSource() == copySel) { + table.copySelection(); + + } else if (e.getSource() == copyTable) { + table.copyTable(); + + } else if (e.getSource() == paste) { + table.paste(); + + } else if (e.getSource() == compareOff) { + table.compare(table.COMPARE_OFF); + + } else if (e.getSource() == compareOriginal) { + table.compare(table.COMPARE_ORIGINAL); + + } else if (e.getSource() == compareMap) { + JTableChooser chooser = new JTableChooser(); + if (chooser.showChooser(table.getRom().getContainer().getImages(), table.getRom().getContainer(), table) == true) { + table.pasteCompare(); + table.compare(Table.COMPARE_TABLE); + } + + } else if (e.getSource() == compareAbsolute) { + table.setCompareDisplay(Table.COMPARE_ABSOLUTE); + + } else if (e.getSource() == comparePercent) { + table.setCompareDisplay(Table.COMPARE_PERCENT); + + } + } +} \ No newline at end of file diff --git a/src/enginuity/swing/TablePropertyPanel.form b/src/enginuity/swing/TablePropertyPanel.form new file mode 100644 index 00000000..d92e3897 --- /dev/null +++ b/src/enginuity/swing/TablePropertyPanel.form @@ -0,0 +1,261 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/enginuity/swing/TablePropertyPanel.java b/src/enginuity/swing/TablePropertyPanel.java new file mode 100644 index 00000000..9a625bab --- /dev/null +++ b/src/enginuity/swing/TablePropertyPanel.java @@ -0,0 +1,232 @@ +package enginuity.swing; + +import enginuity.maps.Table; + +public class TablePropertyPanel extends javax.swing.JPanel { + + public TablePropertyPanel(Table table) { + initComponents(); + setVisible(true); + + tableName.setText(table.getName() + " (" + table.getType() + "D)"); + category.setText(table.getCategory()); + unit.setText(table.getScale().getUnit()); + byteToReal.setText(table.getScale().getExpression()); + realToByte.setText(table.getScale().getByteExpression()); + storageSize.setText("uint" + (table.getStorageType() * 8)); + storageAddress.setText("0x" + Integer.toHexString(table.getStorageAddress())); + if (table.getEndian() == table.ENDIAN_BIG) endian.setText("big"); + else endian.setText("little"); + description.setText(table.getDescription()); + System.out.println(table.getDescription()); + } + + private TablePropertyPanel() { } + + // //GEN-BEGIN:initComponents + private void initComponents() { + lblTable = new javax.swing.JLabel(); + tableName = new javax.swing.JLabel(); + lblCategory = new javax.swing.JLabel(); + category = new javax.swing.JLabel(); + lblStorageSize = new javax.swing.JLabel(); + lblStorageAddress = new javax.swing.JLabel(); + lblEndian = new javax.swing.JLabel(); + lblConversion = new javax.swing.JLabel(); + lblStorage = new javax.swing.JLabel(); + lblByteToReal = new javax.swing.JLabel(); + lblRealToByte = new javax.swing.JLabel(); + lblUnit = new javax.swing.JLabel(); + byteToReal = new javax.swing.JLabel(); + realToByte = new javax.swing.JLabel(); + unit = new javax.swing.JLabel(); + storageAddress = new javax.swing.JLabel(); + storageSize = new javax.swing.JLabel(); + endian = new javax.swing.JLabel(); + lblDescription = new javax.swing.JLabel(); + description = new javax.swing.JLabel(); + + lblTable.setText("Table:"); + lblTable.setFocusable(false); + + tableName.setText("Tablename (3D)"); + tableName.setFocusable(false); + + lblCategory.setText("Category:"); + lblCategory.setFocusable(false); + + category.setText("Category"); + category.setFocusable(false); + + lblStorageSize.setText("Storage Size:"); + lblStorageSize.setFocusable(false); + + lblStorageAddress.setText("Storage Address:"); + lblStorageAddress.setFocusable(false); + + lblEndian.setText("Endian:"); + lblEndian.setFocusable(false); + + lblConversion.setText("----------- Conversion -----------"); + lblConversion.setFocusable(false); + + lblStorage.setText("---------- Storage ----------"); + lblStorage.setFocusable(false); + + lblByteToReal.setText("Byte to Real:"); + lblByteToReal.setFocusable(false); + + lblRealToByte.setText("Real to Byte:"); + lblRealToByte.setFocusable(false); + + lblUnit.setText("Unit:"); + lblUnit.setFocusable(false); + + byteToReal.setText("bytetoreal"); + byteToReal.setFocusable(false); + + realToByte.setText("realtobyte"); + realToByte.setFocusable(false); + + unit.setText("unit"); + unit.setFocusable(false); + + storageAddress.setText("0x00"); + storageAddress.setFocusable(false); + + storageSize.setText("uint16"); + storageSize.setFocusable(false); + + endian.setText("little"); + endian.setFocusable(false); + + lblDescription.setText("Description:"); + lblDescription.setFocusable(false); + + description.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + description.setText("Description"); + description.setVerticalAlignment(javax.swing.SwingConstants.TOP); + description.setFocusable(false); + + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(description, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE) + .add(lblDescription) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblConversion) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblByteToReal) + .add(lblRealToByte) + .add(lblUnit)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(byteToReal) + .add(realToByte) + .add(unit))) + .add(layout.createSequentialGroup() + .add(lblTable) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(tableName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 213, Short.MAX_VALUE))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblStorage) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(lblStorageAddress) + .add(lblStorageSize) + .add(lblEndian)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(endian) + .add(storageSize) + .add(storageAddress))) + .add(layout.createSequentialGroup() + .add(lblCategory) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(category))) + .add(20, 20, 20))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblTable) + .add(tableName)) + .add(20, 20, 20) + .add(lblConversion) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(layout.createSequentialGroup() + .add(lblUnit) + .add(40, 40, 40)) + .add(layout.createSequentialGroup() + .add(lblByteToReal) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(lblRealToByte)) + .add(layout.createSequentialGroup() + .add(unit) + .add(40, 40, 40)) + .add(layout.createSequentialGroup() + .add(byteToReal) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(realToByte))) + .add(26, 26, 26) + .add(lblDescription)) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblCategory) + .add(category)) + .add(20, 20, 20) + .add(lblStorage) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblStorageSize) + .add(storageSize)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblStorageAddress) + .add(storageAddress)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(lblEndian) + .add(endian)))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(description, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 60, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel byteToReal; + private javax.swing.JLabel category; + private javax.swing.JLabel description; + private javax.swing.JLabel endian; + private javax.swing.JLabel lblByteToReal; + private javax.swing.JLabel lblCategory; + private javax.swing.JLabel lblConversion; + private javax.swing.JLabel lblDescription; + private javax.swing.JLabel lblEndian; + private javax.swing.JLabel lblRealToByte; + private javax.swing.JLabel lblStorage; + private javax.swing.JLabel lblStorageAddress; + private javax.swing.JLabel lblStorageSize; + private javax.swing.JLabel lblTable; + private javax.swing.JLabel lblUnit; + private javax.swing.JLabel realToByte; + private javax.swing.JLabel storageAddress; + private javax.swing.JLabel storageSize; + private javax.swing.JLabel tableName; + private javax.swing.JLabel unit; + // End of variables declaration//GEN-END:variables +} \ No newline at end of file diff --git a/src/enginuity/swing/TableToolBar.java b/src/enginuity/swing/TableToolBar.java new file mode 100644 index 00000000..9c151c5c --- /dev/null +++ b/src/enginuity/swing/TableToolBar.java @@ -0,0 +1,176 @@ +package enginuity.swing; + +import enginuity.swing.TableFrame; +import enginuity.maps.Table; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.text.DecimalFormat; +import java.text.ParseException; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JTextArea; +import javax.swing.JToolBar; +import javax.swing.KeyStroke; +import javax.swing.border.LineBorder; + +public class TableToolBar extends JToolBar implements MouseListener { + + private JButton incrementFine = new JButton(new ImageIcon("./graphics/icon-incfine.png")); + private JButton decrementFine = new JButton(new ImageIcon("./graphics/icon-decfine.png")); + private JButton incrementCoarse = new JButton(new ImageIcon("./graphics/icon-inccoarse.png")); + private JButton decrementCoarse = new JButton(new ImageIcon("./graphics/icon-deccoarse.png")); + private JButton setValue = new JButton("Set"); + + private JFormattedTextField incrementBy = new JFormattedTextField(new DecimalFormat("#")); + private JFormattedTextField setValueText = new JFormattedTextField(new DecimalFormat("#.####")); + + private Table table; + private TableFrame frame; + + public TableToolBar(Table table, TableFrame frame) { + this.table = table; + this.frame = frame; + this.setFloatable(false); + this.add(incrementFine); + this.add(decrementFine); + this.add(new JLabel(" ")); + this.add(incrementCoarse); + this.add(decrementCoarse); + this.add(new JLabel(" ")); + this.add(incrementBy); + this.add(new JLabel(" ")); + this.add(setValueText); + this.add(new JLabel(" ")); + this.add(setValue); + + incrementFine.setMaximumSize(new Dimension(33,33)); + incrementFine.setBorder(new LineBorder(new Color(150,150,150), 1)); + decrementFine.setMaximumSize(new Dimension(33,33)); + decrementFine.setBorder(new LineBorder(new Color(150,150,150), 1)); + incrementCoarse.setMaximumSize(new Dimension(33,33)); + incrementCoarse.setBorder(new LineBorder(new Color(150,150,150), 1)); + decrementCoarse.setMaximumSize(new Dimension(33,33)); + decrementCoarse.setBorder(new LineBorder(new Color(150,150,150), 1)); + setValue.setMaximumSize(new Dimension(33,23)); + setValue.setBorder(new LineBorder(new Color(150,150,150), 1)); + + incrementBy.setAlignmentX(JTextArea.CENTER_ALIGNMENT); + incrementBy.setAlignmentY(JTextArea.CENTER_ALIGNMENT); + incrementBy.setMaximumSize(new Dimension(45, 23)); + setValueText.setAlignmentX(JTextArea.CENTER_ALIGNMENT); + setValueText.setAlignmentY(JTextArea.CENTER_ALIGNMENT); + setValueText.setMaximumSize(new Dimension(45, 23)); + + incrementFine.setToolTipText("Increment Value (Fine)"); + decrementFine.setToolTipText("Decrement Value (Fine)"); + incrementCoarse.setToolTipText("Increment Value (Coarse)"); + decrementCoarse.setToolTipText("Decrement Value (Coarse)"); + setValue.setToolTipText("Set Absolute Value"); + setValueText.setToolTipText("Set Absolute Value"); + incrementBy.setToolTipText("Coarse Value Adjustment"); + + incrementFine.addMouseListener(this); + decrementFine.addMouseListener(this); + incrementCoarse.addMouseListener(this); + decrementCoarse.addMouseListener(this); + setValue.addMouseListener(this); + + incrementBy.setValue(Math.abs(table.getScale().getIncrement())); + + // key binding actions + Action enterAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + getTable().requestFocus(); + setValue(); + } + }; + + // set input mapping + InputMap im = getInputMap(this.WHEN_IN_FOCUSED_WINDOW); + + KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); + + im.put(enter, "enterAction"); + getActionMap().put(im.get(enter), enterAction); + + incrementFine.getInputMap().put(enter, "enterAction"); + decrementFine.getInputMap().put(enter, "enterAction"); + incrementCoarse.getInputMap().put(enter, "enterAction"); + decrementCoarse.getInputMap().put(enter, "enterAction"); + incrementBy.getInputMap().put(enter, "enterAction"); + setValueText.getInputMap().put(enter, "enterAction"); + setValue.getInputMap().put(enter, "enterAction"); + incrementFine.getInputMap().put(enter, "enterAction"); + } + + public Table getTable() { + return table; + } + + public void mouseClicked(MouseEvent e) { + if (e.getSource() == incrementCoarse) incrementCoarse(); + else if (e.getSource() == decrementCoarse) decrementCoarse(); + else if (e.getSource() == incrementFine) incrementFine(); + else if (e.getSource() == decrementFine) decrementFine(); + else if (e.getSource() == setValue) setValue(); + + table.colorize(); + } + + public void setValue() { + table.setRealValue(setValueText.getText()+""); + } + + + public void incrementFine() { + if (table.getScale().getIncrement() > 0) table.increment(1); + else table.increment(-1); + } + + public void decrementFine() { + if (table.getScale().getIncrement() > 0) table.increment(-1); + else table.increment(1); + } + + public void incrementCoarse() { + table.increment(Integer.parseInt(incrementBy.getValue()+"")); + } + + public void decrementCoarse() { + table.increment(0 - Integer.parseInt(incrementBy.getValue()+"")); + } + + public void setCoarseValue(int input) { + incrementBy.setText(input+""); + try { + incrementBy.commitEdit(); + } catch (ParseException ex) { } + } + + public void focusSetValue(char input) { + setValueText.requestFocus(); + setValueText.setText(input+""); + } + + public void setInputMap(InputMap im) { + incrementFine.setInputMap(this.WHEN_FOCUSED, im); + decrementFine.setInputMap(this.WHEN_FOCUSED, im); + incrementCoarse.setInputMap(this.WHEN_FOCUSED, im); + decrementCoarse.setInputMap(this.WHEN_FOCUSED, im); + setValue.setInputMap(this.WHEN_FOCUSED, im); + } + + public void mousePressed(MouseEvent e) { } + public void mouseReleased(MouseEvent e) { } + public void mouseEntered(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } +} \ No newline at end of file diff --git a/src/enginuity/swing/TableTreeNode.java b/src/enginuity/swing/TableTreeNode.java new file mode 100644 index 00000000..63872a14 --- /dev/null +++ b/src/enginuity/swing/TableTreeNode.java @@ -0,0 +1,56 @@ +package enginuity.swing; + +import enginuity.maps.Rom; +import enginuity.maps.Table; +import javax.swing.tree.DefaultMutableTreeNode; + +public class TableTreeNode extends DefaultMutableTreeNode { + + private String type; + private Rom rom; + private Table table; + private String toolTip; + private TableFrame frame; + + public TableTreeNode(Table table) { + super(table.getName() + " (" + table.getType() + "D)"); + this.table = table; + this.frame = table.getFrame(); + } + + public String getType() { + return type; + } + + public Rom getRom() { + return rom; + } + + public void setRom(Rom rom) { + this.rom = rom; + } + + public Table getTable() { + return table; + } + + public void setTable(Table table) { + this.table = table; + } + + public void setToolTipText(String input) { + toolTip = input; + } + + public String getToolTipText() { + return toolTip; + } + + public TableFrame getFrame() { + return frame; + } + + public void setFrame(TableFrame frame) { + this.frame = frame; + } +} \ No newline at end of file diff --git a/src/enginuity/swing/VTextIcon.java b/src/enginuity/swing/VTextIcon.java new file mode 100644 index 00000000..c51a3518 --- /dev/null +++ b/src/enginuity/swing/VTextIcon.java @@ -0,0 +1,296 @@ +package enginuity.swing; + +import java.awt.*; +import javax.swing.*; +import java.beans.*; + +/** + VTextIcon is an Icon implementation which draws a short string vertically. + It's useful for JTabbedPanes with LEFT or RIGHT tabs but can be used in any + component which supports Icons, such as JLabel or JButton + + You can provide a hint to indicate whether to rotate the string + to the left or right, or not at all, and it checks to make sure + that the rotation is legal for the given string + (for example, Chinese/Japanese/Korean scripts have special rules when + drawn vertically and should never be rotated) + */ +public class VTextIcon extends Component implements Icon, PropertyChangeListener { + String fLabel; + String[] fCharStrings; // for efficiency, break the fLabel into one-char strings to be passed to drawString + int[] fCharWidths; // Roman characters should be centered when not rotated (Japanese fonts are monospaced) + int[] fPosition; // Japanese half-height characters need to be shifted when drawn vertically + int fWidth, fHeight, fCharHeight, fDescent; // Cached for speed + int fRotation; + Component fComponent; + + static final int POSITION_NORMAL = 0; + static final int POSITION_TOP_RIGHT = 1; + static final int POSITION_FAR_TOP_RIGHT = 2; + + public static final int ROTATE_DEFAULT = 0x00; + public static final int ROTATE_NONE = 0x01; + public static final int ROTATE_LEFT = 0x02; + public static final int ROTATE_RIGHT = 0x04; + + /** + * Creates a VTextIcon for the specified component + * with the specified label. + * It sets the orientation to the default for the string + * @see #verifyRotation + */ + public VTextIcon(Component component, String label) { + this(component, label, ROTATE_DEFAULT); + } + + /** + * Creates a VTextIcon for the specified component + * with the specified label. + * It sets the orientation to the provided value if it's legal for the string + * @see #verifyRotation + */ + public VTextIcon(Component component, String label, int rotateHint) { + fComponent = component; + fLabel = label; + fRotation = verifyRotation(label, rotateHint); + calcDimensions(); + fComponent.addPropertyChangeListener(this); + } + + /** + * sets the label to the given string, updating the orientation as needed + * and invalidating the layout if the size changes + * @see #verifyRotation + */ + public void setLabel(String label) { + fLabel = label; + fRotation = verifyRotation(label, fRotation); // Make sure the current rotation is still legal + recalcDimensions(); + } + + /** + * Checks for changes to the font on the fComponent + * so that it can invalidate the layout if the size changes + */ + public void propertyChange(PropertyChangeEvent e) { + String prop = e.getPropertyName(); + if("font".equals(prop)) { + recalcDimensions(); + } + } + + /** + * Calculates the dimensions. If they've changed, + * invalidates the component + */ + void recalcDimensions() { + int wOld = getIconWidth(); + int hOld = getIconHeight(); + calcDimensions(); + if (wOld != getIconWidth() || hOld != getIconHeight()) + fComponent.invalidate(); + } + + void calcDimensions() { + FontMetrics fm = fComponent.getFontMetrics(fComponent.getFont()); + fCharHeight = fm.getAscent() + fm.getDescent(); + fDescent = fm.getDescent(); + if (fRotation == ROTATE_NONE) { + int len = fLabel.length(); + char data[] = new char[len]; + fLabel.getChars(0, len, data, 0); + // if not rotated, width is that of the widest char in the string + fWidth = 0; + // we need an array of one-char strings for drawString + fCharStrings = new String[len]; + fCharWidths = new int[len]; + fPosition = new int[len]; + char ch; + for (int i = 0; i < len; i++) { + ch = data[i]; + fCharWidths[i] = fm.charWidth(ch); + if (fCharWidths[i] > fWidth) + fWidth = fCharWidths[i]; + fCharStrings[i] = new String(data, i, 1); + // small kana and punctuation + if (sDrawsInTopRight.indexOf(ch) >= 0) // if ch is in sDrawsInTopRight + fPosition[i] = POSITION_TOP_RIGHT; + else if (sDrawsInFarTopRight.indexOf(ch) >= 0) + fPosition[i] = POSITION_FAR_TOP_RIGHT; + else + fPosition[i] = POSITION_NORMAL; + } + // and height is the font height * the char count, + one extra leading at the bottom + fHeight = fCharHeight * len + fDescent; + } + else { + // if rotated, width is the height of the string + fWidth = fCharHeight; + // and height is the width, plus some buffer space + fHeight = fm.stringWidth(fLabel) + 2*kBufferSpace; + } + } + + /** + * Draw the icon at the specified location. Icon implementations + * may use the Component argument to get properties useful for + * painting, e.g. the foreground or background color. + */ + public void paintIcon(Component c, Graphics g, int x, int y) { + // We don't insist that it be on the same Component + g.setColor(c.getForeground()); + g.setFont(c.getFont()); + if (fRotation == ROTATE_NONE) { + int yPos = y + fCharHeight; + for (int i = 0; i < fCharStrings.length; i++) { + // Special rules for Japanese - "half-height" characters (like ya, yu, yo in combinations) + // should draw in the top-right quadrant when drawn vertically + // - they draw in the bottom-left normally + int tweak; + switch (fPosition[i]) { + case POSITION_NORMAL: + // Roman fonts should be centered. Japanese fonts are always monospaced. + g.drawString(fCharStrings[i], x+((fWidth-fCharWidths[i])/2), yPos); + break; + case POSITION_TOP_RIGHT: + tweak = fCharHeight/3; // Should be 2, but they aren't actually half-height + g.drawString(fCharStrings[i], x+(tweak/2), yPos-tweak); + break; + case POSITION_FAR_TOP_RIGHT: + tweak = fCharHeight - fCharHeight/3; + g.drawString(fCharStrings[i], x+(tweak/2), yPos-tweak); + break; + } + yPos += fCharHeight; + } + } + else if (fRotation == ROTATE_LEFT) { + g.translate(x+fWidth,y+fHeight); + ((Graphics2D)g).rotate(-NINETY_DEGREES); + g.drawString(fLabel, kBufferSpace, -fDescent); + ((Graphics2D)g).rotate(NINETY_DEGREES); + g.translate(-(x+fWidth),-(y+fHeight)); + } + else if (fRotation == ROTATE_RIGHT) { + g.translate(x,y); + ((Graphics2D)g).rotate(NINETY_DEGREES); + g.drawString(fLabel, kBufferSpace, -fDescent); + ((Graphics2D)g).rotate(-NINETY_DEGREES); + g.translate(-x,-y); + } + + } + + /** + * Returns the icon's width. + * + * @return an int specifying the fixed width of the icon. + */ + public int getIconWidth() { + return fWidth; + } + + /** + * Returns the icon's height. + * + * @return an int specifying the fixed height of the icon. + */ + public int getIconHeight() { + return fHeight; + } + + /** + verifyRotation + + returns the best rotation for the string (ROTATE_NONE, ROTATE_LEFT, ROTATE_RIGHT) + + This is public static so you can use it to test a string without creating a VTextIcon + + from http://www.unicode.org/unicode/reports/tr9/tr9-3.html + When setting text using the Arabic script in vertical lines, + it is more common to employ a horizontal baseline that + is rotated by 90¡ counterclockwise so that the characters + are ordered from top to bottom. Latin text and numbers + may be rotated 90¡ clockwise so that the characters + are also ordered from top to bottom. + + Rotation rules + - Roman can rotate left, right, or none - default right (counterclockwise) + - CJK can't rotate + - Arabic must rotate - default left (clockwise) + + from the online edition of _The Unicode Standard, Version 3.0_, file ch10.pdf page 4 + Ideographs are found in three blocks of the Unicode Standard... + U+4E00-U+9FFF, U+3400-U+4DFF, U+F900-U+FAFF + + Hiragana is U+3040-U+309F, katakana is U+30A0-U+30FF + + from http://www.unicode.org/unicode/faq/writingdirections.html + East Asian scripts are frequently written in vertical lines + which run from top-to-bottom and are arrange columns either + from left-to-right (Mongolian) or right-to-left (other scripts). + Most characters use the same shape and orientation when displayed + horizontally or vertically, but many punctuation characters + will change their shape when displayed vertically. + + Letters and words from other scripts are generally rotated through + ninety degree angles so that they, too, will read from top to bottom. + That is, letters from left-to-right scripts will be rotated clockwise + and letters from right-to-left scripts counterclockwise, both + through ninety degree angles. + + Unlike the bidirectional case, the choice of vertical layout + is usually treated as a formatting style; therefore, + the Unicode Standard does not define default rendering behavior + for vertical text nor provide directionality controls designed to override such behavior + + */ + public static int verifyRotation(String label, int rotateHint) { + boolean hasCJK = false; + boolean hasMustRotate = false; // Arabic, etc + + int len = label.length(); + char data[] = new char[len]; + char ch; + label.getChars(0, len, data, 0); + for (int i = 0; i < len; i++) { + ch = data[i]; + if ((ch >= '\u4E00' && ch <= '\u9FFF') || + (ch >= '\u3400' && ch <= '\u4DFF') || + (ch >= '\uF900' && ch <= '\uFAFF') || + (ch >= '\u3040' && ch <= '\u309F') || + (ch >= '\u30A0' && ch <= '\u30FF') ) + hasCJK = true; + if ((ch >= '\u0590' && ch <= '\u05FF') || // Hebrew + (ch >= '\u0600' && ch <= '\u06FF') || // Arabic + (ch >= '\u0700' && ch <= '\u074F') ) // Syriac + hasMustRotate = true; + } + // If you mix Arabic with Chinese, you're on your own + if (hasCJK) + return DEFAULT_CJK; + + int legal = hasMustRotate ? LEGAL_MUST_ROTATE : LEGAL_ROMAN; + if ((rotateHint & legal) > 0) + return rotateHint; + + // The hint wasn't legal, or it was zero + return hasMustRotate ? DEFAULT_MUST_ROTATE : DEFAULT_ROMAN; + } + + // The small kana characters and Japanese punctuation that draw in the top right quadrant: + // small a, i, u, e, o, tsu, ya, yu, yo, wa (katakana only) ka ke + static final String sDrawsInTopRight = + "\u3041\u3043\u3045\u3047\u3049\u3063\u3083\u3085\u3087\u308E" + // hiragana + "\u30A1\u30A3\u30A5\u30A7\u30A9\u30C3\u30E3\u30E5\u30E7\u30EE\u30F5\u30F6"; // katakana + static final String sDrawsInFarTopRight = "\u3001\u3002"; // comma, full stop + + static final int DEFAULT_CJK = ROTATE_NONE; + static final int LEGAL_ROMAN = ROTATE_NONE | ROTATE_LEFT | ROTATE_RIGHT; + static final int DEFAULT_ROMAN = ROTATE_RIGHT; + static final int LEGAL_MUST_ROTATE = ROTATE_LEFT | ROTATE_RIGHT; + static final int DEFAULT_MUST_ROTATE = ROTATE_LEFT; + + static final double NINETY_DEGREES = Math.toRadians(90.0); + static final int kBufferSpace = 5; +} diff --git a/src/enginuity/swing/XMLFilter.java b/src/enginuity/swing/XMLFilter.java new file mode 100644 index 00000000..b2881c4f --- /dev/null +++ b/src/enginuity/swing/XMLFilter.java @@ -0,0 +1,90 @@ +package enginuity.swing; + +import java.io.File; +import java.util.Hashtable; +import java.util.Enumeration; +import javax.swing.*; +import javax.swing.filechooser.*; + +public class XMLFilter extends FileFilter { + + private static String TYPE_UNKNOWN = "Type Unknown"; + private static String HIDDEN_FILE = "Hidden File"; + + private Hashtable filters = null; + private String description = null; + private String fullDescription = null; + private boolean useExtensionsInDescription = true; + + public XMLFilter() { + this.filters = new Hashtable(); + this.addExtension("xml"); + this.setDescription("ECU Definition Files"); + } + + public boolean accept(File f) { + if(f != null) { + if(f.isDirectory()) { + return true; + } + String extension = getExtension(f); + if(extension != null && filters.get(getExtension(f)) != null) { + return true; + }; + } + return false; + } + + public String getExtension(File f) { + if(f != null) { + String filename = f.getName(); + int i = filename.lastIndexOf('.'); + if(i>0 && i 2 && input.substring(0,2).equalsIgnoreCase("0x")) { + return Integer.parseInt(input.substring(2), 16); + } else { + return Integer.parseInt(input, 16); + } + } + + public static int parseStorageType(String input) { + try { + return Integer.parseInt(input.substring(4)) / 8; + } catch (Exception ex) { + return Integer.parseInt(input); + } + } + + public static int parseScaleType(String input) { + if (input.equalsIgnoreCase("inverse")) { + return Scale.INVERSE; + } else { + return Scale.LINEAR; + } + } + + public static int parseTableType(String input) { + if (input.equalsIgnoreCase("3D") || input.equalsIgnoreCase(Table.TABLE_3D+"")) { + return Table.TABLE_3D; + } else if (input.equalsIgnoreCase("2D") || input.equalsIgnoreCase(Table.TABLE_2D+"")) { + return Table.TABLE_2D; + } else if (input.equalsIgnoreCase("X Axis") || input.equalsIgnoreCase("Static X Axis") || input.equalsIgnoreCase(Table.TABLE_X_AXIS+"")) { + return Table.TABLE_X_AXIS; + } else if (input.equalsIgnoreCase("Y Axis") || input.equalsIgnoreCase("Static Y Axis") || input.equalsIgnoreCase(Table.TABLE_Y_AXIS+"")) { + return Table.TABLE_Y_AXIS; + } else { + return Table.TABLE_1D; + } + } + + public static int parseByteValue(byte[] input, int endian, int address, int length) throws ArrayIndexOutOfBoundsException { + try { + int output = 0; + if (endian == Table.ENDIAN_BIG) { + for (int i = 0; i < length; i++) { + output += (input[address + i] & 0xff) << 8 * (length - i - 1); + } + } else { // little endian + for (int i = 0; i < length; i++) { + output += (input[address + length - i - 1] & 0xff) << 8 * (length - i - 1); + } + } + return output; + } catch (ArrayIndexOutOfBoundsException ex) { + throw new ArrayIndexOutOfBoundsException(); + } + } + + public static byte[] parseIntegerValue(int input, int endian, int length) { + byte[] byteArray = new byte[4]; + + byteArray[0] = (byte)((input >> 24) & 0x000000FF); + byteArray[1] = (byte)((input >> 16) & 0x0000FF); + byteArray[2] = (byte)((input >> 8) & 0x00FF); + byteArray[3] = (byte)(input & 0xFF ); + + byte[] output = new byte[length]; + + for (int i = 0; i < length; i++) { + if (endian == Table.ENDIAN_BIG) { + //output[i] = byteArray[i + length]; + output[i] = byteArray[4 - length + i]; + } else { // little endian + output[length - 1 - i] = byteArray[4 - length + i]; + } + } + return output; + } + + public static int parseFileSize(String input) throws NumberFormatException { + try { + return Integer.parseInt(input); + } catch (NumberFormatException ex) { + if (input.substring(input.length() - 2).equalsIgnoreCase("kb")) { + return Integer.parseInt(input.substring(0, input.length() - 2)) * 1024; + } else if (input.substring(input.length() - 2).equalsIgnoreCase("mb")) { + return Integer.parseInt(input.substring(0, input.length() - 2)) * 1024 * 1024; + } + throw new NumberFormatException(); + } + } + + //public static boolean parseBoolean +} \ No newline at end of file diff --git a/src/enginuity/xml/RomNotFoundException.java b/src/enginuity/xml/RomNotFoundException.java new file mode 100644 index 00000000..136670ba --- /dev/null +++ b/src/enginuity/xml/RomNotFoundException.java @@ -0,0 +1,7 @@ +package enginuity.xml; + +public class RomNotFoundException extends Exception { + + public RomNotFoundException() { + } +} \ No newline at end of file diff --git a/src/enginuity/xml/TableIsOmittedException.java b/src/enginuity/xml/TableIsOmittedException.java new file mode 100644 index 00000000..366dcd8c --- /dev/null +++ b/src/enginuity/xml/TableIsOmittedException.java @@ -0,0 +1,6 @@ +package enginuity.xml; + +public class TableIsOmittedException extends Exception { + + public TableIsOmittedException() { } +} \ No newline at end of file diff --git a/src/enginuity/xml/TableNotFoundException.java b/src/enginuity/xml/TableNotFoundException.java new file mode 100644 index 00000000..bf0e7e2a --- /dev/null +++ b/src/enginuity/xml/TableNotFoundException.java @@ -0,0 +1,3 @@ +package enginuity.xml; + +public class TableNotFoundException extends Exception { } \ No newline at end of file