Added DebugId tag proper display and editation

This commit is contained in:
Jindra Petřík
2022-12-03 22:22:08 +01:00
parent 537d1b3adb
commit 19eafbf43e
5 changed files with 224 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- [#1884] Memory search - show size and adress in hex, show only aligned to N bytes
- AS3 - "internal" keyword support
- ProductInfo tag information display
- DebugId tag proper display and editation
### Fixed
- [#1897] Close menu button without selecting specific item

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
import com.jpexs.decompiler.flash.types.annotations.UUID;
import com.jpexs.helpers.ByteArrayRange;
import java.io.IOException;
import java.util.logging.Level;
@@ -39,6 +40,7 @@ public class DebugIDTag extends Tag {
public static final String NAME = "DebugID";
@SWFType(value = BasicType.UI8, count = 16)
@UUID
public byte[] debugId;
/**

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2010-2022 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.types.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface UUID {
}

View File

@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.gui.generictageditors.FullSized;
import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor;
import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor;
import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor;
import com.jpexs.decompiler.flash.gui.generictageditors.UUIDEditor;
import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
@@ -50,6 +51,7 @@ import com.jpexs.decompiler.flash.types.annotations.Multiline;
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.annotations.Table;
import com.jpexs.decompiler.flash.types.annotations.UUID;
import com.jpexs.decompiler.flash.types.annotations.parser.AnnotationParseException;
import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator;
import com.jpexs.helpers.ByteArrayRange;
@@ -300,9 +302,13 @@ public class GenericTagTreePanel extends GenericTagPanel {
swfType = evalSwfType(model, parentPath, swfType);
UUID uuid = field.getAnnotation(UUID.class);
Multiline multiline = field.getAnnotation(Multiline.class);
EnumValues enumValues = field.getAnnotation(EnumValues.class);
if (enumValues != null && (type.equals(int.class) || type.equals(Integer.class))) {
if (uuid != null) {
editor = new UUIDEditor(field.getName(), obj, field, index, type);
} else if (enumValues != null && (type.equals(int.class) || type.equals(Integer.class))) {
Map<Integer, String> values = new HashMap<>();
for (EnumValue enumValue : enumValues.value()) {
values.put(enumValue.value(), enumValue.text());
@@ -727,7 +733,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
}
return ret.toString();
}
if (fieldSet.size() == 1) {
ret.append(toString(0));
} else {
@@ -747,7 +753,22 @@ public class GenericTagTreePanel extends GenericTagPanel {
public String toString(int fieldIndex) {
String valStr = "";
Field field = fieldSet.get(fieldIndex);
if (ReflectionTools.needsIndex(field) && (index == -1)) {
if (field.getAnnotation(UUID.class) != null) {
StringBuilder sb = new StringBuilder();
byte[] val = (byte[]) getValue(fieldIndex);
for(int i = 0; i < val.length; i++) {
String h = Integer.toHexString(val[i] & 0xff);
if (h.length() == 1) {
h = "0" + h;
}
sb.append(h);
if (i == 3 || i == 5 || i == 7 || i == 9) {
sb.append("-");
}
}
valStr += " = " + sb.toString();
} else if (ReflectionTools.needsIndex(field) && (index == -1)) {
valStr += "";
} else if (hasEditor(obj, field, index)) {
Object val = getValue(fieldIndex);
@@ -787,6 +808,10 @@ public class GenericTagTreePanel extends GenericTagPanel {
}
public String getType(int fieldIndex) {
UUID uuid = fieldSet.get(fieldIndex).getAnnotation(UUID.class);
if (uuid != null) {
return "UUID";
}
SWFArray swfArray = fieldSet.get(fieldIndex).getAnnotation(SWFArray.class);
Class<?> declaredType = fieldSet.get(fieldIndex).getType();
boolean isArray = ReflectionTools.needsIndex(fieldSet.get(fieldIndex)) || swfArray != null;
@@ -1214,8 +1239,12 @@ public class GenericTagTreePanel extends GenericTagPanel {
type = val.getClass();
} catch (IllegalArgumentException | IllegalAccessException ex) {
return false;
}
if (type.equals(int.class) || type.equals(Integer.class)
}
UUID uuid = field.getAnnotation(UUID.class);
if (uuid != null) {
return true;
} else if (type.equals(int.class) || type.equals(Integer.class)
|| type.equals(short.class) || type.equals(Short.class)
|| type.equals(long.class) || type.equals(Long.class)
|| type.equals(double.class) || type.equals(Double.class)

View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2010-2022 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui.generictageditors;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ReflectionTools;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.lang.reflect.Field;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
*
* @author JPEXS
*/
public class UUIDEditor extends JTextField implements GenericTagEditor {
private final Object obj;
private final Field field;
private final int index;
private final Class<?> type;
private String fieldName;
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public Dimension getPreferredSize() {
Dimension ret = super.getPreferredSize();
ret.width = 300;
return ret;
}
@Override
public BaselineResizeBehavior getBaselineResizeBehavior() {
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
@Override
public int getBaseline(int width, int height) {
return 0;
}
public UUIDEditor(String fieldName, Object obj, Field field, int index, Class<?> type) {
super(32+4);
this.obj = obj;
this.field = field;
this.index = index;
this.type = type;
this.fieldName = fieldName;
reset();
}
@Override
public void reset() {
try {
byte[] val = (byte[]) ReflectionTools.getValue(obj, field, index);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < val.length; i++) {
String h = Integer.toHexString(val[i] & 0xff);
if (h.length() == 1) {
h = "0" + h;
}
sb.append(h);
if (i == 3 || i == 5 || i == 7 || i == 9) {
sb.append("-");
}
}
setText(sb.toString());
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
}
}
@Override
public void save() {
try {
String text = getText();
text = text.replace("-", "").trim();
if (!text.matches("[a-fA-F0-9]{32}")) {
return;
}
byte[] val = new byte[16];
for (int i = 0; i < 16; i++) {
String ch = text.substring(i * 2, i * 2 + 2);
val[i] = (byte) Integer.parseInt(ch, 16);
}
ReflectionTools.setValue(obj, field, index, val);
} catch (IllegalAccessException ex) {
// ignore
}
}
@Override
public void addChangeListener(final ChangeListener l) {
final GenericTagEditor t = this;
addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
l.change(t);
}
});
}
@Override
public Object getChangedValue() {
return getText();
}
@Override
public String getFieldName() {
return fieldName;
}
@Override
public Field getField() {
return field;
}
@Override
public String getReadOnlyValue() {
return Helper.escapeHTML(getChangedValue().toString());
}
@Override
public void added() {
}
@Override
public void validateValue() {
}
}