mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-03 17:45:24 +00:00
Added #1901 Editor mode and autosave feature for header, raw editor, transform
This commit is contained in:
@@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file.
|
||||
("PNG/GIF/JPEG+alpha" option in GUI, "-format image:png_gif_jpeg_alpha" for commandline)
|
||||
- [#1910] Copy/paste transform matrix to/from the clipboard
|
||||
- [#1912] Persist selected item in the tree upon quick search (Ctrl+F)
|
||||
- [#1901] Editor mode for raw edit
|
||||
- [#1901] Editor mode and autosave feature for header, raw editor, transform
|
||||
|
||||
### Fixed
|
||||
- [#1904] NullPointerException when renaming invalid identifiers in AS1/2 files caused by missing charset
|
||||
|
||||
@@ -67,7 +67,7 @@ import layout.TableLayout;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FontPanel extends JPanel {
|
||||
public class FontPanel extends JPanel implements TagEditorPanel {
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
@@ -110,6 +110,7 @@ public class FontPanel extends JPanel {
|
||||
return new DefaultComboBoxModel<>(new Vector<>(faceSet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditing() {
|
||||
return saveButton.isVisible();
|
||||
}
|
||||
@@ -861,4 +862,13 @@ public class FontPanel extends JPanel {
|
||||
private JPanel contentPanel;
|
||||
|
||||
private JScrollPane contentScrollPane;
|
||||
|
||||
@Override
|
||||
public boolean tryAutoSave() {
|
||||
if (Configuration.autoSaveTagModifications.get()) {
|
||||
saveButtonActionPerformed(null);
|
||||
return !(saveButton.isVisible() && saveButton.isEnabled());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.amf.amf3.Amf3Value;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.Amf3ValueEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.BinaryDataEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor;
|
||||
@@ -71,550 +72,25 @@ import javax.swing.SpringLayout;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(GenericTagPanel.class.getName());
|
||||
public abstract class GenericTagPanel extends JPanel {
|
||||
|
||||
protected final MainPanel mainPanel;
|
||||
|
||||
private final JEditorPane genericTagPropertiesEditorPane;
|
||||
|
||||
private final JPanel genericTagPropertiesEditPanel;
|
||||
|
||||
private final JScrollPane genericTagPropertiesEditorPaneScrollPanel;
|
||||
|
||||
private final JScrollPane genericTagPropertiesEditPanelScrollPanel;
|
||||
|
||||
private Tag tag;
|
||||
|
||||
private Tag editedTag;
|
||||
|
||||
private List<String> keys = new ArrayList<>();
|
||||
|
||||
private Map<String, GenericTagEditor> editors = new HashMap<>();
|
||||
|
||||
private Map<String, Component> labels = new HashMap<>();
|
||||
|
||||
private Map<String, Component> types = new HashMap<>();
|
||||
|
||||
private Map<String, List<Field>> fieldPaths = new HashMap<>();
|
||||
|
||||
private Map<String, List<Integer>> fieldIndices = new HashMap<>();
|
||||
|
||||
private HeaderLabel hdr;
|
||||
|
||||
private Set<String> addKeys = new HashSet<>();
|
||||
|
||||
private Map<String, Component> addButtons = new HashMap<>();
|
||||
|
||||
private Map<String, Component> removeButtons = new HashMap<>();
|
||||
|
||||
public GenericTagPanel(MainPanel mainPanel) {
|
||||
super(new BorderLayout());
|
||||
|
||||
this.mainPanel = mainPanel;
|
||||
hdr = new HeaderLabel("");
|
||||
add(hdr, BorderLayout.NORTH);
|
||||
genericTagPropertiesEditorPane = new JEditorPane() {
|
||||
@Override
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
genericTagPropertiesEditorPane.setEditable(false);
|
||||
genericTagPropertiesEditorPaneScrollPanel = new FasterScrollPane(genericTagPropertiesEditorPane);
|
||||
add(genericTagPropertiesEditorPaneScrollPanel, BorderLayout.CENTER);
|
||||
|
||||
genericTagPropertiesEditPanel = new JPanel();
|
||||
genericTagPropertiesEditPanel.setLayout(new SpringLayout());
|
||||
JPanel edPanel = new JPanel(new BorderLayout());
|
||||
edPanel.add(genericTagPropertiesEditPanel, BorderLayout.NORTH);
|
||||
genericTagPropertiesEditPanelScrollPanel = new FasterScrollPane(edPanel);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
editors.clear();
|
||||
fieldPaths.clear();
|
||||
fieldIndices.clear();
|
||||
labels.clear();
|
||||
types.clear();
|
||||
keys.clear();
|
||||
addKeys.clear();
|
||||
addButtons.clear();
|
||||
removeButtons.clear();
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
tag = null;
|
||||
editedTag = null;
|
||||
}
|
||||
public abstract void clear();
|
||||
|
||||
public void setEditMode(boolean edit, Tag tag) {
|
||||
if (tag == null) {
|
||||
tag = this.tag;
|
||||
}
|
||||
public abstract void setEditMode(boolean edit, Tag tag);
|
||||
|
||||
public abstract boolean tryAutoSave();
|
||||
public abstract boolean save();
|
||||
|
||||
this.tag = tag;
|
||||
this.editedTag = Helper.deepCopy(tag);
|
||||
generateEditControls(editedTag, !edit);
|
||||
public abstract Tag getTag();
|
||||
|
||||
if (edit) {
|
||||
remove(genericTagPropertiesEditorPaneScrollPanel);
|
||||
add(genericTagPropertiesEditPanelScrollPanel, BorderLayout.CENTER);
|
||||
} else {
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
remove(genericTagPropertiesEditPanelScrollPanel);
|
||||
add(genericTagPropertiesEditorPaneScrollPanel, BorderLayout.CENTER);
|
||||
setTagText(this.tag);
|
||||
}
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void setTagText(Tag tag) {
|
||||
clear();
|
||||
generateEditControls(tag, true);
|
||||
StringBuilder val = new StringBuilder();
|
||||
for (String key : keys) {
|
||||
GenericTagEditor ed = editors.get(key);
|
||||
if (((Component) ed).isVisible()) {
|
||||
val.append(key).append(" : ").append(ed.getReadOnlyValue()).append("<br>");
|
||||
}
|
||||
}
|
||||
//HTML for colors:
|
||||
val.insert(0, "<html>").append("</html>");
|
||||
genericTagPropertiesEditorPane.setContentType("text/html");
|
||||
genericTagPropertiesEditorPane.setText(val.toString());
|
||||
genericTagPropertiesEditorPane.setCaretPosition(0);
|
||||
hdr.setText(tag.toString());
|
||||
}
|
||||
|
||||
private void generateEditControls(Tag tag, boolean readonly) {
|
||||
clear();
|
||||
generateEditControlsRecursive(tag, "", new ArrayList<>(), new ArrayList<>(), readonly);
|
||||
change(null);
|
||||
}
|
||||
|
||||
private void relayout(int propCount) {
|
||||
//Lay out the panel.
|
||||
SpringUtilities.makeCompactGrid(genericTagPropertiesEditPanel,
|
||||
propCount, 3, //rows, cols
|
||||
6, 6, //initX, initY
|
||||
6, 6); //xPad, yPad
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private int generateEditControlsRecursive(final Object obj, String parent, List<Field> parentFields, List<Integer> parentIndices, boolean readonly) {
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
int propCount = 0;
|
||||
for (final Field field : fields) {
|
||||
try {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
field.setAccessible(true);
|
||||
String name = parent + field.getName();
|
||||
final Object value = field.get(obj);
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
if (value != null) {
|
||||
int i = 0;
|
||||
for (Object obj1 : (Iterable) value) {
|
||||
final String subname = name + "[" + i + "]";
|
||||
propCount += addEditor(subname, obj, field, i, obj1.getClass(), obj1, parentFields, parentIndices, readonly);
|
||||
final int fi = i;
|
||||
i++;
|
||||
JButton removeButton = new JButton(View.getIcon("close16"));
|
||||
removeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(obj, field, fi);
|
||||
}
|
||||
});
|
||||
removeButtons.put(subname, removeButton);
|
||||
}
|
||||
}
|
||||
} else if (field.getType().isArray()) {
|
||||
if (value != null) {
|
||||
for (int i = 0; i < Array.getLength(value); i++) {
|
||||
Object item = Array.get(value, i);
|
||||
String subname = name + "[" + i + "]";
|
||||
propCount += addEditor(subname, obj, field, i, item.getClass(), item, parentFields, parentIndices, readonly);
|
||||
final int fi = i;
|
||||
JButton removeButton = new JButton(View.getIcon("close16"));
|
||||
removeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(obj, field, fi);
|
||||
}
|
||||
});
|
||||
removeButtons.put(subname, removeButton);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields, parentIndices, readonly);
|
||||
}
|
||||
if (ReflectionTools.needsIndex(field) && !readonly && !field.getName().equals("clipActionRecords")) { //No clip actions, sorry
|
||||
JButton addButton = new JButton(View.getIcon("add16"));
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(obj, field);
|
||||
}
|
||||
});
|
||||
name += "[]";
|
||||
|
||||
List<Field> parList = new ArrayList<>(parentFields);
|
||||
parList.add(field);
|
||||
fieldPaths.put(name, parList);
|
||||
|
||||
List<Integer> parIndices = new ArrayList<>(parentIndices);
|
||||
parIndices.add(0);
|
||||
fieldIndices.put(name, parIndices);
|
||||
|
||||
addRow(name, addButton, field);
|
||||
addKeys.add(name);
|
||||
addButtons.put(name, addButton);
|
||||
}
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
return propCount;
|
||||
}
|
||||
|
||||
private void removeItem(Object obj, Field field, int index) {
|
||||
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
|
||||
final int val = sb.getValue(); //save scroll top
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
if (swfType != null && !swfType.countField().isEmpty()) { //Fields with same countField must be removed from too
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
|
||||
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
|
||||
ReflectionTools.removeFromField(obj, fields[f], index);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, decrement, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfType.countField());
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt--;
|
||||
countField.setInt(obj, cnt);
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.removeFromField(obj, field, index);
|
||||
}
|
||||
|
||||
generateEditControls(editedTag, false);
|
||||
|
||||
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
View.execInEventDispatch(() -> {
|
||||
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
|
||||
});
|
||||
}
|
||||
|
||||
}.start();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void addItem(Object obj, Field field) {
|
||||
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
|
||||
final int val = sb.getValue(); //save scroll top
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
if (swfType != null && !swfType.countField().isEmpty()) { //Fields with same countField must be enlarged too
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
|
||||
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
|
||||
ReflectionTools.addToField(obj, fields[f], ReflectionTools.getFieldSubSize(obj, fields[f]), true, null);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, increment, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfType.countField());
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt++;
|
||||
countField.setInt(obj, cnt);
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.addToField(obj, field, ReflectionTools.getFieldSubSize(obj, field), true, null);
|
||||
}
|
||||
generateEditControls(editedTag, false);
|
||||
|
||||
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
View.execInEventDispatch(() -> {
|
||||
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
|
||||
});
|
||||
}
|
||||
|
||||
}.start();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private int addEditor(String name, Object obj, Field field, int index, Class<?> type, Object value, List<Field> parentList, List<Integer> parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException {
|
||||
Calculated calculated = field.getAnnotation(Calculated.class);
|
||||
if (calculated != null) {
|
||||
return 0;
|
||||
}
|
||||
List<Field> parList = new ArrayList<>(parentList);
|
||||
parList.add(field);
|
||||
|
||||
List<Integer> parIndices = new ArrayList<>(parentIndices);
|
||||
parIndices.add(index);
|
||||
Internal inter = field.getAnnotation(Internal.class);
|
||||
if (inter != null) {
|
||||
return 0;
|
||||
}
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
Multiline multiline = field.getAnnotation(Multiline.class);
|
||||
Component editor;
|
||||
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)
|
||||
|| type.equals(float.class) || type.equals(Float.class)) {
|
||||
editor = new NumberEditor(name, obj, field, index, type, swfType);
|
||||
} else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
|
||||
editor = new BooleanEditor(name, obj, field, index, type);
|
||||
} else if (type.equals(String.class)) {
|
||||
editor = new StringEditor(name, obj, field, index, type, multiline != null);
|
||||
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) {
|
||||
editor = new ColorEditor(name, obj, field, index, type);
|
||||
} else if (type.equals(ByteArrayRange.class)) {
|
||||
editor = new BinaryDataEditor(mainPanel, name, obj, field, index, type);
|
||||
} else if (type.equals(Amf3Value.class)) {
|
||||
editor = new Amf3ValueEditor(name, obj, field, index, type);
|
||||
} else {
|
||||
if (value == null) {
|
||||
if (readonly) {
|
||||
return 0;
|
||||
}
|
||||
Optional opt = field.getAnnotation(Optional.class);
|
||||
if (opt == null) {
|
||||
try {
|
||||
value = ReflectionTools.newInstanceOf(field.getType());
|
||||
field.set(obj, value);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return generateEditControlsRecursive(value, name + ".", parList, parIndices, readonly);
|
||||
}
|
||||
if (editor instanceof GenericTagEditor) {
|
||||
GenericTagEditor ce = (GenericTagEditor) editor;
|
||||
ce.addChangeListener(this);
|
||||
editors.put(name, ce);
|
||||
fieldPaths.put(name, parList);
|
||||
fieldIndices.put(name, parIndices);
|
||||
addRow(name, editor, field);
|
||||
|
||||
ce.added();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void addRow(String name, Component editor, Field field) {
|
||||
JLabel label = new JLabel(name + ":", JLabel.TRAILING);
|
||||
label.setVerticalAlignment(JLabel.TOP);
|
||||
genericTagPropertiesEditPanel.add(label);
|
||||
label.setLabelFor(editor);
|
||||
labels.put(name, label);
|
||||
genericTagPropertiesEditPanel.add(editor);
|
||||
JLabel typeLabel = new JLabel(swfTypeToString(field.getAnnotation(SWFType.class)), JLabel.TRAILING);
|
||||
typeLabel.setVerticalAlignment(JLabel.TOP);
|
||||
genericTagPropertiesEditPanel.add(typeLabel);
|
||||
types.put(name, typeLabel);
|
||||
keys.add(name);
|
||||
}
|
||||
|
||||
public String swfTypeToString(SWFType swfType) {
|
||||
if (swfType == null) {
|
||||
return null;
|
||||
}
|
||||
String result = swfType.value().toString();
|
||||
if (swfType.count() > 0) {
|
||||
result += "[" + swfType.count();
|
||||
if (swfType.countAdd() > 0) {
|
||||
result += " + " + swfType.countAdd();
|
||||
}
|
||||
result += "]";
|
||||
} else if (!swfType.countField().isEmpty()) {
|
||||
result += "[" + swfType.countField();
|
||||
if (swfType.countAdd() > 0) {
|
||||
result += " + " + swfType.countAdd();
|
||||
}
|
||||
result += "]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void assignTag(Tag t, Tag assigned) {
|
||||
if (t.getClass() != assigned.getClass()) {
|
||||
return;
|
||||
}
|
||||
for (Field f : t.getClass().getDeclaredFields()) {
|
||||
if ((f.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
|
||||
continue;
|
||||
}
|
||||
if ((f.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
f.set(t, f.get(assigned));
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean save() {
|
||||
for (Object component : genericTagPropertiesEditPanel.getComponents()) {
|
||||
if (component instanceof GenericTagEditor) {
|
||||
try {
|
||||
((GenericTagEditor) component).validateValue();
|
||||
((GenericTagEditor) component).save();
|
||||
} catch (IllegalArgumentException iex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
SWF swf = tag.getSwf();
|
||||
Timelined tim = tag.getTimelined();
|
||||
assignTag(tag, editedTag);
|
||||
tag.setModified(true);
|
||||
tag.setSwf(swf);
|
||||
tag.setTimelined(tim);
|
||||
setTagText(tag);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Tag getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void change(GenericTagEditor ed) {
|
||||
for (String key : editors.keySet()) {
|
||||
GenericTagEditor dependentEditor = editors.get(key);
|
||||
Component dependentLabel = labels.get(key);
|
||||
Component dependentTypeLabel = types.get(key);
|
||||
List<Field> path = fieldPaths.get(key);
|
||||
List<Integer> indices = fieldIndices.get(key);
|
||||
String p = "";
|
||||
boolean conditionMet = true;
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
Field f = path.get(i);
|
||||
int index = indices.get(i);
|
||||
String par = p;
|
||||
if (!p.isEmpty()) {
|
||||
p += ".";
|
||||
}
|
||||
p += f.getName();
|
||||
if (ReflectionTools.needsIndex(f)) {
|
||||
p += "[" + index + "]";
|
||||
}
|
||||
Conditional cond = f.getAnnotation(Conditional.class);
|
||||
if (cond != null) {
|
||||
ConditionEvaluator ev = new ConditionEvaluator(cond);
|
||||
|
||||
try {
|
||||
Set<String> fieldNames = ev.getFields();
|
||||
Map<String, Boolean> fields = new HashMap<>();
|
||||
for (String fld : fieldNames) {
|
||||
String ckey = "";
|
||||
if (!par.isEmpty()) {
|
||||
ckey = par + ".";
|
||||
}
|
||||
ckey += fld;
|
||||
if (editors.containsKey(ckey)) {
|
||||
GenericTagEditor editor = editors.get(ckey);
|
||||
Object val = editor.getChangedValue();
|
||||
fields.put(fld, true);
|
||||
if (val instanceof Boolean) {
|
||||
fields.put(fld, (Boolean) val);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean ok = ev.eval(fields, tag.getId());
|
||||
if (conditionMet) {
|
||||
conditionMet = ok;
|
||||
}
|
||||
((Component) dependentEditor).setVisible(conditionMet);
|
||||
dependentLabel.setVisible(conditionMet);
|
||||
dependentTypeLabel.setVisible(conditionMet);
|
||||
} catch (AnnotationParseException ex) {
|
||||
logger.log(Level.SEVERE, "Invalid condition", ex);
|
||||
}
|
||||
}
|
||||
if (!conditionMet) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
int propCount = 0;
|
||||
for (String key : keys) {
|
||||
|
||||
Component dependentEditor;
|
||||
if (addKeys.contains(key)) {
|
||||
dependentEditor = addButtons.get(key);
|
||||
} else if (removeButtons.containsKey(key)) { //It's array/list, add remove button
|
||||
JPanel editRemPanel = new JPanel(new BorderLayout());
|
||||
editRemPanel.add((Component) editors.get(key), BorderLayout.CENTER);
|
||||
editRemPanel.add(removeButtons.get(key), BorderLayout.EAST);
|
||||
dependentEditor = editRemPanel;
|
||||
} else {
|
||||
dependentEditor = (Component) editors.get(key);
|
||||
}
|
||||
Component dependentLabel = labels.get(key);
|
||||
Component dependentTypeLabel = types.get(key);
|
||||
if (dependentEditor.isVisible()) {
|
||||
genericTagPropertiesEditPanel.add(dependentLabel);
|
||||
genericTagPropertiesEditPanel.add(((Component) dependentEditor));
|
||||
genericTagPropertiesEditPanel.add(dependentTypeLabel);
|
||||
propCount++;
|
||||
}
|
||||
}
|
||||
/*genericTagPropertiesEditPanel.add(new JPanel());
|
||||
genericTagPropertiesEditPanel.add(new JPanel());
|
||||
genericTagPropertiesEditPanel.add(new JPanel());*/
|
||||
relayout(propCount /*+ 1*/);
|
||||
}
|
||||
//@Override
|
||||
//public abstract void change(GenericTagEditor ed);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.amf.amf3.Amf3Value;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.Amf3ValueEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.BinaryDataEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor;
|
||||
@@ -119,16 +120,20 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
private static final int FIELD_INDEX = 0;
|
||||
|
||||
private List<TreeModelListener> listeners = new ArrayList<>();
|
||||
|
||||
public void addTreeModelListener(TreeModelListener listener) {
|
||||
((MyTreeModel)tree.getModel()).addTreeModelListener(listener);
|
||||
listeners.add(listener);
|
||||
((DefaultTreeModel) tree.getModel()).addTreeModelListener(listener);
|
||||
}
|
||||
|
||||
|
||||
public void removeTreeModelListener(TreeModelListener listener) {
|
||||
((MyTreeModel)tree.getModel()).removeTreeModelListener(listener);
|
||||
listeners.remove(listener);
|
||||
((DefaultTreeModel) tree.getModel()).removeTreeModelListener(listener);
|
||||
}
|
||||
|
||||
|
||||
private class MyTree extends JTree {
|
||||
|
||||
|
||||
public MyTree() {
|
||||
if (View.isOceanic()) {
|
||||
setBackground(Color.white);
|
||||
@@ -146,7 +151,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static SWFType evalSwfType(MyTreeModel mod, String parentPath, SWFType swfType) {
|
||||
if (swfType == null) {
|
||||
return null;
|
||||
@@ -157,7 +162,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
Conditional cond = new Conditional() {
|
||||
@Override
|
||||
public String[] value() {
|
||||
return new String[] {swfType.alternateCondition()};
|
||||
return new String[]{swfType.alternateCondition()};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -189,7 +194,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return Conditional.class;
|
||||
}
|
||||
};
|
||||
};
|
||||
ConditionEvaluator ev = new ConditionEvaluator(cond);
|
||||
try {
|
||||
Map<String, Boolean> fieldMap = new HashMap<>();
|
||||
@@ -219,41 +224,41 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
return swfType;
|
||||
}
|
||||
return new SWFType() {
|
||||
@Override
|
||||
public BasicType value() {
|
||||
return swfType.alternateValue();
|
||||
}
|
||||
@Override
|
||||
public BasicType value() {
|
||||
return swfType.alternateValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicType alternateValue() {
|
||||
return BasicType.NONE;
|
||||
}
|
||||
@Override
|
||||
public BasicType alternateValue() {
|
||||
return BasicType.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alternateCondition() {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public String alternateCondition() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count() {
|
||||
return swfType.count();
|
||||
}
|
||||
@Override
|
||||
public int count() {
|
||||
return swfType.count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String countField() {
|
||||
return swfType.countField();
|
||||
}
|
||||
@Override
|
||||
public String countField() {
|
||||
return swfType.countField();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countAdd() {
|
||||
return swfType.countAdd();
|
||||
}
|
||||
@Override
|
||||
public int countAdd() {
|
||||
return swfType.countAdd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return SWFType.class;
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return SWFType.class;
|
||||
}
|
||||
};
|
||||
} catch (AnnotationParseException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
return swfType;
|
||||
@@ -270,7 +275,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
public MyTreeCellEditor(JTree tree) {
|
||||
this.tree = tree;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
|
||||
@@ -298,8 +303,8 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
}
|
||||
GenericTagEditor editor = null;
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
MyTreeModel model = (MyTreeModel)tree.getModel();
|
||||
|
||||
MyTreeModel model = (MyTreeModel) tree.getModel();
|
||||
|
||||
SWFArray swfArray = field.getAnnotation(SWFArray.class);
|
||||
boolean isArray = ReflectionTools.needsIndex(field) || swfArray != null;
|
||||
boolean isArrayParent = isArray && index == -1;
|
||||
@@ -309,11 +314,11 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
if (isArray && !isArrayParent) {
|
||||
parentPath = parentPath.substring(0, parentPath.lastIndexOf("."));
|
||||
}
|
||||
|
||||
|
||||
swfType = evalSwfType(model, parentPath, swfType);
|
||||
|
||||
|
||||
UUID uuid = field.getAnnotation(UUID.class);
|
||||
|
||||
|
||||
Multiline multiline = field.getAnnotation(Multiline.class);
|
||||
EnumValues enumValues = field.getAnnotation(EnumValues.class);
|
||||
if (uuid != null) {
|
||||
@@ -415,10 +420,10 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
return false;
|
||||
}
|
||||
Object obj = path.getLastPathComponent();
|
||||
|
||||
|
||||
FieldNode fnode = (FieldNode) obj;
|
||||
Field field = fnode.fieldSet.get(FIELD_INDEX);
|
||||
|
||||
|
||||
boolean ret = super.isCellEditable(e)
|
||||
&& tree.getModel().isLeaf(obj) && hasEditor(fnode.obj, field, fnode.index);
|
||||
return ret;
|
||||
@@ -426,11 +431,14 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
@Override
|
||||
public boolean stopCellEditing() {
|
||||
boolean modified = false;
|
||||
if (editors != null) {
|
||||
for (GenericTagEditor editor : editors) {
|
||||
try {
|
||||
editor.validateValue();
|
||||
editor.save();
|
||||
if (editor.save()) {
|
||||
modified = true;
|
||||
}
|
||||
} catch (IllegalArgumentException iex) {
|
||||
return false;
|
||||
}
|
||||
@@ -440,15 +448,29 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
editors = null;
|
||||
|
||||
TreePath sp = tree.getSelectionPath();
|
||||
if (sp != null) {
|
||||
((MyTreeModel) tree.getModel()).vchanged(sp);
|
||||
if (modified) {
|
||||
TreePath sp = tree.getSelectionPath();
|
||||
if (sp != null) {
|
||||
((MyTreeModel) tree.getModel()).vchanged(sp);
|
||||
}
|
||||
refreshTree();
|
||||
}
|
||||
refreshTree();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean tryAutoSave() {
|
||||
if (Configuration.autoSaveTagModifications.get()) {
|
||||
if (tag == null) {
|
||||
return true;
|
||||
}
|
||||
return save();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public GenericTagTreePanel(MainPanel mainPanel) {
|
||||
super(mainPanel);
|
||||
setLayout(new BorderLayout());
|
||||
@@ -659,20 +681,19 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
||||
if (component instanceof JLabel) {
|
||||
JLabel lab = (JLabel) component;
|
||||
if (value == tree.getModel().getRoot()) {
|
||||
//It still does not matter since root is hidden
|
||||
if (editedTag != null) {
|
||||
lab.setIcon(AbstractTagTree.getIconForType(AbstractTagTree.getTreeNodeType(editedTag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return component;
|
||||
Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
||||
if (component instanceof JLabel) {
|
||||
JLabel lab = (JLabel) component;
|
||||
if (value == tree.getModel().getRoot()) {
|
||||
//It still does not matter since root is hidden
|
||||
if (editedTag != null) {
|
||||
lab.setIcon(AbstractTagTree.getIconForType(AbstractTagTree.getTreeNodeType(editedTag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -702,7 +723,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
private FieldSet fieldSet;
|
||||
|
||||
private int index;
|
||||
|
||||
|
||||
private MyTreeModel model;
|
||||
|
||||
public FieldNode(MyTreeModel model, Tag tag, Object obj, FieldSet fieldSet, int index) {
|
||||
@@ -746,7 +767,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
|
||||
if (fieldSet.size() == 1) {
|
||||
ret.append(toString(0));
|
||||
} else {
|
||||
@@ -766,11 +787,11 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
public String toString(int fieldIndex) {
|
||||
String valStr = "";
|
||||
Field field = fieldSet.get(fieldIndex);
|
||||
|
||||
|
||||
if (field.getAnnotation(UUID.class) != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] val = (byte[]) getValue(fieldIndex);
|
||||
for(int i = 0; i < val.length; i++) {
|
||||
for (int i = 0; i < val.length; i++) {
|
||||
String h = Integer.toHexString(val[i] & 0xff);
|
||||
if (h.length() == 1) {
|
||||
h = "0" + h;
|
||||
@@ -829,15 +850,14 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
Class<?> declaredType = fieldSet.get(fieldIndex).getType();
|
||||
boolean isArray = ReflectionTools.needsIndex(fieldSet.get(fieldIndex)) || swfArray != null;
|
||||
boolean isArrayParent = isArray && index == -1;
|
||||
|
||||
SWFType swfType = fieldSet.get(fieldIndex).getAnnotation(SWFType.class);
|
||||
|
||||
SWFType swfType = fieldSet.get(fieldIndex).getAnnotation(SWFType.class);
|
||||
String thisPath = model.getNodePathName(this);
|
||||
String parentPath = thisPath.substring(0, thisPath.lastIndexOf("."));
|
||||
if (isArray && !isArrayParent) {
|
||||
parentPath = parentPath.substring(0, parentPath.lastIndexOf("."));
|
||||
}
|
||||
swfType = evalSwfType(model, parentPath, swfType);
|
||||
|
||||
|
||||
Class<?> declaredSubType = isArray ? ReflectionTools.getFieldSubType(obj, fieldSet.get(fieldIndex)) : null;
|
||||
|
||||
@@ -1016,7 +1036,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
}
|
||||
|
||||
public String getNodePathName(Object find) {
|
||||
|
||||
|
||||
if (nodeCacheReverse.containsKey(find)) {
|
||||
return nodeCacheReverse.get(find);
|
||||
}
|
||||
@@ -1112,19 +1132,17 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
if (parent == mtroot) {
|
||||
return filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited, mtroot.getId()).size();
|
||||
}
|
||||
|
||||
|
||||
FieldNode fnode = (FieldNode) parent;
|
||||
|
||||
|
||||
|
||||
Field field = fnode.fieldSet.get(FIELD_INDEX);
|
||||
|
||||
|
||||
boolean isByteArray = field.getType().equals(byte[].class);
|
||||
|
||||
|
||||
|
||||
if (hasEditor(fnode.obj, field, fnode.index) || isByteArray) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays or Lists
|
||||
try {
|
||||
if (field.get(fnode.obj) == null) {
|
||||
@@ -1137,8 +1155,8 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
return ReflectionTools.getFieldSubSize(fnode.obj, field);
|
||||
}
|
||||
parent = fnode.getValue(FIELD_INDEX);
|
||||
|
||||
parent = fnode.getValue(FIELD_INDEX);
|
||||
|
||||
return filterFields(this, getNodePathName(fnode), parent.getClass(), limited, mtroot.getId()).size();
|
||||
}
|
||||
|
||||
@@ -1184,7 +1202,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
}
|
||||
if (!edit && tree.isEditing()) {
|
||||
tree.stopEditing();
|
||||
}
|
||||
}
|
||||
tree.setEditable(edit);
|
||||
refreshTree();
|
||||
}
|
||||
@@ -1200,13 +1218,13 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
tag.setModified(true);
|
||||
tag.setSwf(swf);
|
||||
if (tag instanceof Timelined) {
|
||||
((Timelined)tag).resetTimeline();
|
||||
((Timelined) tag).resetTimeline();
|
||||
}
|
||||
//For example DefineButton and its DefineButtonCxForm
|
||||
if ((tag instanceof CharacterIdTag) && (!(tag instanceof CharacterTag))) {
|
||||
CharacterTag parentCharacter = swf.getCharacter(((CharacterIdTag)tag).getCharacterId());
|
||||
CharacterTag parentCharacter = swf.getCharacter(((CharacterIdTag) tag).getCharacterId());
|
||||
if (parentCharacter instanceof Timelined) {
|
||||
((Timelined)parentCharacter).resetTimeline();
|
||||
((Timelined) parentCharacter).resetTimeline();
|
||||
}
|
||||
}
|
||||
swf.computeDependentCharacters();
|
||||
@@ -1249,9 +1267,9 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
type = val.getClass();
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UUID uuid = field.getAnnotation(UUID.class);
|
||||
|
||||
|
||||
if (uuid != null) {
|
||||
return true;
|
||||
} else if (type.equals(int.class) || type.equals(Integer.class)
|
||||
@@ -1475,7 +1493,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
if ((obj instanceof CLIPACTIONS) && (v instanceof CLIPACTIONRECORD)) {
|
||||
((CLIPACTIONRECORD) v).setParentClipActions((CLIPACTIONS) obj);
|
||||
}
|
||||
|
||||
|
||||
if (obj instanceof HasSwfAndTag) {
|
||||
((HasSwfAndTag) obj).setSourceTag(editedTag);
|
||||
}
|
||||
@@ -1484,11 +1502,15 @@ public class GenericTagTreePanel extends GenericTagPanel {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
((MyTreeModel) tree.getModel()).vchanged(new TreePath(tree.getModel().getRoot()));
|
||||
refreshTree();
|
||||
}
|
||||
|
||||
public void refreshTree() {
|
||||
View.refreshTree(tree, getModel());
|
||||
for (TreeModelListener listener:listeners) {
|
||||
((DefaultTreeModel) tree.getModel()).addTreeModelListener(listener);
|
||||
}
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
@@ -18,12 +18,15 @@ package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFCompression;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.helpers.TableLayoutHelper;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
@@ -34,6 +37,7 @@ import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import layout.TableLayout;
|
||||
|
||||
/**
|
||||
@@ -190,14 +194,24 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
|
||||
add(propertiesPanel, BorderLayout.CENTER);
|
||||
|
||||
editButton.setVisible(false);
|
||||
editButton.addActionListener(this::editButtonActionPerformed);
|
||||
|
||||
saveButton.setVisible(false);
|
||||
saveButton.addActionListener(this::saveButtonActionPerformed);
|
||||
|
||||
cancelButton.setVisible(false);
|
||||
cancelButton.addActionListener(this::cancelButtonActionPerformed);
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
editButton.setVisible(false);
|
||||
saveButton.setVisible(false);
|
||||
saveButton.setEnabled(false);
|
||||
cancelButton.setVisible(false);
|
||||
cancelButton.setEnabled(false);
|
||||
} else {
|
||||
editButton.setVisible(false);
|
||||
saveButton.setVisible(false);
|
||||
cancelButton.setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
buttonsPanel.setLayout(new FlowLayout());
|
||||
buttonsPanel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
@@ -294,7 +308,27 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
yMinEditor.setModel(new SpinnerNumberModel(swf.displayRect.Ymin, -0x80000000, 0x7fffffff, 1));
|
||||
yMaxEditor.setModel(new SpinnerNumberModel(swf.displayRect.Ymax, -0x80000000, 0x7fffffff, 1));
|
||||
|
||||
setEditMode(false);
|
||||
compressionComboBox.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
setModified();
|
||||
}
|
||||
});
|
||||
versionEditor.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
gfxCheckBox.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
frameRateEditor.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
xMinEditor.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
xMaxEditor.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
yMinEditor.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
yMaxEditor.addChangeListener((ChangeEvent e) -> {setModified();});
|
||||
|
||||
setEditMode(Configuration.editorMode.get());
|
||||
}
|
||||
|
||||
private void setModified() {
|
||||
saveButton.setEnabled(true);
|
||||
cancelButton.setEnabled(true);
|
||||
mainPanel.setEditingStatus();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
@@ -311,6 +345,10 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
}
|
||||
|
||||
private void setEditMode(boolean edit) {
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
edit = true;
|
||||
}
|
||||
compressionLabel.setVisible(!edit);
|
||||
compressionEditorPanel.setVisible(edit);
|
||||
versionLabel.setVisible(!edit);
|
||||
@@ -326,9 +364,17 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
|
||||
warningPanel.setVisible(false);
|
||||
|
||||
editButton.setVisible(!edit);
|
||||
saveButton.setVisible(edit);
|
||||
cancelButton.setVisible(edit);
|
||||
if (Configuration.editorMode.get()) {
|
||||
editButton.setVisible(false);
|
||||
saveButton.setVisible(true);
|
||||
saveButton.setEnabled(false);
|
||||
cancelButton.setVisible(true);
|
||||
cancelButton.setEnabled(false);
|
||||
} else {
|
||||
editButton.setVisible(!edit);
|
||||
saveButton.setVisible(edit);
|
||||
cancelButton.setVisible(edit);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validateHeader() {
|
||||
@@ -362,13 +408,15 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
|
||||
@Override
|
||||
public boolean tryAutoSave() {
|
||||
// todo: implement
|
||||
return false;
|
||||
if (saveButton.isVisible() && saveButton.isEnabled()) {
|
||||
saveButtonActionPerformed(null);
|
||||
}
|
||||
return !(saveButton.isVisible() && saveButton.isEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditing() {
|
||||
return saveButton.isVisible();
|
||||
return saveButton.isVisible() && saveButton.isEnabled();
|
||||
}
|
||||
|
||||
public void startEdit() {
|
||||
|
||||
@@ -846,7 +846,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
|
||||
public void setEditingStatus() {
|
||||
statusPanel.setStatus(translate("status.editing"));
|
||||
statusPanel.setStatus(translate(Configuration.autoSaveTagModifications.get() ? "status.editing.autosave" : "status.editing"));
|
||||
}
|
||||
|
||||
public void clearEditingStatus() {
|
||||
|
||||
@@ -63,6 +63,8 @@ import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
@@ -422,7 +424,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
genericSaveButton.setVisible(true);
|
||||
genericSaveButton.setEnabled(false);
|
||||
genericCancelButton.setVisible(true);
|
||||
genericSaveButton.setEnabled(false);
|
||||
genericCancelButton.setEnabled(false);
|
||||
} else {
|
||||
genericEditButton.setVisible(true);
|
||||
genericSaveButton.setVisible(false);
|
||||
@@ -524,7 +526,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), placeObject);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
imagePanel.setLoop(Configuration.loopMedia.get());
|
||||
|
||||
@@ -687,6 +689,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
genericTagPanel = new GenericTagTreePanel(mainPanel);
|
||||
genericTagCard.add(genericTagPanel, BorderLayout.CENTER);
|
||||
genericTagCard.add(createGenericTagButtonsPanel(), BorderLayout.SOUTH);
|
||||
addGenericListener();
|
||||
return genericTagCard;
|
||||
}
|
||||
|
||||
@@ -708,6 +711,16 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
});
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
placeImagePanel.addBoundsChangeListener(new BoundsChangeListener() {
|
||||
@Override
|
||||
public void boundsChanged(Rectangle2D newBounds, Point2D registrationPoint, RegistrationPointPosition registrationPointPosition) {
|
||||
if (placeSaveButton.isVisible()) {
|
||||
placeSaveButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
placeTransformPanel = new TransformPanel(placeImagePanel);
|
||||
//imagePanel.setLoop(Configuration.loopMedia.get());
|
||||
previewCnt.add(placeTransformSplitPane = new JPersistentSplitPane(
|
||||
@@ -727,6 +740,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
previewPanel.add(prevIntLabel, BorderLayout.NORTH);
|
||||
|
||||
placeGenericPanel = new GenericTagTreePanel(mainPanel);
|
||||
addPlaceGenericListener();
|
||||
placeSplitPane = new JPersistentSplitPane(JSplitPane.HORIZONTAL_SPLIT, previewPanel, placeGenericPanel, Configuration.guiSplitPanePlaceDividerLocationPercent);
|
||||
|
||||
placeTagCard.add(placeSplitPane, BorderLayout.CENTER);
|
||||
@@ -1058,7 +1072,6 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
genericEditButton.setEnabled(true);
|
||||
if (Configuration.editorMode.get()) {
|
||||
genericTagPanel.setEditMode(!tag.isReadOnly(), tag);
|
||||
addGenericListener();
|
||||
genericSaveButton.setVisible(!tag.isReadOnly());
|
||||
genericCancelButton.setVisible(!tag.isReadOnly());
|
||||
} else {
|
||||
@@ -1079,7 +1092,6 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
placeGenericPanel.setEditMode(!tag.isReadOnly(), tag);
|
||||
addPlaceGenericListener();
|
||||
placeEditButton.setVisible(false);
|
||||
placeSaveButton.setVisible(!tag.isReadOnly());
|
||||
placeCancelButton.setVisible(!tag.isReadOnly());
|
||||
@@ -1292,7 +1304,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
}
|
||||
|
||||
private void saveGenericTagButtonActionPerformed(ActionEvent evt) {
|
||||
private void saveGenericTag(boolean refreshTree) {
|
||||
if (genericTagPanel.save()) {
|
||||
Tag tag = genericTagPanel.getTag();
|
||||
SWF swf = tag.getSwf();
|
||||
@@ -1302,7 +1314,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
tag.getTimelined().resetTimeline();
|
||||
swf.assignClassesToSymbols();
|
||||
swf.assignExportNamesToSymbols();
|
||||
mainPanel.refreshTree(swf);
|
||||
if (refreshTree) {
|
||||
mainPanel.refreshTree(swf);
|
||||
}
|
||||
if (Configuration.editorMode.get()) {
|
||||
genericEditButton.setVisible(false);
|
||||
genericSaveButton.setVisible(true);
|
||||
@@ -1319,26 +1333,29 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
mainPanel.clearEditingStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveGenericTagButtonActionPerformed(ActionEvent evt) {
|
||||
saveGenericTag(true);
|
||||
}
|
||||
|
||||
private void cancelGenericTagButtonActionPerformed(ActionEvent evt) {
|
||||
if (Configuration.editorMode.get()) {
|
||||
genericTagPanel.setEditMode(true, null);
|
||||
genericEditButton.setVisible(false);
|
||||
genericSaveButton.setVisible(true);
|
||||
genericSaveButton.setEnabled(false);
|
||||
genericCancelButton.setVisible(true);
|
||||
genericCancelButton.setEnabled(false);
|
||||
genericTagPanel.setEditMode(true, null);
|
||||
addGenericListener();
|
||||
genericCancelButton.setEnabled(false);
|
||||
} else {
|
||||
genericTagPanel.setEditMode(false, null);
|
||||
genericEditButton.setVisible(true);
|
||||
genericSaveButton.setVisible(false);
|
||||
genericCancelButton.setVisible(false);
|
||||
genericTagPanel.setEditMode(false, null);
|
||||
genericCancelButton.setVisible(false);
|
||||
}
|
||||
mainPanel.clearEditingStatus();
|
||||
}
|
||||
|
||||
private void savePlaceTagButtonActionPerformed(ActionEvent evt) {
|
||||
private void savePlaceTag(boolean refreshTree) {
|
||||
if (placeEditMode == PLACE_EDIT_TRANSFORM) {
|
||||
Matrix matrix = placeImagePanel.getNewMatrix();
|
||||
placeTag.setPlaceFlagHasMatrix(true);
|
||||
@@ -1348,7 +1365,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
placeImagePanel.freeTransformDepth(-1);
|
||||
placeTag.getTimelined().resetTimeline();
|
||||
placeTransformScrollPane.setVisible(false);
|
||||
placeGenericPanel.setVisible(true);
|
||||
placeGenericPanel.setVisible(true);
|
||||
}
|
||||
Tag hilightTag = null;
|
||||
if (placeEditMode == PLACE_EDIT_RAW) {
|
||||
@@ -1356,7 +1373,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
Tag tag = placeGenericPanel.getTag();
|
||||
SWF swf = tag.getSwf();
|
||||
tag.getTimelined().resetTimeline();
|
||||
mainPanel.refreshTree(swf);
|
||||
if (refreshTree) {
|
||||
mainPanel.refreshTree(swf);
|
||||
}
|
||||
hilightTag = tag;
|
||||
}
|
||||
placeGenericPanel.setEditMode(false, null);
|
||||
@@ -1385,6 +1404,10 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
}
|
||||
|
||||
private void savePlaceTagButtonActionPerformed(ActionEvent evt) {
|
||||
savePlaceTag(true);
|
||||
}
|
||||
|
||||
private void editPlaceTagButtonActionPerformed(ActionEvent evt) {
|
||||
placeEditMode = PLACE_EDIT_RAW;
|
||||
placeGenericPanel.setEditMode(true, placeTag);
|
||||
@@ -1410,7 +1433,12 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
placeTransformButton.setVisible(false);
|
||||
placeSaveButton.setVisible(true);
|
||||
placeCancelButton.setVisible(true);
|
||||
placeSaveButton.setEnabled(true);
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
placeSaveButton.setEnabled(false);
|
||||
} else {
|
||||
placeSaveButton.setEnabled(true);
|
||||
}
|
||||
placeCancelButton.setEnabled(true);
|
||||
mainPanel.setEditingStatus();
|
||||
|
||||
@@ -1430,7 +1458,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}, 40); //add some delay before controls are hidden
|
||||
}
|
||||
|
||||
private void saveImageTransformButtonActionPerformed(ActionEvent evt) {
|
||||
private void saveImageTransform(boolean refreshTree) {
|
||||
Matrix matrix = imagePanel.getNewMatrix();
|
||||
|
||||
imageTransformScrollPane.setVisible(false);
|
||||
@@ -1470,7 +1498,13 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
|
||||
mainPanel.clearEditingStatus();
|
||||
mainPanel.reload(true);
|
||||
if (refreshTree) {
|
||||
mainPanel.reload(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveImageTransformButtonActionPerformed(ActionEvent evt) {
|
||||
saveImageTransform(true);
|
||||
}
|
||||
|
||||
private void cancelImageTransformButtonActionPerformed(ActionEvent evt) {
|
||||
@@ -1615,8 +1649,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
if (placeEditMode == PLACE_EDIT_RAW) {
|
||||
placeGenericPanel.setEditMode(true, null);
|
||||
addPlaceGenericListener();
|
||||
placeGenericPanel.setEditMode(true, null);
|
||||
}
|
||||
placeEditButton.setVisible(false);
|
||||
placeSaveButton.setVisible(true);
|
||||
@@ -1634,7 +1667,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
mainPanel.clearEditingStatus();
|
||||
placeTransformButton.setVisible(true);
|
||||
|
||||
|
||||
if (placeEditMode == PLACE_EDIT_TRANSFORM) {
|
||||
placeEditMode = PLACE_EDIT_RAW;
|
||||
}
|
||||
@@ -1660,8 +1693,31 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
@Override
|
||||
public boolean tryAutoSave() {
|
||||
// todo: implement
|
||||
return textPanel.tryAutoSave() && false;
|
||||
boolean ok = true;
|
||||
|
||||
if (imageTransformSaveButton.isVisible() && imageTransformSaveButton.isEnabled() && Configuration.autoSaveTagModifications.get()) {
|
||||
saveImageTransform(false);
|
||||
ok = ok && !(imageTransformSaveButton.isVisible() && imageTransformSaveButton.isEnabled());
|
||||
}
|
||||
|
||||
if (placeSaveButton.isVisible() && placeSaveButton.isEnabled() && Configuration.autoSaveTagModifications.get()) {
|
||||
savePlaceTag(false);
|
||||
ok = ok && !(placeSaveButton.isVisible() && placeSaveButton.isEnabled());
|
||||
}
|
||||
if (genericSaveButton.isVisible() && genericSaveButton.isEnabled()) {
|
||||
saveGenericTag(false);
|
||||
ok = ok && !(genericSaveButton.isVisible() && genericSaveButton.isEnabled());
|
||||
}
|
||||
if (metadataSaveButton.isVisible() && metadataSaveButton.isEnabled() && Configuration.autoSaveTagModifications.get()) {
|
||||
saveMetadataButtonActionPerformed(null);
|
||||
ok = ok && !(metadataSaveButton.isVisible() && metadataSaveButton.isEnabled());
|
||||
}
|
||||
if (fontPanel.isEditing() && Configuration.autoSaveTagModifications.get()) {
|
||||
ok = ok && fontPanel.tryAutoSave();
|
||||
}
|
||||
ok = ok && textPanel.tryAutoSave();
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
import java.util.Timer;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
@@ -175,14 +176,19 @@ public class Amf3ValueEditor extends JPanel implements GenericTagEditor, FullSiz
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
Object val = getChangedValue();
|
||||
ReflectionTools.setValue(obj, field, index, val);
|
||||
value = (Amf3Value) val;
|
||||
Object oldValue = (Amf3Value) ReflectionTools.getValue(obj, field, index);
|
||||
Object newValue = getChangedValue();
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, newValue);
|
||||
value = (Amf3Value) newValue;
|
||||
} catch (IllegalAccessException ex) {
|
||||
//ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JButton;
|
||||
|
||||
/**
|
||||
@@ -99,12 +100,18 @@ public class BinaryDataEditor extends JButton implements GenericTagEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
ReflectionTools.setValue(obj, field, index, value);
|
||||
Object oldValue = ReflectionTools.getValue(obj, field, index);
|
||||
Object newValue = value;
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, newValue);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -67,12 +67,20 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
boolean oldValue = (boolean) ReflectionTools.getValue(obj, field, index);
|
||||
boolean newValue = isSelected();
|
||||
|
||||
if (oldValue == newValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReflectionTools.setValue(obj, field, index, isSelected());
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.awt.event.FocusEvent;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JColorChooser;
|
||||
@@ -145,13 +146,19 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
Object val = getChangedValue();
|
||||
public boolean save() {
|
||||
try {
|
||||
ReflectionTools.setValue(obj, field, index, val);
|
||||
} catch (IllegalAccessException ex) {
|
||||
Object oldValue = ReflectionTools.getValue(obj, field, index);
|
||||
Object newValue = getChangedValue();
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReflectionTools.setValue(obj, field, index, newValue);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.awt.event.FocusEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
@@ -103,104 +104,22 @@ public class EnumEditor extends JComboBox<ComboBoxItem<Integer>> implements Gene
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
Object value = getChangedValue();
|
||||
if (value != null) {
|
||||
ReflectionTools.setValue(obj, field, index, value);
|
||||
Integer oldValue = (Integer) ReflectionTools.getValue(obj, field, index);
|
||||
Integer newValue = (Integer)getChangedValue();
|
||||
if (newValue == null) {
|
||||
return false;
|
||||
}
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, newValue);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private SpinnerModel getModel(SWFType swfType, Object value) {
|
||||
SpinnerNumberModel m = null;
|
||||
BasicType basicType = swfType == null ? BasicType.NONE : swfType.value();
|
||||
switch (basicType) {
|
||||
case UI8:
|
||||
m = new SpinnerNumberModel(toInt(value), 0, 0xff, 1);
|
||||
break;
|
||||
case UI16:
|
||||
m = new SpinnerNumberModel(toInt(value), 0, 0xffff, 1);
|
||||
break;
|
||||
case UB: {
|
||||
long max = 1;
|
||||
if (swfType.count() > 0) {
|
||||
max <<= swfType.count();
|
||||
} else {
|
||||
max <<= 31;
|
||||
}
|
||||
m = new SpinnerNumberModel((Number) toLong(value), 0L, (long) max - 1, 1L);
|
||||
}
|
||||
break;
|
||||
case UI32:
|
||||
case EncodedU32:
|
||||
case NONE:
|
||||
m = new SpinnerNumberModel((Number) toLong(value), 0L, 0xffffffffL, 1L);
|
||||
break;
|
||||
case SI8:
|
||||
m = new SpinnerNumberModel(toInt(value), -0x80, 0x7f, 1);
|
||||
break;
|
||||
case SI16:
|
||||
case FLOAT16:
|
||||
m = new SpinnerNumberModel(toInt(value), -0x8000, 0x7fff, 1);
|
||||
break;
|
||||
case FB:
|
||||
case SB: {
|
||||
long max = 1;
|
||||
if (swfType.count() > 0) {
|
||||
max <<= (swfType.count() - 1);
|
||||
} else {
|
||||
max <<= 30;
|
||||
}
|
||||
m = new SpinnerNumberModel((Number) toLong(value), (long) (-max), (long) max - 1, 1L);
|
||||
}
|
||||
break;
|
||||
case SI32:
|
||||
m = new SpinnerNumberModel(toDouble(value), -0x80000000, 0x7fffffff, 1);
|
||||
break;
|
||||
case FLOAT:
|
||||
case FIXED:
|
||||
case FIXED8:
|
||||
m = new SpinnerNumberModel(toDouble(value), -0x80000000, 0x7fffffff, 0.01);
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
private double toDouble(Object value) {
|
||||
if (value instanceof Float) {
|
||||
return (double) (Float) value;
|
||||
}
|
||||
if (value instanceof Double) {
|
||||
return (double) (Double) value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int toInt(Object value) {
|
||||
if (value instanceof Short) {
|
||||
return (int) (Short) value;
|
||||
}
|
||||
if (value instanceof Integer) {
|
||||
return (int) (Integer) value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private long toLong(Object value) {
|
||||
if (value instanceof Short) {
|
||||
return (long) (Short) value;
|
||||
}
|
||||
if (value instanceof Integer) {
|
||||
return (long) (Integer) value;
|
||||
}
|
||||
if (value instanceof Long) {
|
||||
return (long) (Long) value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(final ChangeListener l) {
|
||||
|
||||
@@ -28,7 +28,7 @@ public interface GenericTagEditor {
|
||||
|
||||
public void reset();
|
||||
|
||||
public void save();
|
||||
public boolean save();
|
||||
|
||||
public void addChangeListener(ChangeListener l);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.Component;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SpinnerModel;
|
||||
@@ -91,15 +92,21 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
Object value = getChangedValue();
|
||||
if (value != null) {
|
||||
ReflectionTools.setValue(obj, field, index, value);
|
||||
Object oldValue = ReflectionTools.getValue(obj, field, index);
|
||||
Object newValue = getChangedValue();
|
||||
if (newValue == null) {
|
||||
return false;
|
||||
}
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, newValue);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private SpinnerModel getModel(SWFType swfType, Object value) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.Dimension;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
/**
|
||||
@@ -91,12 +92,18 @@ public class StringEditor extends JTextArea implements GenericTagEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
String oldValue = (String) ReflectionTools.getValue(obj, field, index);
|
||||
String newValue = getText();
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, getText());
|
||||
} catch (IllegalAccessException ex) {
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.Dimension;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
@@ -65,7 +66,7 @@ public class UUIDEditor extends JTextField implements GenericTagEditor {
|
||||
}
|
||||
|
||||
public UUIDEditor(String fieldName, Object obj, Field field, int index, Class<?> type) {
|
||||
super(32+4);
|
||||
super(32 + 4);
|
||||
this.obj = obj;
|
||||
this.field = field;
|
||||
this.index = index;
|
||||
@@ -79,7 +80,7 @@ public class UUIDEditor extends JTextField implements GenericTagEditor {
|
||||
try {
|
||||
byte[] val = (byte[]) ReflectionTools.getValue(obj, field, index);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 0; i < val.length; i++) {
|
||||
for (int i = 0; i < val.length; i++) {
|
||||
String h = Integer.toHexString(val[i] & 0xff);
|
||||
if (h.length() == 1) {
|
||||
h = "0" + h;
|
||||
@@ -96,22 +97,28 @@ public class UUIDEditor extends JTextField implements GenericTagEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public boolean save() {
|
||||
try {
|
||||
byte[] oldValue = (byte[]) ReflectionTools.getValue(obj, field, index);
|
||||
|
||||
String text = getText();
|
||||
text = text.replace("-", "").trim();
|
||||
if (!text.matches("[a-fA-F0-9]{32}")) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
byte[] val = new byte[16];
|
||||
byte[] newValue = 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);
|
||||
newValue[i] = (byte) Integer.parseInt(ch, 16);
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, val);
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (Objects.equals(oldValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
ReflectionTools.setValue(obj, field, index, newValue);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1080,4 +1080,6 @@ message.info.importImages2 = During importing images, you need to select a FOLDE
|
||||
|
||||
transform.clipboard = Clipboard
|
||||
transform.clipboard.copy = Copy matrix to clipboard
|
||||
transform.clipboard.paste = Paste matrix from clipboard
|
||||
transform.clipboard.paste = Paste matrix from clipboard
|
||||
|
||||
status.editing.autosave = You are in the EDIT mode. Make changes, then press Save button. Or discard changes with Cancel button. If you switch to other tag, current editation will be automatically saved.
|
||||
|
||||
@@ -1065,4 +1065,6 @@ message.info.importImages2 = B\u011bhem importu text\u016f mus\u00edte vybrat SL
|
||||
|
||||
transform.clipboard = Schr\u00e1nka
|
||||
transform.clipboard.copy = Kop\u00edrovat matici do schr\u00e1nky
|
||||
transform.clipboard.paste = Vlo\u017eit matici ze schr\u00e1nky
|
||||
transform.clipboard.paste = Vlo\u017eit matici ze schr\u00e1nky
|
||||
|
||||
status.editing.autosave = Jste v EDITA\u010cN\u00cdM re\u017eimu. Prove\u010fte zm\u011bny a stiskn\u011bte tla\u010d\u00edtko Ulo\u017eit. Nebo zru\u0161te zm\u011bny tla\u010d\u00edtkem Storno. Pokud p\u0159epnete na jin\u00fd tag, aktu\u00e1ln\u00ed editace bude automaticky ulo\u017eena.
|
||||
|
||||
Reference in New Issue
Block a user