// Near Infinity - An Infinity Engine Browser and Editor // Copyright (C) 2001 - 2005 Jon Olav Hauglid // See LICENSE.txt for license information package org.infinity.gui; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.infinity.NearInfinity; import org.infinity.icon.Icons; import org.infinity.resource.ResourceFactory; import org.infinity.resource.key.FileResourceEntry; import org.infinity.resource.key.ResourceEntry; import org.infinity.util.io.FileManager; public final class OpenFileFrame extends ChildFrame implements ActionListener { private static final JFileChooser fc = new JFileChooser("."); private final JButton bExternalBrowse = new JButton("Browse..."); private final JButton bOpen = new JButton("Open", Icons.getIcon(Icons.ICON_OPEN_16)); private final JButton bOpenNew = new JButton("Open in new window", Icons.getIcon(Icons.ICON_OPEN_16)); private final JCheckBox cbStayOpen = new JCheckBox("Keep this dialog open"); private final JLabel lExternalDrop = new JLabel("or drop file(s) here", JLabel.CENTER); private final JRadioButton rbExternal = new JRadioButton("Open external file"); private final JRadioButton rbInternal = new JRadioButton("Open internal file"); private final JTextField tfExternalName = new JTextField(20); private final TextListPanel lpInternal; OpenFileFrame() { super("Open File"); setIconImage(Icons.getIcon(Icons.ICON_OPEN_16).getImage()); rbExternal.addActionListener(this); rbInternal.addActionListener(this); rbExternal.setMnemonic('e'); rbInternal.setMnemonic('i'); cbStayOpen.setMnemonic('k'); ButtonGroup gb = new ButtonGroup(); gb.add(rbExternal); gb.add(rbInternal); fc.setDialogTitle("Open external file"); tfExternalName.addActionListener(this); bExternalBrowse.setMnemonic('b'); bExternalBrowse.addActionListener(this); tfExternalName.setMinimumSize( new Dimension(tfExternalName.getMinimumSize().width, bExternalBrowse.getMinimumSize().height)); tfExternalName.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { bOpenNew.setEnabled(rbInternal.isSelected() || tfExternalName.getText().length() > 0); } @Override public void removeUpdate(DocumentEvent e) { bOpenNew.setEnabled(rbInternal.isSelected() || tfExternalName.getText().length() > 0); } @Override public void changedUpdate(DocumentEvent e) { bOpenNew.setEnabled(rbInternal.isSelected() || tfExternalName.getText().length() > 0); } }); lpInternal = new TextListPanel(new ArrayList<ResourceEntry>(ResourceFactory.getResources().getResourceEntries())); bOpen.addActionListener(this); bOpenNew.addActionListener(this); bOpenNew.setEnabled(false); bOpen.setMnemonic('o'); bOpenNew.setMnemonic('n'); lExternalDrop.setBorder(BorderFactory.createLineBorder(UIManager.getColor("controlDkShadow"))); new DropTarget(lExternalDrop, new MyDropTargetListener()); rbExternal.setSelected(true); bOpen.setEnabled(false); getRootPane().setDefaultButton(bOpenNew); lpInternal.setEnabled(false); lpInternal.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent event) { if (event.getClickCount() == 2) { actionPerformed(new ActionEvent(lpInternal, 0, "View")); } } }); JPanel pane = (JPanel)getContentPane(); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); pane.setLayout(gbl); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(3, 3, 3, 6); gbl.setConstraints(rbExternal, gbc); pane.add(rbExternal); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; gbc.gridwidth = 1; gbc.insets = new Insets(0, 12, 3, 0); gbl.setConstraints(tfExternalName, gbc); pane.add(tfExternalName); gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = new Insets(0, 3, 3, 6); gbl.setConstraints(bExternalBrowse, gbc); pane.add(bExternalBrowse); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.insets = new Insets(0, 12, 3, 6); gbl.setConstraints(lExternalDrop, gbc); pane.add(lExternalDrop); gbc.weighty = 0.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(9, 3, 3, 6); gbl.setConstraints(rbInternal, gbc); pane.add(rbInternal); gbc.weighty = 3.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(0, 12, 3, 6); gbl.setConstraints(lpInternal, gbc); pane.add(lpInternal); JPanel bPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); bPanel.add(bOpen); bPanel.add(bOpenNew); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 0.0; gbc.insets = new Insets(3, 6, 0, 6); gbl.setConstraints(bPanel, gbc); pane.add(bPanel); gbc.insets.top = 0; gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.NONE; gbl.setConstraints(cbStayOpen, gbc); pane.add(cbStayOpen); setSize(330, 400); Center.center(this, NearInfinity.getInstance().getBounds()); } // --------------------- Begin Interface ActionListener --------------------- @Override public void actionPerformed(ActionEvent event) { if (event.getSource() == rbExternal) { bOpen.setEnabled(false); bOpenNew.setEnabled(tfExternalName.getText().length() > 0); lpInternal.setEnabled(false); tfExternalName.setEnabled(true); bExternalBrowse.setEnabled(true); } else if (event.getSource() == rbInternal) { bOpen.setEnabled(true); bOpenNew.setEnabled(true); lpInternal.setEnabled(true); tfExternalName.setEnabled(false); bExternalBrowse.setEnabled(false); } else if (event.getSource() == tfExternalName) { openExternalFile(this, FileManager.resolve(tfExternalName.getText())); } else if (event.getSource() == bExternalBrowse) { if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) tfExternalName.setText(fc.getSelectedFile().toString()); } else if (event.getSource() == bOpen || event.getSource() == lpInternal) { if (!cbStayOpen.isSelected()) setVisible(false); ResourceEntry entry = (ResourceEntry)lpInternal.getSelectedValue(); NearInfinity.getInstance().showResourceEntry(entry); } else if (event.getSource() == bOpenNew) { if (!cbStayOpen.isSelected()) { setVisible(false); } if (rbInternal.isSelected()) { new ViewFrame(this, ResourceFactory.getResource((ResourceEntry)lpInternal.getSelectedValue())); } else { openExternalFile(this, FileManager.resolve(tfExternalName.getText())); } } } // --------------------- End Interface ActionListener --------------------- /** Attempts to open the specified external game resource. */ public static void openExternalFile(Component parent, Path file) { if (!Files.exists(file)) { JOptionPane.showMessageDialog(parent, '\"' + file.toString() + "\" not found", "Error", JOptionPane.ERROR_MESSAGE); } else { new ViewFrame(parent, ResourceFactory.getResource(new FileResourceEntry(file))); } } // -------------------------- INNER CLASSES -------------------------- private final class MyDropTargetListener implements DropTargetListener, Runnable { private List<File> files; private MyDropTargetListener() { } @Override public void dragEnter(DropTargetDragEvent event) { } @Override public void dragOver(DropTargetDragEvent event) { } @Override public void dropActionChanged(DropTargetDragEvent event) { } @Override public void dragExit(DropTargetEvent event) { } @SuppressWarnings("unchecked") @Override public void drop(DropTargetDropEvent event) { if (event.isLocalTransfer() || !event.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { event.rejectDrop(); return; } try { event.acceptDrop(DnDConstants.ACTION_COPY); files = (List<File>)event.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); } catch (Exception e) { e.printStackTrace(); event.dropComplete(false); return; } event.dropComplete(true); new Thread(this).start(); } @Override public void run() { if (files != null) { for (final File file: files) { if (file != null && !file.isDirectory()) { openExternalFile(OpenFileFrame.this, file.toPath()); } } } } } }