Added: #2478 Simple editor - editing texts (not WYSIWYG, textual as in classic editor)

This commit is contained in:
Jindra Petřík
2025-07-06 18:26:43 +02:00
parent 8d0952a8fc
commit 0ac9ec748c
9 changed files with 214 additions and 21 deletions

View File

@@ -18,6 +18,9 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.easygui.DoableOperation;
import com.jpexs.decompiler.flash.easygui.EasyStrings;
import com.jpexs.decompiler.flash.easygui.UndoManager;
import com.jpexs.decompiler.flash.gui.controls.JRepeatButton;
import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane;
import com.jpexs.decompiler.flash.helpers.HighlightedText;
@@ -41,7 +44,7 @@ import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.JScrollPane;
import javax.swing.text.BadLocationException;
/**
@@ -86,9 +89,15 @@ public class TextPanel extends JPanel implements TagEditorPanel {
private final JButton undoChangesButton;
private TextTag textTag;
private final UndoManager undoManager;
private String oldText = null;
public TextPanel(final MainPanel mainPanel) {
public TextPanel(final MainPanel mainPanel, UndoManager undoManager) {
super(new BorderLayout());
this.undoManager = undoManager;
this.mainPanel = mainPanel;
textSearchPanel = new SearchPanel<>(new FlowLayout(), mainPanel);
@@ -97,14 +106,18 @@ public class TextPanel extends JPanel implements TagEditorPanel {
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
topPanel.add(textSearchPanel);
textValue = new LineMarkedEditorPane();
add(new FasterScrollPane(textValue), BorderLayout.CENTER);
JScrollPane sp = new FasterScrollPane(textValue);
sp.setPreferredSize(new Dimension(200, 200));
//sp.setMaximumSize(sp.getSize());
//sp.setPreferredSize(sp.getMaximumSize());
add(sp, BorderLayout.CENTER);
textValue.setFont(Configuration.getSourceFont());
textValue.changeContentType("text/swftext");
textValue.addTextChangedListener(this::textChanged);
JPanel textButtonsPanel = new JPanel();
textButtonsPanel.setLayout(new FlowLayout(SwingConstants.WEST));
textButtonsPanel.setMinimumSize(new Dimension(10, textButtonsPanel.getMinimumSize().height));
textButtonsPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
//textButtonsPanel.setMinimumSize(new Dimension(10, textButtonsPanel.getMinimumSize().height));
selectPreviousTagButton = createButton(null, "arrowup16", "selectPreviousTag", e -> mainPanel.previousTag());
selectNextTagButton = createButton(null, "arrowdown16", "selectNextTag", e -> mainPanel.nextTag());
@@ -126,7 +139,9 @@ public class TextPanel extends JPanel implements TagEditorPanel {
textButtonsPanel.add(decreaseTranslateXButton);
textButtonsPanel.add(increaseTranslateXButton);
textButtonsPanel.add(changeCaseButton);
textButtonsPanel.add(undoChangesButton);
if (undoManager == null) {
textButtonsPanel.add(undoChangesButton);
}
textButtonsPanel.setAlignmentX(0);
topPanel.add(textButtonsPanel);
@@ -148,6 +163,10 @@ public class TextPanel extends JPanel implements TagEditorPanel {
add(buttonsPanel, BorderLayout.SOUTH);
}
public TextTag getTextTag() {
return textTag;
}
private JButton createButton(String textResource, String iconName, String toolTipResource, ActionListener actionListener) {
return createButton(textResource, iconName, toolTipResource, actionListener, false);
}
@@ -180,6 +199,7 @@ public class TextPanel extends JPanel implements TagEditorPanel {
}
textValue.setText(formattedText);
oldText = formattedText;
}
public void setText(TextTag textTag) {
@@ -203,6 +223,7 @@ public class TextPanel extends JPanel implements TagEditorPanel {
undoChangesButton.setVisible(!readOnly);
selectPreviousTagButton.setVisible(mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES);
selectNextTagButton.setVisible(mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES);
updateButtonsVisibility();
}
private boolean isModified() {
@@ -281,10 +302,15 @@ public class TextPanel extends JPanel implements TagEditorPanel {
}
}
boolean editable = textValue.isEditable();
textValue.setEditable(true);
textValue.replaceSelection(selected.toString());
saveText(true);
textValue.setEditable(editable);
if (!editable) {
saveText(true);
updateButtonsVisibility();
updateButtonsVisibility();
}
textTag.getSwf().clearImageCache();
mainPanel.repaintTree();
@@ -340,12 +366,13 @@ public class TextPanel extends JPanel implements TagEditorPanel {
private void cancelText() {
setEditText(false);
refresh();
mainPanel.reload(true);
mainPanel.clearEditingStatus();
}
private void saveText(boolean refresh) {
if (mainPanel.saveText(textTag, textValue.getText(), null, textValue)) {
if (mainPanel.saveText(textTag, textValue.getText(), null, textValue, undoManager)) {
setEditText(false);
setModified(false);
textTag.getSwf().clearImageCache();
@@ -357,16 +384,74 @@ public class TextPanel extends JPanel implements TagEditorPanel {
}
private void textAlign(TextAlign textAlign) {
if (undoManager != null) {
String prevText = textTag.getFormattedText(false).text;
undoManager.doOperation(new DoableOperation() {
@Override
public void doOperation() {
textAlignInternal(textAlign);
}
@Override
public void undoOperation() {
try {
textTag.setFormattedText(null, prevText, null);
} catch (TextParseException ex) {
//ignore
}
}
@Override
public String getDescription() {
return EasyStrings.translate("action.change").replace("%item%", EasyStrings.translate("action.change.text"));
}
}, textTag.getSwf());
return;
}
textAlignInternal(textAlign);
}
private void textAlignInternal(TextAlign textAlign) {
if (textTag.alignText(textAlign)) {
updateButtonsVisibility();
refresh();
textTag.getSwf().clearImageCache();
mainPanel.repaintTree();
}
}
private void translateX(int delta, int repeatCount) {
if (undoManager != null) {
undoManager.doOperation(new DoableOperation() {
@Override
public void doOperation() {
translateXInternal(delta, repeatCount);
}
@Override
public void undoOperation() {
translateXInternal(-delta, repeatCount);
}
@Override
public String getDescription() {
return EasyStrings.translate("action.change").replace("%item%", EasyStrings.translate("action.change.text"));
}
}, textTag.getSwf());
return;
}
translateXInternal(delta, repeatCount);
}
private void translateXInternal(int delta, int repeatCount) {
if (textTag.translateText(delta * (repeatCount + 1))) {
updateButtonsVisibility();
refresh();
textTag.getSwf().clearImageCache();
mainPanel.repaintTree();
}