Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * FE Editor - GBA Fire Emblem (U) ROM editor
- *
- * Copyright (C) 2008-2011 Hextator,
- * hextator (AIM) [email protected] (MSN)
- *
- * Major thanks to Zahlman (AIM/MSN: [email protected]) for optimization,
- * organization and modularity improvements.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3
- * as published by the Free Software Foundation
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * <Description> This class provides a dialog with a text area and other
- * appropriate controls for easy modification of the games' scripts
- */
- /* MODIFIED BY CAMTECH075 OF SERENESFOREST -
- *
- * Changed refresh method to apply changes automatically.
- * Removed lines 120-135 (well, commented them out, at least)
- * Added "applyChanges" override method at line 306
- */
- package FEditorAdvance;
- import java.awt.event.ActionListener;
- import java.awt.event.ActionEvent;
- import java.io.FileWriter;
- import java.io.File;
- import java.util.Scanner;
- import javax.swing.BorderFactory;
- import javax.swing.JCheckBox;
- import javax.swing.JLabel;
- import javax.swing.JScrollPane;
- import javax.swing.JTextArea;
- import javax.swing.JTextField;
- import javax.swing.JPanel;
- //import javax.swing.JButton;
- import Controls.TablePanel;
- import Controls.Process;
- import Controls.ProcessComponent;
- import Model.Game;
- import Model.TextArray;
- import Model.Util;
- public class TextEditor extends Editor<TextArray> {
- private TablePanel<TextArray> tablePanel;
- private JTextArea inputArea;
- private JCheckBox regExChkBox;
- public TextEditor(View view) {
- super(view);
- inputArea = new JTextArea(8, 16);
- inputArea.setLineWrap(true);
- inputArea.setWrapStyleWord(true);
- JScrollPane inputPane = new JScrollPane(inputArea);
- inputPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
- // Don't limit the size of this!
- add(inputPane);
- // FIXME: This should use TextArray.maxSize(), but there is
- // no instance available yet.
- tablePanel = new TablePanel<TextArray>(this, 0x1, 0xFFFF, 0);
- tablePanel.setMaximumSize(tablePanel.getPreferredSize());
- add(tablePanel);
- JPanel findPanel = new JPanel();
- findPanel.add(new JLabel("Input text to find:"));
- final JTextField findField = new JTextField(32);
- findPanel.add(findField);
- findPanel.setMaximumSize(findPanel.getPreferredSize());
- add(findPanel);
- JPanel replacePanel = new JPanel();
- replacePanel.add(new JLabel("Input text to replace:"));
- final JTextField replaceField = new JTextField(30);
- replacePanel.add(replaceField);
- replacePanel.setMaximumSize(replacePanel.getPreferredSize());
- add(replacePanel);
- JPanel panelA = new JPanel();
- addButtonToPanel(panelA, "Find", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- table.moveTo(1); find(findField.getText(), true);
- }
- });
- addButtonToPanel(panelA, "Find Next", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- table.next(); find(findField.getText(), true);
- }
- });
- addButtonToPanel(panelA, "Find Previous", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- table.prev(); find(findField.getText(), false);
- }
- });
- addButtonToPanel(panelA, "Replace All", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- replaceAll(findField.getText(), replaceField.getText());
- }
- });
- regExChkBox = new JCheckBox("Use Reg Ex?");
- regExChkBox.setSelected(false);
- panelA.add(regExChkBox);
- panelA.setMaximumSize(panelA.getPreferredSize());
- add(panelA);
- JPanel panelB = new JPanel();
- /**
- *addButtonToPanel(panelB, "Apply", new ActionListener() {
- * public void actionPerformed(ActionEvent a) {
- * table.setText(inputArea.getText());
- * // Refresh the input area in case the text
- * // was modified in the process of any
- * // last second formatting done prior to insertion
- * inputArea.setText(table.getText());
- * }
- *});
- *addButtonToPanel(panelB, "Revert", new ActionListener() {
- * public void actionPerformed(ActionEvent a) {
- * inputArea.setText(table.getText());
- * }
- *});
- */
- addButtonToPanel(panelB, "Dump...", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- dump();
- }
- });
- addButtonToPanel(panelB, "Insert...", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- insert();
- }
- });
- addButtonToPanel(panelB, "Quit", new ActionListener() {
- public void actionPerformed(ActionEvent a) {
- quit();
- }
- });
- panelB.setMaximumSize(panelB.getPreferredSize());
- add(panelB);
- setMinimumSize(getSize());
- }
- @Override
- public void setup(Game game) {
- table = game.textArray();
- // The TablePanel will call back to refresh().
- tablePanel.setTable(table);
- }
- /* Hextator sez: This override is redundant and unsafe
- @Override
- public void cleanup() {
- tablePanel.setTable(null); // so it can be GC'd
- }
- */
- @Override
- //FIXME: Doesn't work, instead displays "[X]" for everything
- public void refresh() {
- //Camtech - I'm desperately hoping that this works the way I think it
- //does; that is, I'm hoping it reads the 'input index' during the call
- //to "getText", rather than for each spinner change.
- applyChanges();
- inputArea.setText(table.getText());
- }
- private void find(final String toFind, final boolean forward) {
- if (toFind.equals("")) {
- java.awt.Toolkit.getDefaultToolkit().beep();
- return;
- }
- final boolean useRegularExpressions = regExChkBox.isSelected();
- class Finder extends ProcessComponent {
- public String found = null;
- public boolean regExError = false;
- public Finder(int iterations, int weight, String description) {
- super(iterations, weight, description);
- }
- protected boolean iterate(int i) {
- //System.out.println(Util.verboseReport("find iteration"));
- String entry = table.getText();
- boolean foundMatch;
- if (!useRegularExpressions)
- foundMatch = entry.indexOf(toFind) != -1;
- else {
- try {
- String[] temp = entry.split(toFind);
- foundMatch =
- temp != null
- && (
- temp.length > 1
- || temp.length == 0
- )
- ;
- } catch (Exception e) {
- regExError = true;
- return true;
- }
- }
- if (entry != null && foundMatch) {
- found = entry;
- return true;
- }
- if (forward) { table.next(); }
- else { table.prev(); }
- return false;
- }
- }
- final Finder f = new Finder(
- table.getCurrentSize(), 1, "Searching for text..."
- );
- view.process(
- false, // don't show dialogs
- new Process(true, f) { // can cancel
- @Override
- public void finish() {
- if (f.found == null) {
- if (!f.regExError)
- CommonDialogs.showGenericErrorDialog(
- "String not found!"
- );
- else
- CommonDialogs.showGenericErrorDialog(
- "It seems your regular expression is invalid."
- );
- } else {
- // Synchronize the spinner with the position that was moved to
- // behind the scenes.
- tablePanel.setIndex(table.getPosition());
- // In turn, the tablePanel will call refresh().
- }
- }
- }
- );
- }
- class PositionRestoringProcess extends Process {
- private int originalPosition;
- public PositionRestoringProcess(ProcessComponent component) {
- super(false, component); // can't cancel
- originalPosition = tablePanel.getIndex();
- }
- @Override
- public void finish() {
- // The spinner hasn't changed, but the table position needs to be
- // reset, and text should be updated to match.
- tablePanel.setIndex(originalPosition);
- }
- }
- private void replaceAll(final String toFind, final String replaceWith) {
- if (toFind.equals("")) {
- java.awt.Toolkit.getDefaultToolkit().beep();
- return;
- }
- final boolean useRegularExpressions = regExChkBox.isSelected();
- view.process(
- true, // show dialogs
- new PositionRestoringProcess(
- new ProcessComponent(
- table.getCurrentSize(), 1, "Replacing occurrences of text..."
- ) {
- protected boolean iterate(int i) {
- if (i == 0) { return false; }
- table.moveTo(i);
- String text = table.getText();
- if (text != null) {
- if (!useRegularExpressions)
- table.setText(text.replace(toFind, replaceWith));
- else
- table.setText(text.replaceAll(toFind, replaceWith));
- }
- return false;
- }
- }
- )
- );
- }
- @Override
- public void applyChanges() { table.setText(inputArea.getText()); }
- //Camtech - I'm mostly doing things in the safest way I can think of,
- //as I don't understand half of this stuff anyway. And still, I'm sure
- //I fucked something up somewhere or other.
- private void dump() {
- final FileWriter scriptToDump;
- File selectedFile = CommonDialogs.showSaveFileDialog("script dump");
- if (selectedFile == null) { return; }
- try { scriptToDump = new FileWriter(selectedFile); }
- catch (Exception e) {
- CommonDialogs.showStreamErrorDialog();
- return;
- }
- int size = table.getCurrentSize();
- view.process(
- true, // show dialogs
- new PositionRestoringProcess(
- new ProcessComponent(size, 1, "Dumping script...") {
- protected boolean iterate(int i) {
- if (i == 0) { return false; }
- table.moveTo(i);
- String text = table.getText();
- if (text != null) { // should be impossible for text to be null?
- try {
- scriptToDump.write(String.format(
- "Text of ID 0x%04X\n%s\n\n",
- i, table.getText()
- ).replaceAll("\\n", Util.newline));
- } catch (Exception e) {}
- }
- return false;
- }
- @Override
- protected void cleanup() {
- try { scriptToDump.close(); }
- catch (Exception e) {}
- }
- }
- )
- );
- }
- private void insert() {
- final Scanner scriptToInsert;
- File fileSelected = CommonDialogs.showOpenFileDialog("script dump");
- if (fileSelected == null) { return; }
- try { scriptToInsert = new Scanner(fileSelected); }
- catch (Exception e) {
- CommonDialogs.showStreamErrorDialog();
- return;
- }
- //int writeIndex;
- //String indexLine;
- view.process(
- true, // show dialogs
- new PositionRestoringProcess(
- // We don't know how many iterations there will be, so we set up
- // an indeterminate process step and do the loop manually.
- new ProcessComponent(1, 0, "Reading script...") {
- protected boolean iterate(int i) {
- int index = 1;
- while (writeEntry(index++, scriptToInsert)) {}
- return false;
- }
- @Override
- protected void cleanup() {
- try { scriptToInsert.close(); }
- catch (Exception e) {}
- }
- }
- )
- );
- }
- // Return false when we run out of data.
- @SuppressWarnings("empty-statement")
- private boolean writeEntry(int index, Scanner source) {
- String indexLine = "";
- while (indexLine.equals("")) {
- if (!source.hasNextLine()) { return false; }
- indexLine = source.nextLine();
- };
- try {
- index = Util.parseInt(
- indexLine.substring(indexLine.lastIndexOf(" "))
- ) & 0xFFFF;
- } catch (Exception e) { /* Use the default counter value. */ }
- String outString = "";
- String line;
- do {
- if (!source.hasNextLine()) { return false; }
- line = source.nextLine();
- outString += line + "\n";
- } while (!line.endsWith("[X]"));
- outString = outString.trim();
- table.moveTo(index);
- table.setText(outString);
- return true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment