From ab772df38008aa5656dc2a2083235f01c5d75ea1 Mon Sep 17 00:00:00 2001 From: honfika Date: Sun, 22 Jun 2014 19:31:26 +0200 Subject: [PATCH] highlight current node in dump view --- .../decompiler/flash/SWFInputStream.java | 8 +- .../decompiler/flash/gui/DumpViewPanel.java | 150 ++++++++++++++---- 2 files changed, 127 insertions(+), 31 deletions(-) diff --git a/src/com/jpexs/decompiler/flash/SWFInputStream.java b/src/com/jpexs/decompiler/flash/SWFInputStream.java index deadb555a..4798ed825 100644 --- a/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -364,7 +364,11 @@ public class SWFInputStream implements AutoCloseable { private void newDumpLevel(String name, String type) { if (dumpInfo != null) { - DumpInfo di = new DumpInfo(name, type, null, is.getPos(), bitPos, 0, 0); + long startByte = is.getPos(); + if (bitPos > 0) { + startByte--; + } + DumpInfo di = new DumpInfo(name, type, null, startByte, bitPos, 0, 0); di.parent = dumpInfo; dumpInfo.childInfos.add(di); dumpInfo = di; @@ -380,7 +384,7 @@ public class SWFInputStream implements AutoCloseable { if (dumpInfo.startBit == 0 && bitPos == 0) { dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte; } else { - dumpInfo.lengthBits = (int) ((is.getPos() - dumpInfo.startByte - (dumpInfo.startBit == 0 ? 1 : 0)) * 8 - dumpInfo.startBit + bitPos); + dumpInfo.lengthBits = (int) ((is.getPos() - dumpInfo.startByte - 1) * 8 - dumpInfo.startBit + (bitPos == 0 ? 8 : bitPos)); } dumpInfo.previewValue = value; dumpInfo = dumpInfo.parent; diff --git a/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java index 5ec487ee8..cd9c81e82 100644 --- a/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java @@ -19,13 +19,20 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.dumpview.DumpInfo; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; import java.awt.Font; +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; +import javax.swing.JViewport; import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; @@ -40,31 +47,48 @@ public class DumpViewPanel extends JPanel { private final JLabel dumpViewLabel; private final JTable dumpViewHexTable; private byte[] data; + private DumpInfo[] dumpInfos; + private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"}; + private final Color[] highlightColors; + public class HighlightCellRenderer extends DefaultTableCellRenderer { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { + + JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + int idx = row * bytesInRow + col - 1; + int level = -1; + for (int i = 0; i < dumpInfos.length; i++) { + DumpInfo di = dumpInfos[i]; + if (di.startByte <= idx && getEndIndex(di) >= idx) { + level++; + } else { + break; + } + } + if (level > -1) { + l.setBackground(highlightColors[level % highlightColors.length]); + } else { + l.setBackground(Color.white); + } + return l; + } + } + public DumpViewPanel() { super(new BorderLayout()); + highlightColors = new Color[highlightColorsStr.length]; + for (int i = 0; i < highlightColors.length; i++) { + highlightColors[i] = Color.decode("#" + highlightColorsStr[i]); + } + dumpViewLabel = new JLabel(); dumpViewLabel.setMinimumSize(new Dimension(100, 20)); add(dumpViewLabel, BorderLayout.SOUTH); dumpViewHexTable = new JTable(); - dumpViewHexTable.setBackground(Color.white); - dumpViewHexTable.setFont(new Font("Monospaced", Font.PLAIN, 12)); - dumpViewHexTable.setTableHeader(new JTableHeader()); - dumpViewHexTable.setMaximumSize(new Dimension(200, 200)); - TableColumnModel columnModel = dumpViewHexTable.getColumnModel(); - columnModel.addColumn(new TableColumn()); - columnModel.getColumn(0).setMinWidth(100); - for (int i = 0; i < bytesInRow; i++) { - columnModel.addColumn(new TableColumn()); - columnModel.getColumn(i + 1).setWidth(20); - } - for (int i = 0; i < bytesInRow; i++) { - columnModel.addColumn(new TableColumn()); - columnModel.getColumn(i + bytesInRow + 1).setWidth(10); - } - dumpViewHexTable.setShowHorizontalLines(false); dumpViewHexTable.setModel(new AbstractTableModel() { @Override @@ -114,30 +138,98 @@ public class DumpViewPanel extends JPanel { } } }); + + dumpViewHexTable.setBackground(Color.white); + dumpViewHexTable.setFont(new Font("Monospaced", Font.PLAIN, 12)); + dumpViewHexTable.setTableHeader(new JTableHeader()); + dumpViewHexTable.setMaximumSize(new Dimension(200, 200)); + + dumpViewHexTable.setShowHorizontalLines(false); + dumpViewHexTable.setShowVerticalLines(false); + + HighlightCellRenderer cellRenderer = new HighlightCellRenderer(); + TableColumnModel columnModel = dumpViewHexTable.getColumnModel(); + columnModel.getColumn(0).setMaxWidth(80); + for (int i = 0; i < bytesInRow; i++) { + TableColumn column = columnModel.getColumn(i + 1); + column.setMaxWidth(25); + column.setCellRenderer(cellRenderer); + } + for (int i = 0; i < bytesInRow; i++) { + TableColumn column = columnModel.getColumn(i + bytesInRow + 1); + column.setMaxWidth(10); + } + add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER); } + public static void scrollToVisible(JTable table, int rowIndex, int vColIndex) { + if (!(table.getParent() instanceof JViewport)) { + return; + } + JViewport viewport = (JViewport)table.getParent(); + + // This rectangle is relative to the table where the + // northwest corner of cell (0,0) is always (0,0). + Rectangle rect = table.getCellRect(rowIndex, vColIndex, true); + + // The location of the viewport relative to the table + Point pt = viewport.getViewPosition(); + + // Translate the cell location so that it is relative + // to the view, assuming the northwest corner of the + // view is (0,0) + rect.setLocation(rect.x-pt.x, rect.y-pt.y); + + table.scrollRectToVisible(rect); + + // Scroll the area into view + //viewport.scrollRectToVisible(rect); + } + + private int getEndIndex(DumpInfo dumpInfo) { + int end = (int) dumpInfo.startByte; + if (dumpInfo.lengthBytes != 0) { + end += dumpInfo.lengthBytes; + } else { + int bits = dumpInfo.startBit + dumpInfo.lengthBits; + end += bits / 8; + if (bits % 8 != 0) { + end++; + } + } + return end - 1; + } + public void setData(byte[] data, DumpInfo dumpInfo) { this.data = data; + List dumpInfos = new ArrayList<>(); + DumpInfo di = dumpInfo; + while (di.parent != null) { + dumpInfos.add(di); + di = di.parent; + } + DumpInfo[] dumpInfos1 = new DumpInfo[dumpInfos.size()]; + for (int i = 0; i < dumpInfos1.length; i++) { + dumpInfos1[i] = dumpInfos.get(dumpInfos1.length - i - 1); + } + this.dumpInfos = dumpInfos1; if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) { - // todo - int end = (int) dumpInfo.startByte; - if (dumpInfo.lengthBytes != 0) { - end += dumpInfo.lengthBytes; - } else { - int bits = dumpInfo.startBit + dumpInfo.lengthBits; - end += bits / 8; - if (bits % 8 != 0) { - end++; - } - } - //setSelectedRange((int) dumpInfo.startByte, end - 1); + int selectionStart = (int) dumpInfo.startByte; + int selectionEnd = getEndIndex(dumpInfo); + //setSelectedRange(selectionStart, end - 1); setLabelText("startByte: " + dumpInfo.startByte + " startBit: " + dumpInfo.startBit + " lengthBytes: " + dumpInfo.lengthBytes - + " lengthBits: " + dumpInfo.lengthBits); + + " lengthBits: " + dumpInfo.lengthBits + + " selectionStart: " + selectionStart + + " selectionEnd: " + selectionEnd); } + + scrollToVisible(dumpViewHexTable, (int) (dumpInfo.startByte / bytesInRow), 0); + + repaint(); } public void setLabelText(String text) {