/*
* Copyright (C) 2014 James Lawrence.
*
* This file is part of GrimEdi.
*
* GrimEdi is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Created by JFormDesigner on Fri Mar 15 22:29:38 GMT 2013
*/
package com.sqrt4.grimedi.ui;
import com.sqrt.liblab.LabCollection;
import com.sqrt.liblab.LabFile;
import com.sqrt.liblab.codec.CodecMapper;
import com.sqrt.liblab.codec.EntryCodec;
import com.sqrt.liblab.entry.LabEntry;
import com.sqrt.liblab.io.DataSource;
import com.sqrt.liblab.io.DiskDataSource;
import com.sqrt4.grimedi.Main;
import com.sqrt4.grimedi.ui.component.BusyDialog;
import com.sqrt4.grimedi.ui.editor.EditorMapper;
import com.sqrt4.grimedi.ui.editor.EditorPanel;
import com.sqrt4.grimedi.ui.editor.HexView;
import com.sqrt4.grimedi.util.CachedPredicate;
import com.sqrt4.grimedi.util.Predicate;
import com.sqrt4.grimedi.util.Size;
import org.netbeans.swing.outline.DefaultOutlineModel;
import org.netbeans.swing.outline.Outline;
import org.netbeans.swing.outline.RenderDataProvider;
import org.netbeans.swing.outline.RowModel;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author James Lawrence
*/
public class MainWindow extends JFrame {
private static MainWindow inst;
public LabCollection context;
private FilterableLabTreeModel filterableEntries;
private Predicate<DataSource> searchPredicate;
private BusyDialog _busy;
private DataSource popupSource;
private LabFile labPopupSource;
private final JFileChooser fileChooser = new JFileChooser(".");
static {
SplashScreenController.setPercentage(10);
SplashScreenController.setText("Registering codecs...");
CodecMapper.registerDefaults();
SplashScreenController.setPercentage(30);
SplashScreenController.setText("Registering views...");
EditorMapper.registerDefaults();
SplashScreenController.setPercentage(80);
SplashScreenController.setPercentage(100);
SplashScreenController.setText("GrimEdi v" + Main.VERSION + " by James Lawrence");
// It loads too fast, add artificial delay so people can appreciate the splash screen...
if (SplashScreenController.supported()) {
try {
Thread.sleep(3000);
} catch (Exception e) {
/**/
}
}
}
public static MainWindow getInstance() {
return inst;
}
public MainWindow() {
inst = this;
SplashScreenController.setText("Initialising UI...");
initComponents();
fileList.setRenderDataProvider(new RenderDataProvider() {
public String getDisplayName(Object o) {
return o.toString();
}
public boolean isHtmlDisplayName(Object o) {
return false;
}
public Color getBackground(Object o) {
return fileList.getBackground();
}
public Color getForeground(Object o) {
return fileList.getForeground();
}
public String getTooltipText(Object o) {
return null;
}
ImageIcon labIcon = new ImageIcon(getClass().getResource("/lab.png"));
public Icon getIcon(Object o) {
if (o instanceof LabFile)
return labIcon;
else if (o instanceof DataSource) {
EditorPanel panel = EditorMapper.editorPanelForProvider((DataSource) o);
return panel == null ? EditorPanel.defaultIcon : panel.getIcon();
}
return null;
}
});
fileList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
fileSelected(e);
}
});
}
public JFileChooser createFileDialog() {
JFileChooser jfc = new JFileChooser(fileChooser.getCurrentDirectory());
return jfc;
}
private void fileSearch(CaretEvent e) {
filterableEntries.removeFilter(searchPredicate);
if (searchField.getText().isEmpty()) {
filterableEntries.applyFilters();
return;
}
final String search = searchField.getText().toLowerCase();
final String regex = search.replace(".", "\\.").replace("*", ".*").replace("?", ".");
searchPredicate = new CachedPredicate<DataSource>(new Predicate<DataSource>() {
public boolean accept(DataSource dataSource) {
String lcase = dataSource.getName().toLowerCase();
return lcase.startsWith(search) || lcase.matches(regex);
}
});
filterableEntries.addFilter(searchPredicate);
filterableEntries.applyFilters();
}
public void runAsyncWithPopup(String message, final Runnable r, boolean canCancel, Action cancelCallback) {
final AtomicBoolean abort = new AtomicBoolean(false);
final Thread asyncThread = new Thread() {
public void run() {
while (_busy == null || !_busy.isVisible()) {
try {
Thread.sleep(10); // Wait until the busy dialog is shown...
} catch (InterruptedException ignore) {
}
}
try {
if(!abort.get())
r.run(); // Do it...
} catch (Throwable t) {
t.printStackTrace(); // Catch any errors
} finally {
_busy.setVisible(false);
_busy = null;
}
}
};
asyncThread.setDaemon(true);
asyncThread.start();
try {
if (_busy == null)
_busy = new BusyDialog(this);
_busy.setCancellable(canCancel);
_busy.setCancelCallback(cancelCallback);
_busy.setTitle("Please wait...");
_busy.setMessage(message);
_busy.pack();
_busy.setVisible(true);
} catch (Throwable t) {
abort.set(true);
if (_busy != null)
_busy.setVisible(true);
t.printStackTrace();
}
}
public void runAsyncWithPopup(String message, final Runnable r) {
runAsyncWithPopup(message, r, false, null);
}
public void setBusyMessage(String message) {
if (_busy == null || !_busy.isVisible())
return;
_busy.setMessage(message);
_busy.pack();
}
public void handleException(Throwable t) {
t.printStackTrace();
JOptionPane.showMessageDialog(this, t.getLocalizedMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
private void fileSelected(ListSelectionEvent e) {
int row = fileList.getSelectionModel().getLeadSelectionIndex();
Object selObj = fileList.getModel().getValueAt(fileList.convertRowIndexToModel(row), 0);
if (selObj == null || !(selObj instanceof DataSource))
return;
final DataSource selected = (DataSource) selObj;
runAsyncWithPopup("Loading " + selected.getName() + "...", new Runnable() {
public void run() {
while (editorPane.getComponentCount() > 0) {
Component c = editorPane.getComponent(0);
if (c instanceof EditorPanel) {
EditorPanel ep = (EditorPanel) c;
ep.onHide();
// Todo: check if modified, save in temporary file if it is, cleanup if not - etc.
// Saving in a temporary file means we can leave it to be GC'd, as we'll have a version on disk
// It also means we don't modify the LAB until it's time to rebuild the entire thing
}
editorPane.remove(0);
}
EntryCodec<?> codec = CodecMapper.codecForProvider(selected);
boolean fallback = true;
LabEntry data = null;
try {
selected.position(0);
if (codec != null) {
try {
data = codec.read(selected);
} catch (OutOfMemoryError oome) {
System.gc();
data = codec.read(selected);
}
}
} catch (Throwable e1) {
handleException(e1);
}
EditorPanel panel = EditorMapper.editorPanelForProvider(selected);
if (data != null && panel != null) {
panel.setWindow(MainWindow.this);
panel.setData(data);
fallback = false;
editorPane.add(panel);
panel.onShow();
}
if (fallback)
editorPane.add(new HexView(selected));
editorPane.invalidate();
editorPane.revalidate();
editorPane.repaint();
}
});
}
private void fileListMousePressed(MouseEvent e) {
if (context == null)
return;
TreePath selPath = fileList.getClosestPathForLocation(e.getX(), e.getY());
if (selPath == null)
return;
Object clicked = selPath.getLastPathComponent();
if (clicked instanceof DataSource) {
popupSource = (DataSource) clicked;
if (e.getClickCount() == 1 && SwingUtilities.isRightMouseButton(e)) {
entryPopupMenu.show(e.getComponent(), e.getX(), e.getY());
}
} else if (clicked instanceof LabFile) {
labPopupSource = (LabFile) clicked;
if (e.getClickCount() == 1 && SwingUtilities.isRightMouseButton(e)) {
labPopupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
}
private void onOpen() {
filterableEntries = new FilterableLabTreeModel(context);
fileList.setModel(DefaultOutlineModel.createOutlineModel(filterableEntries, filterableEntries, false, "File"));
searchField.setText("");
searchPredicate = null;
searchField.setEnabled(true);
searchLabel.setEnabled(true);
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
// Generated using JFormDesigner non-commercial license
private JMenuBar menuBar1;
private JMenu menu1;
private JMenuItem menuItem1;
private JMenuItem menuItem2;
private JSeparator separator1;
private JMenuItem menuItem3;
private JMenu menu2;
private JMenuItem menuItem7;
private JSplitPane splitPane1;
private JPanel panel1;
private JScrollPane scrollPane1;
private Outline fileList;
private JPanel panel2;
private JLabel searchLabel;
private JTextField searchField;
private JPanel editorPane;
private JPopupMenu entryPopupMenu;
private JMenuItem menuItem9;
private JMenuItem menuItem10;
private JMenuItem menuItem4;
private JMenuItem menuItem5;
private JPopupMenu labPopupMenu;
private JMenuItem menuItem11;
private JMenuItem menuItem6;
private JMenuItem menuItem8;
private OpenAction openAction;
private CloseAction closeAction;
private ExtractEntryAction extractEntryAction;
private DeleteEntryAction deleteEntryAction;
private ExtractAllAction extractAllAction;
private OpenAboutDialogAction openAboutDialogAction;
private SaveLabAction saveLabAction;
private InsertFileAction insertFileAction;
private ReplaceFileAction replaceFileAction;
// JFormDesigner - End of variables declaration //GEN-END:variables
private class OpenAction extends AbstractAction {
private OpenAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Open");
putValue(SHORT_DESCRIPTION, "Open a LAB file");
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fileChooser.showOpenDialog(MainWindow.this) != JFileChooser.APPROVE_OPTION)
return;
runAsyncWithPopup("Loading LAB files...", new Runnable() {
public void run() {
File f = fileChooser.getSelectedFile();
try {
context = LabCollection.open(f);
onOpen();
} catch (IOException e1) {
handleException(e1);
}
}
});
}
}
private class CloseAction extends AbstractAction {
private CloseAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Close");
putValue(SHORT_DESCRIPTION, "Close the current LAB file");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
// TODO: close the LAB file...
}
}
private class FilterableLabTreeModel implements TreeModel, RowModel {
private final LabCollection source;
private final java.util.List<TreeModelListener> listeners = new LinkedList<TreeModelListener>();
private final java.util.List<Predicate<DataSource>> predicates = new LinkedList<Predicate<DataSource>>();
private final LinkedHashMap<LabFile, java.util.List<DataSource>> filtered = new LinkedHashMap<LabFile, java.util.List<DataSource>>();
public FilterableLabTreeModel(LabCollection coll) {
this.source = coll;
applyFilters();
}
public void addFilter(Predicate<DataSource> pred) {
predicates.add(pred);
}
public void removeFilter(Predicate<DataSource> pred) {
predicates.remove(pred);
}
public void applyFilters() {
for (LabFile lb : source.labs) {
java.util.List<DataSource> source = lb.entries;
for (Predicate<DataSource> pred : predicates) {
java.util.List<DataSource> accepted = new LinkedList<DataSource>();
for (DataSource e : source)
if (pred.accept(e))
accepted.add(e);
source = accepted;
}
if (source.isEmpty())
filtered.remove(lb);
else
filtered.put(lb, source);
}
fireChange();
}
public void fireChange() {
if (listeners.isEmpty())
return;
TreeModelEvent tme = new TreeModelEvent(this, new Object[]{source});
for (int i = 0; i < listeners.size(); i++) {
listeners.get(i).treeStructureChanged(tme);
}
}
public Object getRoot() {
return source;
}
public Object getChild(Object parent, int index) {
if (parent == context) {
Object[] labs = filtered.keySet().toArray();
if (labs.length == 0 && index == 0)
return "No entries";
return labs[index];
} else if (parent instanceof LabFile)
return filtered.get(parent).get(index);
return null;
}
public int getChildCount(Object parent) {
if (parent == source) {
int labs = filtered.keySet().size();
if (labs == 0)
return 1; // No results message
return labs;
} else if (parent instanceof LabFile) {
return filtered.get(parent).size();
}
return 0;
}
public boolean isLeaf(Object node) {
return getChildCount(node) == 0;
}
public void valueForPathChanged(TreePath path, Object newValue) {
System.out.println(path);
}
public int getIndexOfChild(Object parent, Object child) {
if (parent == context)
return context.labs.indexOf(child);
else if (parent instanceof LabFile)
return filtered.get(parent).indexOf(child);
return -1;
}
public void addTreeModelListener(TreeModelListener l) {
listeners.add(l);
}
public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(l);
}
public int getColumnCount() {
return 2;
}
public Object getValueFor(Object o, int i) {
switch (i) {
case 0:
String s = o.toString();
int idx = s.lastIndexOf('.');
if (idx == -1)
return "";
return s.substring(idx + 1);
case 1:
if (o instanceof DataSource)
return new Size(((DataSource) o).length());
else if(o instanceof LabFile) {
long length = 0;
for(DataSource ds: ((LabFile) o).entries)
length += ds.length();
return new Size(length);
} else if(o instanceof LabCollection) {
long length = 0;
for(LabFile lf: ((LabCollection) o).labs) {
for(DataSource ds: lf.entries)
length += ds.length();
}
return new Size(length);
}
return null;
}
return null;
}
public Class getColumnClass(int i) {
switch (i) {
case 0:
return String.class;
case 1:
return Integer.class;
}
return null;
}
public boolean isCellEditable(Object o, int i) {
return false;
}
public void setValueFor(Object o, int i, Object o2) {
}
public String getColumnName(int i) {
switch (i) {
case 0:
return "Type";
case 1:
return "Size";
default:
return "?";
}
}
}
private class ExtractEntryAction extends AbstractAction {
private ExtractEntryAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Extract");
putValue(SHORT_DESCRIPTION, "Extract this entry to a file");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
String name = popupSource.getName();
String ext = name.substring(name.lastIndexOf('.') + 1).toLowerCase();
final JFileChooser jfc = createFileDialog();
jfc.setFileFilter(new FileNameExtensionFilter("Grim Fandango " + ext.toUpperCase() + " (*." + ext + ")", ext));
jfc.setSelectedFile(new File(name));
if (jfc.showSaveDialog(MainWindow.this) != JFileChooser.APPROVE_OPTION)
return;
File f = jfc.getSelectedFile();
String nn = f.getName();
if(!nn.toLowerCase().endsWith("." + ext))
nn += "." + ext;
final File dest = new File(f.getParentFile(), nn);
runAsyncWithPopup("Extracting " + name + "...", new Runnable() {
public void run() {
try {
FileOutputStream fos = new FileOutputStream(dest);
byte[] buf = new byte[5000];
int copied = 0;
long len = popupSource.length();
popupSource.position(0);
while (copied < len) {
int toRead = (int) Math.min(buf.length, len - copied);
popupSource.get(buf, 0, toRead);
fos.write(buf, 0, toRead);
copied += toRead;
}
fos.close();
} catch (IOException e1) {
handleException(e1);
}
}
});
}
}
private class DeleteEntryAction extends AbstractAction {
private DeleteEntryAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Delete");
putValue(SHORT_DESCRIPTION, "Delete the entry from the LAB file");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
popupSource.container.entries.remove(popupSource);
filterableEntries.fireChange();
}
}
private class ExtractAllAction extends AbstractAction {
private ExtractAllAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Extract all...");
putValue(SHORT_DESCRIPTION, "Extract all the entries in this LAB file to the specified directory...");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = createFileDialog();
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (jfc.showSaveDialog(MainWindow.this) != JFileChooser.APPROVE_OPTION)
return;
final File dir = jfc.getSelectedFile();
final AtomicBoolean cancelled = new AtomicBoolean(false);
final String pre = "<html>Extracting " + labPopupSource.toString() + "...<br/>";
runAsyncWithPopup(pre, new Runnable() {
public void run() {
final byte[] buf = new byte[5000];
for (DataSource source : labPopupSource.entries) {
_busy.setMessage(pre + "\n" + "\t" + source.getName());
try {
File f = new File(dir, source.getName());
FileOutputStream fos = new FileOutputStream(f);
int copied = 0;
long len = source.length();
source.position(0);
while (!cancelled.get() && copied < len) {
int toRead = (int) Math.min(buf.length, len - copied);
source.get(buf, 0, toRead);
fos.write(buf, 0, toRead);
copied += toRead;
}
fos.close();
if(cancelled.get()) {
f.delete();
return;
}
Thread.sleep(1000);
} catch (Exception e1) {
handleException(e1);
break;
}
}
}
}, true, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
cancelled.set(true);
}
});
}
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
menuBar1 = new JMenuBar();
menu1 = new JMenu();
menuItem1 = new JMenuItem();
menuItem2 = new JMenuItem();
separator1 = new JSeparator();
menuItem3 = new JMenuItem();
menu2 = new JMenu();
menuItem7 = new JMenuItem();
splitPane1 = new JSplitPane();
panel1 = new JPanel();
scrollPane1 = new JScrollPane();
fileList = new Outline();
panel2 = new JPanel();
searchLabel = new JLabel();
searchField = new JTextField();
editorPane = new JPanel();
entryPopupMenu = new JPopupMenu();
menuItem9 = new JMenuItem();
menuItem10 = new JMenuItem();
menuItem4 = new JMenuItem();
menuItem5 = new JMenuItem();
labPopupMenu = new JPopupMenu();
menuItem11 = new JMenuItem();
menuItem6 = new JMenuItem();
menuItem8 = new JMenuItem();
openAction = new OpenAction();
closeAction = new CloseAction();
extractEntryAction = new ExtractEntryAction();
deleteEntryAction = new DeleteEntryAction();
extractAllAction = new ExtractAllAction();
openAboutDialogAction = new OpenAboutDialogAction();
saveLabAction = new SaveLabAction();
insertFileAction = new InsertFileAction();
replaceFileAction = new ReplaceFileAction();
//======== this ========
setTitle("GrimEdi");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
//======== menuBar1 ========
{
//======== menu1 ========
{
menu1.setText("File");
//---- menuItem1 ----
menuItem1.setAction(openAction);
menuItem1.setMnemonic('O');
menu1.add(menuItem1);
//---- menuItem2 ----
menuItem2.setAction(closeAction);
menu1.add(menuItem2);
menu1.add(separator1);
//---- menuItem3 ----
menuItem3.setText("Exit");
menu1.add(menuItem3);
}
menuBar1.add(menu1);
//======== menu2 ========
{
menu2.setText("Help");
//---- menuItem7 ----
menuItem7.setAction(openAboutDialogAction);
menu2.add(menuItem7);
}
menuBar1.add(menu2);
}
setJMenuBar(menuBar1);
//======== splitPane1 ========
{
//======== panel1 ========
{
panel1.setLayout(new BorderLayout());
//======== scrollPane1 ========
{
//---- fileList ----
fileList.setFillsViewportHeight(true);
fileList.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
fileList.setFullyNonEditable(true);
fileList.setSurrendersFocusOnKeystroke(false);
fileList.setShowHorizontalLines(true);
fileList.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
fileListMousePressed(e);
}
});
scrollPane1.setViewportView(fileList);
}
panel1.add(scrollPane1, BorderLayout.CENTER);
//======== panel2 ========
{
panel2.setLayout(new GridBagLayout());
((GridBagLayout)panel2.getLayout()).columnWidths = new int[] {0, 0, 0, 0};
((GridBagLayout)panel2.getLayout()).rowHeights = new int[] {0, 0, 0};
((GridBagLayout)panel2.getLayout()).columnWeights = new double[] {1.0, 1.0, 0.0, 1.0E-4};
((GridBagLayout)panel2.getLayout()).rowWeights = new double[] {1.0, 1.0, 1.0E-4};
//---- searchLabel ----
searchLabel.setIcon(new ImageIcon(getClass().getResource("/tm_item_search.png")));
searchLabel.setLabelFor(searchField);
searchLabel.setText("Search:");
searchLabel.setEnabled(false);
searchLabel.setHorizontalAlignment(SwingConstants.TRAILING);
panel2.add(searchLabel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 2, 2), 0, 0));
//---- searchField ----
searchField.setEnabled(false);
searchField.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
fileSearch(e);
}
});
panel2.add(searchField, new GridBagConstraints(1, 0, 2, 1, 3.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 2, 0), 0, 0));
}
panel1.add(panel2, BorderLayout.NORTH);
}
splitPane1.setLeftComponent(panel1);
//======== editorPane ========
{
editorPane.setLayout(new BorderLayout());
}
splitPane1.setRightComponent(editorPane);
}
contentPane.add(splitPane1, BorderLayout.CENTER);
setSize(800, 600);
setLocationRelativeTo(null);
//======== entryPopupMenu ========
{
//---- menuItem9 ----
menuItem9.setAction(insertFileAction);
entryPopupMenu.add(menuItem9);
entryPopupMenu.addSeparator();
//---- menuItem10 ----
menuItem10.setAction(replaceFileAction);
entryPopupMenu.add(menuItem10);
//---- menuItem4 ----
menuItem4.setMnemonic('E');
menuItem4.setAction(extractEntryAction);
entryPopupMenu.add(menuItem4);
//---- menuItem5 ----
menuItem5.setMnemonic('D');
menuItem5.setAction(deleteEntryAction);
entryPopupMenu.add(menuItem5);
}
//======== labPopupMenu ========
{
//---- menuItem11 ----
menuItem11.setText("text");
menuItem11.setAction(insertFileAction);
labPopupMenu.add(menuItem11);
//---- menuItem6 ----
menuItem6.setAction(extractAllAction);
labPopupMenu.add(menuItem6);
//---- menuItem8 ----
menuItem8.setAction(saveLabAction);
labPopupMenu.add(menuItem8);
}
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
private class OpenAboutDialogAction extends AbstractAction {
private OpenAboutDialogAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "About");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
AboutDialog dialog = new AboutDialog(MainWindow.this);
dialog.pack();
dialog.setVisible(true);
}
}
private class SaveLabAction extends AbstractAction {
private SaveLabAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Save LAB");
putValue(SHORT_DESCRIPTION, "Rebuild and save this LAB");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = createFileDialog();
jfc.setFileFilter(new FileNameExtensionFilter("Grim Fandango LAB (*.lab)", "lab"));
String ln = labPopupSource.getName();
int idx = ln.lastIndexOf('.');
if(idx != -1)
ln = ln.substring(0, idx);
jfc.setSelectedFile(new File(ln + ".lab"));
if(jfc.showSaveDialog(MainWindow.this) != JFileChooser.APPROVE_OPTION)
return;
File f = jfc.getSelectedFile();
File dir = f.getParentFile();
String name = f.getName();
if(!name.toLowerCase().endsWith(".lab"))
name += ".lab";
final File dest = new File(dir, name);
runAsyncWithPopup("Building LAB file, please wait...", new Runnable() {
public void run() {
try {
labPopupSource.save(dest);
} catch (IOException e1) {
handleException(e1);
}
}
});
}
}
private class InsertFileAction extends AbstractAction {
private InsertFileAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Insert");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = createFileDialog();
if(jfc.showOpenDialog(MainWindow.this) != JFileChooser.APPROVE_OPTION)
return;
try {
LabFile lf =((JMenuItem) e.getSource()).getParent() == entryPopupMenu? popupSource.container: labPopupSource;
File f = jfc.getSelectedFile();
File temp = File.createTempFile(f.getName(), "tmp");
Files.copy(f.toPath(), temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
DataSource ds = new DiskDataSource(lf, f.getName(), new RandomAccessFile(temp, "rw"));
lf.entries.add(ds);
filterableEntries.fireChange();
} catch (IOException e1) {
handleException(e1);
}
}
}
private class ReplaceFileAction extends AbstractAction {
private ReplaceFileAction() {
// JFormDesigner - Action initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
putValue(NAME, "Replace");
putValue(SHORT_DESCRIPTION, "Replaces the selected file with one from your hard drive");
// JFormDesigner - End of action initialization //GEN-END:initComponents
}
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = createFileDialog();
if(jfc.showOpenDialog(MainWindow.this) != JFileChooser.APPROVE_OPTION)
return;
String name = popupSource.getName();
LabFile container = popupSource.container;
deleteEntryAction.actionPerformed(e);
popupSource = null;
try {
File f = jfc.getSelectedFile();
File temp = File.createTempFile(name, "tmp");
Files.copy(f.toPath(), temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
DataSource ds = new DiskDataSource(container, name, new RandomAccessFile(temp, "rw"));
popupSource.container.entries.add(ds);
filterableEntries.fireChange();
} catch (IOException e1) {
handleException(e1);
}
}
}
}