mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 07:10:46 +00:00
generic tag editor: disable instantiation of abstract classes, make Action list related types not editable (it does not work yet)
This commit is contained in:
@@ -61,6 +61,7 @@ import javax.swing.AbstractCellEditor;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
@@ -242,6 +243,11 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
itemStr = AppStrings.translate("generictag.array.item");
|
||||
}
|
||||
if (ReflectionTools.needsIndex(fnode.field)) {
|
||||
|
||||
boolean canAdd = true;
|
||||
if (!ReflectionTools.canAddToField(fnode.obj, fnode.field)) {
|
||||
canAdd = false;
|
||||
}
|
||||
JPopupMenu p = new JPopupMenu();
|
||||
JMenuItem mi;
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.insertbeginning").replace("%item%", itemStr));
|
||||
@@ -252,6 +258,9 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
addItem(fnode.obj, fnode.field, 0);
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
|
||||
if (fnode.index > -1) {
|
||||
@@ -263,6 +272,9 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
addItem(fnode.obj, fnode.field, fnode.index);
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.remove").replace("%item%", itemStr));
|
||||
@@ -283,6 +295,9 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
addItem(fnode.obj, fnode.field, fnode.index + 1);
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
}
|
||||
|
||||
@@ -294,6 +309,9 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
addItem(fnode.obj, fnode.field, ReflectionTools.getFieldSubSize(fnode.obj, fnode.field));
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
//}
|
||||
p.show(tree, e.getX(), e.getY());
|
||||
@@ -789,12 +807,21 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
SWFArray swfArray = field.getAnnotation(SWFArray.class);
|
||||
if (swfArray != null && !swfArray.countField().equals("")) { //Fields with same countField must be enlarged too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
List<Integer> sameFlds = new ArrayList<>();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class);
|
||||
if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) {
|
||||
ReflectionTools.addToField(obj, fields[f], index, true);
|
||||
sameFlds.add(f);
|
||||
if (!ReflectionTools.canAddToField(obj, fields[f])) {
|
||||
JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!!
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (int f : sameFlds) {
|
||||
ReflectionTools.addToField(obj, fields[f], index, true);
|
||||
}
|
||||
try {
|
||||
//If countField exists, increment, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfArray.countField());
|
||||
@@ -807,6 +834,10 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
if (!ReflectionTools.canAddToField(obj, field)) {
|
||||
JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!!
|
||||
return;
|
||||
}
|
||||
ReflectionTools.addToField(obj, field, index, true);
|
||||
}
|
||||
refreshTree();
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui.generictageditors;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@@ -85,6 +86,42 @@ public class ReflectionTools {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canInstantiate(Class cls) {
|
||||
if (cls.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
if (Modifier.isAbstract(cls.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean canAddToField(Object object, Field field) {
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
|
||||
ParameterizedType listType = (ParameterizedType) field.getGenericType();
|
||||
Class<?> parameterClass = (Class<?>) listType.getActualTypeArguments()[0];
|
||||
return canInstantiate(parameterClass);
|
||||
}
|
||||
|
||||
if (field.getType().isArray()) {
|
||||
Object arrValue;
|
||||
try {
|
||||
arrValue = field.get(object);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
Class componentClass = arrValue.getClass().getComponentType();
|
||||
if (componentClass.isPrimitive()) {
|
||||
return true;
|
||||
}
|
||||
return canInstantiate(componentClass);
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static Object newInstanceOf(Class cls) throws InstantiationException, IllegalAccessException {
|
||||
if (cls == Integer.class || cls == int.class) {
|
||||
return new Integer(0);
|
||||
@@ -95,6 +132,12 @@ public class ReflectionTools {
|
||||
} else if (cls == Long.class || cls == long.class) {
|
||||
return new Long(0L);
|
||||
}
|
||||
if (cls.isInterface()) {
|
||||
return null;
|
||||
}
|
||||
if (Modifier.isAbstract(cls.getModifiers())) {
|
||||
return null;
|
||||
}
|
||||
return cls.newInstance();
|
||||
}
|
||||
|
||||
@@ -114,6 +157,9 @@ public class ReflectionTools {
|
||||
Class<?> parameterClass = (Class<?>) listType.getActualTypeArguments()[0];
|
||||
try {
|
||||
Object val = newInstanceOf(parameterClass);
|
||||
if (val == null) {
|
||||
return false;
|
||||
}
|
||||
list.add(index, val);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
@@ -151,19 +197,28 @@ public class ReflectionTools {
|
||||
return false;
|
||||
}
|
||||
Class componentClass = arrValue.getClass().getComponentType();
|
||||
int originalSize = Array.getLength(arrValue);
|
||||
Object copy = Array.newInstance(componentClass, originalSize + 1);
|
||||
//Copy items before
|
||||
for (int i = 0; i < index; i++) {
|
||||
Array.set(copy, i, Array.get(arrValue, i));
|
||||
}
|
||||
Object val = null;
|
||||
if (!componentClass.isPrimitive()) {
|
||||
try {
|
||||
Array.set(copy, index, componentClass.newInstance());
|
||||
val = newInstanceOf(componentClass);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
if (val == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int originalSize = Array.getLength(arrValue);
|
||||
Object copy = Array.newInstance(componentClass, originalSize + 1);
|
||||
|
||||
//Copy items before
|
||||
for (int i = 0; i < index; i++) {
|
||||
Array.set(copy, i, Array.get(arrValue, i));
|
||||
}
|
||||
if (val != null) {
|
||||
Array.set(copy, index, val);
|
||||
}
|
||||
//Copy items after
|
||||
for (int i = index; i < originalSize; i++) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -123,6 +124,7 @@ public class PlaceObject2Tag extends CharacterIdTag implements Container, PlaceO
|
||||
* @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
|
||||
*/
|
||||
@Conditional("placeFlagHasClipActions")
|
||||
@Internal //TODO: make editable
|
||||
public CLIPACTIONS clipActions;
|
||||
public static final int ID = 26;
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@ public class PlaceObject3Tag extends CharacterIdTag implements Container, PlaceO
|
||||
* @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
|
||||
*/
|
||||
@Conditional(value = "placeFlagHasClipActions", minSwfVersion = 5)
|
||||
@Internal //TODO: make editable
|
||||
public CLIPACTIONS clipActions;
|
||||
/**
|
||||
* If PlaceFlagHasVisible, 0 = Place invisible, 1 = Place visible
|
||||
|
||||
@@ -181,6 +181,7 @@ public class PlaceObject4Tag extends CharacterIdTag implements Container, PlaceO
|
||||
* @since SWF 5 If PlaceFlagHasClipActions, Clip Actions Data
|
||||
*/
|
||||
@Conditional(value = "placeFlagHasClipActions", minSwfVersion = 5)
|
||||
@Internal //TODO: make editable
|
||||
public CLIPACTIONS clipActions;
|
||||
/**
|
||||
* If PlaceFlagHasVisible, 0 = Place invisible, 1 = Place visible
|
||||
|
||||
@@ -95,6 +95,14 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem, S
|
||||
@Internal
|
||||
private long hdrPos;
|
||||
|
||||
//Constructor for Generic tag editor. TODO:Handle this somehow better
|
||||
public CLIPACTIONRECORD(){
|
||||
swf = null;
|
||||
eventFlags = new CLIPEVENTFLAGS();
|
||||
actionBytes = new byte[0];
|
||||
hdrPos = 0;
|
||||
}
|
||||
|
||||
public CLIPACTIONRECORD(SWF swf, InputStream is, int version, long pos) throws IOException {
|
||||
this.swf = swf;
|
||||
SWFInputStream sis = new SWFInputStream(is, version);
|
||||
|
||||
Reference in New Issue
Block a user