diff --git a/src/me/ByteEdit/boxes/GlobalSearchBox.java b/src/me/ByteEdit/boxes/GlobalSearchBox.java new file mode 100644 index 0000000..e2fced0 --- /dev/null +++ b/src/me/ByteEdit/boxes/GlobalSearchBox.java @@ -0,0 +1,189 @@ +package me.ByteEdit.boxes; + +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.HashSet; +import java.util.Set; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; + +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import me.ByteEdit.boxes.GlobalSearchOpenBox.Info; +import me.ByteEdit.main.Main; + +public class GlobalSearchBox extends JFrame { + + public JPanel contentPane; + public JTextField txtString; + public JCheckBox chckbxCaseSensitive; + private JLabel lblOwner; + private JTextField txtOwner; + private JLabel lblName; + private JTextField txtName; + private JLabel lblDesc; + private JTextField txtDesc; + private GlobalSearchOpenBox openBox; + + public GlobalSearchBox() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + openBox = new GlobalSearchOpenBox(); + setResizable(false); + setTitle("Global Search"); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 128), + (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 181), 256, 262); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + JLabel lblFind = new JLabel("String Search"); + lblFind.setBounds(10, 25, 71, 14); + contentPane.add(lblFind); + txtString = new JTextField(); + KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); + txtString.registerKeyboardAction(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + find(); + } + }, enter, JComponent.WHEN_IN_FOCUSED_WINDOW); + txtString.setBounds(91, 22, 149, 20); + contentPane.add(txtString); + txtString.setColumns(10); + chckbxCaseSensitive = new JCheckBox("Case sensitive"); + chckbxCaseSensitive.setBounds(10, 199, 114, 23); + contentPane.add(chckbxCaseSensitive); + JButton btnFind = new JButton("Find"); + btnFind.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + find(); + } + }); + btnFind.setBounds(130, 199, 110, 23); + contentPane.add(btnFind); + + JLabel lblFieldmethodSearch = new JLabel("Field/Method Search"); + lblFieldmethodSearch.setBounds(10, 53, 230, 14); + contentPane.add(lblFieldmethodSearch); + + lblOwner = new JLabel("Owner"); + lblOwner.setBounds(10, 81, 71, 14); + contentPane.add(lblOwner); + + txtOwner = new JTextField(); + txtOwner.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + find(); + } + }); + txtOwner.setColumns(10); + txtOwner.setBounds(91, 78, 149, 20); + contentPane.add(txtOwner); + + lblName = new JLabel("Name"); + lblName.setBounds(10, 109, 71, 14); + contentPane.add(lblName); + + txtName = new JTextField(); + txtName.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + find(); + } + }); + txtName.setColumns(10); + txtName.setBounds(91, 106, 149, 20); + contentPane.add(txtName); + + lblDesc = new JLabel("Desc"); + lblDesc.setBounds(10, 137, 71, 14); + contentPane.add(lblDesc); + + txtDesc = new JTextField(); + txtDesc.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + find(); + } + }); + txtDesc.setColumns(10); + txtDesc.setBounds(91, 134, 149, 20); + contentPane.add(txtDesc); + } + + public void find() { + boolean ignoreCase = !chckbxCaseSensitive.isSelected(); + openBox.model.clear(); + Set set = new HashSet<>(); + if (!txtString.getText().isEmpty()) { + String str = txtString.getText(); + if (ignoreCase) { + str = str.toLowerCase(); + } + for (ClassNode cn : Main.classNodes.values()) { + for (MethodNode mn : cn.methods) { + for (AbstractInsnNode insn : mn.instructions.toArray()) { + if (insn instanceof LdcInsnNode && ((LdcInsnNode) insn).cst instanceof String) { + String s = (String) ((LdcInsnNode) insn).cst; + if (ignoreCase) { + s = s.toLowerCase(); + } + if (s.startsWith(str)) { + set.add(new Info(cn.name, mn.name, mn.desc, mn)); + } + } + } + } + } + } else { + String owner = txtOwner.getText(); + String name = txtName.getText(); + String desc = txtDesc.getText(); + for (ClassNode cn : Main.classNodes.values()) { + for (MethodNode mn : cn.methods) { + for (AbstractInsnNode insn : mn.instructions.toArray()) { + if (insn instanceof FieldInsnNode) { + if (((FieldInsnNode) insn).owner.equals(owner) && ((FieldInsnNode) insn).name.equals(name) + && ((FieldInsnNode) insn).desc.equals(desc)) { + set.add(new Info(cn.name, mn.name, mn.desc, mn)); + } + } else if (insn instanceof MethodInsnNode) { + if (((MethodInsnNode) insn).owner.equals(owner) && ((MethodInsnNode) insn).name.equals(name) + && ((MethodInsnNode) insn).desc.equals(desc)) { + set.add(new Info(cn.name, mn.name, mn.desc, mn)); + } + } + } + } + } + } + for (Info s : set) { + openBox.model.addElement(s); + } + openBox.setVisible(true); + } +} diff --git a/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java b/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java new file mode 100644 index 0000000..bc82403 --- /dev/null +++ b/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java @@ -0,0 +1,135 @@ +package me.ByteEdit.boxes; + +import java.awt.Toolkit; + +import javax.swing.DefaultListModel; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.text.BadLocationException; + +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; + +import me.ByteEdit.main.Main; + +public class GlobalSearchOpenBox extends JFrame { + + public JPanel contentPane; + DefaultListModel model; + + public GlobalSearchOpenBox() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + setResizable(false); + setTitle("Global Search - Result"); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 200), + (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 140), 400, 280); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + + model = new DefaultListModel<>(); + JList list = new JList(model); + list.addListSelectionListener(new ListSelectionListener() { + + public void valueChanged(ListSelectionEvent e) { + Info val = list.getSelectedValue(); + if (val != null && !val.owner.equals(Main.currentNodeName)) { + int lineFound = Main.selectFileWithSearch(val.nodePath, val.mn); + if (lineFound != -1) { + try { + Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound)); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } + } + } + } + }); + + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBounds(10, 11, 374, 229); + contentPane.add(scrollPane); + + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + scrollPane.setViewportView(list); + } + + static class Info { + String owner; + String name; + String desc; + MethodNode mn; + String nodePath; + + public Info(String owner, String name, String desc, MethodNode mn) { + this.owner = owner; + this.name = name; + this.desc = desc; + this.mn = mn; + nodePath = owner + ".class"; + } + + @Override + public String toString() { + return owner + "/" + name + " " + desc; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((desc == null) ? 0 : desc.hashCode()); + result = prime * result + ((mn == null) ? 0 : mn.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((owner == null) ? 0 : owner.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Info other = (Info) obj; + if (desc == null) { + if (other.desc != null) + return false; + } else if (!desc.equals(other.desc)) + return false; + if (mn == null) { + if (other.mn != null) + return false; + } else if (!mn.equals(other.mn)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (owner == null) { + if (other.owner != null) + return false; + } else if (!owner.equals(other.owner)) + return false; + return true; + } + + } + +} diff --git a/src/me/ByteEdit/main/Main.java b/src/me/ByteEdit/main/Main.java index d18307e..17332d4 100644 --- a/src/me/ByteEdit/main/Main.java +++ b/src/me/ByteEdit/main/Main.java @@ -72,6 +72,7 @@ import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; import me.ByteEdit.boxes.CompilationBox; +import me.ByteEdit.boxes.GlobalSearchBox; import me.ByteEdit.boxes.OptionBox; import me.ByteEdit.boxes.RenameBox; import me.ByteEdit.boxes.SearchBox; @@ -94,6 +95,7 @@ public class Main extends JFrame { public static HashMap classNodes = new HashMap<>(); public static String currentNodeName; public static RSyntaxTextArea txtByteEditView; + public static GlobalSearchBox globalSearchBox; public static SearchBox searchBox; public static TypeOpenBox typeOpenBox; public static OptionBox optionBox; @@ -195,6 +197,7 @@ public class Main extends JFrame { } catch (IOException e2) { e2.printStackTrace(); } + globalSearchBox = new GlobalSearchBox(); searchBox = new SearchBox(); typeOpenBox = new TypeOpenBox(); optionBox = new OptionBox(); @@ -299,6 +302,7 @@ public class Main extends JFrame { } txtByteEditView.setText(""); currentNodeName = null; + globalSearchBox.setVisible(false); searchBox.setVisible(false); typeOpenBox.setVisible(false); optionBox.setVisible(false); @@ -373,6 +377,15 @@ public class Main extends JFrame { KeyStroke ctrlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK); KeyStroke ctrlE = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK); // global + txtByteEditView.registerKeyboardAction(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + globalSearchBox.setVisible(true); +// globalSearchBox.txtFind.requestFocusInWindow(); +// globalSearchBox.txtFind.select(0, searchBox.txtFind.getText().length()); + } + }, ctrlG, JComponent.WHEN_IN_FOCUSED_WINDOW); txtByteEditView.registerKeyboardAction(new ActionListener() { @Override