// Near Infinity - An Infinity Engine Browser and Editor // Copyright (C) 2001 - 2005 Jon Olav Hauglid // See LICENSE.txt for license information package org.infinity.search; import java.awt.CardLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.infinity.NearInfinity; import org.infinity.gui.Center; import org.infinity.gui.ChildFrame; import org.infinity.gui.ViewFrame; import org.infinity.icon.Icons; import org.infinity.resource.ResourceFactory; import org.infinity.resource.Viewable; import org.infinity.resource.bcs.BcsResource; import org.infinity.resource.key.ResourceEntry; public final class SearchFrame extends ChildFrame implements ActionListener, ListSelectionListener, Runnable { private static final SearchFrame searchframe = null; private final CardLayout cards = new CardLayout(); 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 JButton binsert = new JButton("Insert reference", Icons.getIcon(Icons.ICON_PASTE_16)); private final JButton bsearch = new JButton("Search", Icons.getIcon(Icons.ICON_FIND_16)); private final JList<String> list = new JList<>(); private final JPanel bpanel; private final JProgressBar progress = new JProgressBar(); private final JRadioButton rbcre = new JRadioButton("Creatures"); private final JRadioButton rbitm = new JRadioButton("Items"); private final JRadioButton rbspl = new JRadioButton("Spells"); private final JRadioButton rbsto = new JRadioButton("Stores"); private final JTextField tfield = new JTextField(10); public static void clearCache() { if (searchframe != null) { searchframe.list.setListData(new String[0]); searchframe.bopen.setEnabled(false); searchframe.bopennew.setEnabled(false); searchframe.binsert.setEnabled(false); } } public SearchFrame() { super("Find"); setIconImage(Icons.getIcon(Icons.ICON_FIND_16).getImage()); getRootPane().setDefaultButton(bsearch); bopen.setMnemonic('o'); bopennew.setMnemonic('n'); binsert.setMnemonic('r'); rbcre.setMnemonic('c'); rbitm.setMnemonic('i'); rbspl.setMnemonic('s'); rbsto.setMnemonic('t'); ButtonGroup bg = new ButtonGroup(); bg.add(rbcre); bg.add(rbitm); bg.add(rbspl); bg.add(rbsto); rbcre.setSelected(true); list.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); JScrollPane scroll = new JScrollPane(list); list.setEnabled(false); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.addListSelectionListener(this); bopen.setEnabled(false); bopennew.setEnabled(false); binsert.setEnabled(false); binsert.setToolTipText("Inserts reference to selected item into script displayed in main window"); JLabel label = new JLabel("Name:"); label.setLabelFor(tfield); label.setDisplayedMnemonic('n'); JLabel resultLabel = new JLabel("Result:"); bsearch.addActionListener(this); bopen.addActionListener(this); bopennew.addActionListener(this); binsert.addActionListener(this); list.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent event) { if (event.getClickCount() == 2) { String selected = list.getSelectedValue(); String resname = selected.substring(0, selected.indexOf(" - ")); ResourceEntry entry = ResourceFactory.getResourceEntry(resname); NearInfinity.getInstance().showResourceEntry(entry); } } }); addWindowListener(new WindowAdapter() { @Override public void windowOpened(WindowEvent event) { tfield.requestFocus(); } }); JPanel lpanel2 = new JPanel(); lpanel2.setLayout(new FlowLayout()); lpanel2.add(binsert); lpanel2.add(bopen); lpanel2.add(bopennew); bpanel = new JPanel(); bpanel.setLayout(cards); bpanel.add(lpanel2, "Button"); bpanel.add(progress, "Progress"); cards.show(bpanel, "Button"); JPanel rbpanel = new JPanel(); rbpanel.setLayout(new GridLayout(1, 4, 3, 3)); rbpanel.add(rbcre); rbpanel.add(rbitm); rbpanel.add(rbspl); rbpanel.add(rbsto); rbpanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Find:"), BorderFactory.createEmptyBorder(3, 6, 3, 3))); JPanel pane = (JPanel)getContentPane(); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); pane.setLayout(gbl); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.0; gbc.weighty = 0.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(6, 4, 3, 5); gbl.setConstraints(rbpanel, gbc); pane.add(rbpanel); gbc.fill = GridBagConstraints.NONE; gbc.gridwidth = 1; gbc.insets = new Insets(3, 6, 3, 3); gbl.setConstraints(label, gbc); pane.add(label); gbc.weightx = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.SOUTH; gbc.insets.left = 3; tfield.setPreferredSize(new Dimension((int)tfield.getPreferredSize().getWidth(), (int)bsearch.getPreferredSize().getHeight())); gbl.setConstraints(tfield, gbc); pane.add(tfield); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weightx = 0.0; gbc.insets = new Insets(6, 3, 3, 7); gbl.setConstraints(bsearch, gbc); pane.add(bsearch); gbc.anchor = GridBagConstraints.CENTER; gbc.insets.left = 6; gbc.insets.bottom = 0; gbl.setConstraints(resultLabel, gbc); pane.add(resultLabel); gbc.insets = new Insets(3, 4, 3, 5); gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; gbl.setConstraints(scroll, gbc); pane.add(scroll); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.0; gbc.weighty = 0.0; gbc.insets = new Insets(3, 6, 6, 7); gbl.setConstraints(bpanel, gbc); pane.add(bpanel); setSize(500, 450); Center.center(this, NearInfinity.getInstance().getBounds()); } // --------------------- Begin Interface ActionListener --------------------- @Override public void actionPerformed(ActionEvent event) { if (event.getSource() == tfield || event.getSource() == bsearch) { if (tfield.getText() == null || tfield.getText().equals("")) return; new Thread(this).start(); } else if (event.getSource() == bopen) { String selected = list.getSelectedValue(); String resname = selected.substring(0, selected.indexOf(" - ")); ResourceEntry entry = ResourceFactory.getResourceEntry(resname); NearInfinity.getInstance().showResourceEntry(entry); } else if (event.getSource() == bopennew) { String selected = list.getSelectedValue(); String resname = selected.substring(0, selected.indexOf(" - ")); new ViewFrame(this, ResourceFactory.getResource(ResourceFactory.getResourceEntry(resname))); } else if (event.getSource() == binsert) { Viewable viewable = NearInfinity.getInstance().getViewable(); if (viewable == null || !(viewable instanceof BcsResource)) { JOptionPane.showMessageDialog(this, "No script displayed in the main window", "Error", JOptionPane.ERROR_MESSAGE); return; } String selected = list.getSelectedValue(); String resname = selected.substring(0, selected.indexOf(".")); ((BcsResource)viewable).insertString('\"' + resname + '\"'); } } // --------------------- End Interface ActionListener --------------------- // --------------------- Begin Interface ListSelectionListener --------------------- @Override public void valueChanged(ListSelectionEvent event) { bopen.setEnabled(true); bopennew.setEnabled(true); binsert.setEnabled(true); } // --------------------- End Interface ListSelectionListener --------------------- // --------------------- Begin Interface Runnable --------------------- @Override public void run() { list.setEnabled(false); tfield.setEnabled(false); list.clearSelection(); bsearch.setEnabled(false); bopen.setEnabled(false); bopennew.setEnabled(false); binsert.setEnabled(false); list.setListData(new String[]{}); rbcre.setEnabled(false); rbitm.setEnabled(false); rbspl.setEnabled(false); rbsto.setEnabled(false); String selectedtype = ""; if (rbcre.isSelected()) selectedtype = "CRE"; else if (rbitm.isSelected()) selectedtype = "ITM"; else if (rbspl.isSelected()) selectedtype = "SPL"; else if (rbsto.isSelected()) selectedtype = "STO"; List<ResourceEntry> resources = ResourceFactory.getResources(selectedtype); String expr = tfield.getText().toLowerCase(Locale.ENGLISH); List<String> found = new ArrayList<String>(); cards.show(bpanel, "Progress"); progress.setMaximum(resources.size()); for (int i = 0; i < resources.size(); i++) { ResourceEntry entry = resources.get(i); String string = entry.getSearchString(); if (string != null && string.toLowerCase(Locale.ENGLISH).indexOf(expr) != -1) found.add(entry.toString() + " - " + string); progress.setValue(i + 1); } cards.show(bpanel, "Button"); progress.setValue(0); list.ensureIndexIsVisible(0); if (found.size() > 0) { Collections.sort(found); list.setListData(found.toArray(new String[found.size()])); list.setEnabled(true); } rbcre.setEnabled(true); rbitm.setEnabled(true); rbspl.setEnabled(true); rbsto.setEnabled(true); tfield.setEnabled(true); bsearch.setEnabled(true); } // --------------------- End Interface Runnable --------------------- }