2021-06-26 01:13:46 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer.gui.resourcesearch;
|
2018-01-31 15:03:53 +00:00
|
|
|
|
|
|
|
import java.awt.BorderLayout;
|
|
|
|
import java.awt.GridLayout;
|
|
|
|
import java.awt.event.ItemListener;
|
2021-07-30 02:37:05 +00:00
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
|
import java.awt.event.MouseEvent;
|
2021-04-12 22:31:22 +00:00
|
|
|
import java.util.Objects;
|
2021-08-26 21:59:07 +00:00
|
|
|
import javax.swing.DefaultComboBoxModel;
|
|
|
|
import javax.swing.JButton;
|
|
|
|
import javax.swing.JCheckBox;
|
|
|
|
import javax.swing.JComboBox;
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
import javax.swing.JPopupMenu;
|
|
|
|
import javax.swing.JScrollPane;
|
|
|
|
import javax.swing.JTree;
|
2021-07-09 01:58:27 +00:00
|
|
|
import javax.swing.tree.DefaultTreeModel;
|
2021-07-30 03:28:10 +00:00
|
|
|
import javax.swing.tree.TreePath;
|
2021-04-12 20:19:12 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
2021-07-30 03:28:10 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.gui.contextmenu.ContextMenu;
|
2021-06-26 01:13:46 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
|
2021-04-12 20:19:12 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.searching.BackgroundSearchThread;
|
2021-07-30 02:32:32 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.searching.LDCSearchTreeNodeResult;
|
2021-07-21 13:54:29 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
|
2021-08-26 21:59:07 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedDefaultMutableTreeNode;
|
|
|
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJButton;
|
|
|
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBox;
|
|
|
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJLabel;
|
|
|
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedVisibleComponent;
|
2018-01-31 15:03:53 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
|
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
|
|
|
* *
|
|
|
|
* This program 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/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A pane dedicating to searching the loaded files.
|
2018-01-31 15:41:24 +00:00
|
|
|
*
|
2018-01-31 15:03:53 +00:00
|
|
|
* @author Konloch
|
|
|
|
* @author WaterWolf
|
2021-07-04 07:03:40 +00:00
|
|
|
* @since 09/29/2011
|
2018-01-31 15:03:53 +00:00
|
|
|
*/
|
2021-07-07 10:39:29 +00:00
|
|
|
public class SearchBoxPane extends TranslatedVisibleComponent
|
2021-06-26 01:13:46 +00:00
|
|
|
{
|
2021-04-12 22:31:22 +00:00
|
|
|
public static final SearchRadius[] SEARCH_RADII = SearchRadius.values();
|
|
|
|
public static final SearchType[] SEARCH_TYPES = SearchType.values();
|
2018-01-31 15:03:53 +00:00
|
|
|
|
2021-07-21 13:54:29 +00:00
|
|
|
public final JCheckBox exact = new TranslatedJCheckBox("Exact", TranslatedComponents.EXACT);
|
|
|
|
public final TranslatedDefaultMutableTreeNode treeRoot = new TranslatedDefaultMutableTreeNode("Results", TranslatedComponents.RESULTS);
|
2021-06-22 18:05:25 +00:00
|
|
|
public final JTree tree;
|
2021-07-30 02:32:32 +00:00
|
|
|
public final JComboBox<SearchType> typeBox;
|
2021-06-22 18:05:25 +00:00
|
|
|
|
|
|
|
public SearchType searchType = null;
|
|
|
|
public final JComboBox searchRadiusBox;
|
2021-07-30 03:28:10 +00:00
|
|
|
public final JPopupMenu rightClickMenu = new JPopupMenu();
|
2018-01-31 15:03:53 +00:00
|
|
|
|
2021-07-21 13:54:29 +00:00
|
|
|
public JButton search = new TranslatedJButton("Search", TranslatedComponents.SEARCH);
|
2021-07-05 02:06:15 +00:00
|
|
|
public BackgroundSearchThread performSearchThread;
|
2018-01-31 15:03:53 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2021-07-05 02:06:15 +00:00
|
|
|
public SearchBoxPane()
|
|
|
|
{
|
2021-07-21 13:54:29 +00:00
|
|
|
super("Search", TranslatedComponents.SEARCH);
|
2018-01-31 15:03:53 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
final JPanel optionPanel = new JPanel(new BorderLayout());
|
|
|
|
final JPanel searchRadiusOpt = new JPanel(new BorderLayout());
|
|
|
|
final JPanel searchOpts = new JPanel(new GridLayout(2, 1));
|
|
|
|
|
2021-07-21 13:54:29 +00:00
|
|
|
searchRadiusOpt.add(new TranslatedJLabel("Search from ", TranslatedComponents.SEARCH_FROM), BorderLayout.WEST);
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
DefaultComboBoxModel model = new DefaultComboBoxModel();
|
2021-07-05 02:06:15 +00:00
|
|
|
|
|
|
|
for (final SearchRadius st : SEARCH_RADII)
|
2018-01-31 15:41:24 +00:00
|
|
|
model.addElement(st);
|
|
|
|
|
|
|
|
searchRadiusBox = new JComboBox(model);
|
|
|
|
searchRadiusOpt.add(searchRadiusBox, BorderLayout.CENTER);
|
|
|
|
searchOpts.add(searchRadiusOpt);
|
|
|
|
|
|
|
|
model = new DefaultComboBoxModel();
|
2021-06-22 18:05:25 +00:00
|
|
|
for (final SearchType st : SEARCH_TYPES)
|
2018-01-31 15:41:24 +00:00
|
|
|
model.addElement(st);
|
|
|
|
|
2021-07-30 02:32:32 +00:00
|
|
|
typeBox = new JComboBox<SearchType>(model);
|
2018-01-31 15:41:24 +00:00
|
|
|
final JPanel searchOptPanel = new JPanel();
|
|
|
|
|
2021-04-12 22:31:22 +00:00
|
|
|
final ItemListener il = arg0 -> {
|
|
|
|
searchOptPanel.removeAll();
|
|
|
|
searchType = (SearchType) typeBox.getSelectedItem();
|
2021-07-30 02:32:32 +00:00
|
|
|
searchOptPanel.add(Objects.requireNonNull(searchType).panel.getPanel());
|
2018-01-31 15:41:24 +00:00
|
|
|
|
2021-04-12 22:31:22 +00:00
|
|
|
searchOptPanel.revalidate();
|
|
|
|
searchOptPanel.repaint();
|
2018-01-31 15:41:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typeBox.addItemListener(il);
|
|
|
|
|
2019-04-17 06:45:15 +00:00
|
|
|
typeBox.setSelectedItem(SearchType.Strings);
|
2018-01-31 15:41:24 +00:00
|
|
|
il.itemStateChanged(null);
|
|
|
|
|
|
|
|
searchOpts.add(typeBox);
|
|
|
|
|
|
|
|
optionPanel.add(searchOpts, BorderLayout.NORTH);
|
|
|
|
|
2021-07-08 00:53:57 +00:00
|
|
|
JPanel sharedPanel = new JPanel();
|
|
|
|
sharedPanel.setLayout(new BorderLayout());
|
|
|
|
sharedPanel.add(searchOptPanel, BorderLayout.NORTH);
|
|
|
|
sharedPanel.add(exact, BorderLayout.SOUTH);
|
2018-01-31 15:41:24 +00:00
|
|
|
|
2021-07-08 00:53:57 +00:00
|
|
|
optionPanel.add(sharedPanel, BorderLayout.CENTER);
|
2018-01-31 15:41:24 +00:00
|
|
|
|
2021-04-12 22:31:22 +00:00
|
|
|
search.addActionListener(arg0 -> search());
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
optionPanel.add(search, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
this.tree = new JTree(treeRoot);
|
2021-07-09 01:58:27 +00:00
|
|
|
treeRoot.setTree((DefaultTreeModel) tree.getModel());
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
getContentPane().setLayout(new BorderLayout());
|
|
|
|
|
2021-07-08 00:53:57 +00:00
|
|
|
getContentPane().add(optionPanel, BorderLayout.NORTH);
|
2018-01-31 15:41:24 +00:00
|
|
|
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
2021-07-30 02:37:05 +00:00
|
|
|
|
|
|
|
tree.addMouseListener(new MouseAdapter()
|
2021-07-05 02:06:15 +00:00
|
|
|
{
|
2021-07-30 02:37:05 +00:00
|
|
|
@Override
|
|
|
|
public void mouseReleased(MouseEvent e)
|
More Translations
Most components should be translated. All of the components that were hardcoded for English now work with translations.
All of the translations now include any missing translation keys.
Added translations for: Farsi, Finnish, Greek, Indonesian, Bengali, Italian, Korean, Dutch, Polish, Swedish, Thai, Hebrew, Turkish, Ukrainian, Hungarian, Georgian, Javanese, Hausa, Swahili, Norwegian & Vietnamese
2021-07-08 08:22:39 +00:00
|
|
|
{
|
2021-07-30 02:37:05 +00:00
|
|
|
//TODO right-click context menu
|
|
|
|
if (e.isMetaDown())
|
|
|
|
{
|
2021-07-30 03:28:10 +00:00
|
|
|
TreePath selPath = SearchBoxPane.this.tree.getClosestPathForLocation(e.getX(), e.getY());
|
|
|
|
|
|
|
|
if (selPath == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//select the closest path
|
|
|
|
SearchBoxPane.this.tree.clearSelection();
|
|
|
|
SearchBoxPane.this.tree.addSelectionPath(selPath);
|
|
|
|
|
|
|
|
if(!(tree.getLastSelectedPathComponent() instanceof LDCSearchTreeNodeResult))
|
|
|
|
return;
|
|
|
|
|
|
|
|
//get selected path
|
|
|
|
LDCSearchTreeNodeResult result = (LDCSearchTreeNodeResult) tree.getLastSelectedPathComponent();
|
|
|
|
|
|
|
|
showContextMenu(result, e.getX(), e.getY());
|
2021-07-30 02:37:05 +00:00
|
|
|
}
|
|
|
|
else if (e.getButton() == MouseEvent.BUTTON1)
|
|
|
|
{
|
|
|
|
if(!(tree.getLastSelectedPathComponent() instanceof LDCSearchTreeNodeResult))
|
|
|
|
return;
|
|
|
|
|
|
|
|
LDCSearchTreeNodeResult result = (LDCSearchTreeNodeResult) tree.getLastSelectedPathComponent();
|
More Translations
Most components should be translated. All of the components that were hardcoded for English now work with translations.
All of the translations now include any missing translation keys.
Added translations for: Farsi, Finnish, Greek, Indonesian, Bengali, Italian, Korean, Dutch, Polish, Swedish, Thai, Hebrew, Turkish, Ukrainian, Hungarian, Georgian, Javanese, Hausa, Swahili, Norwegian & Vietnamese
2021-07-08 08:22:39 +00:00
|
|
|
|
2021-07-30 02:37:05 +00:00
|
|
|
final String name = result.resourceWorkingName;
|
More Translations
Most components should be translated. All of the components that were hardcoded for English now work with translations.
All of the translations now include any missing translation keys.
Added translations for: Farsi, Finnish, Greek, Indonesian, Bengali, Italian, Korean, Dutch, Polish, Swedish, Thai, Hebrew, Turkish, Ukrainian, Hungarian, Georgian, Javanese, Hausa, Swahili, Norwegian & Vietnamese
2021-07-08 08:22:39 +00:00
|
|
|
|
2021-07-30 02:37:05 +00:00
|
|
|
BytecodeViewer.viewer.workPane.addClassResource(result.container, name);
|
|
|
|
}
|
More Translations
Most components should be translated. All of the components that were hardcoded for English now work with translations.
All of the translations now include any missing translation keys.
Added translations for: Farsi, Finnish, Greek, Indonesian, Bengali, Italian, Korean, Dutch, Polish, Swedish, Thai, Hebrew, Turkish, Ukrainian, Hungarian, Georgian, Javanese, Hausa, Swahili, Norwegian & Vietnamese
2021-07-08 08:22:39 +00:00
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
this.setVisible(true);
|
2021-07-30 03:28:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void resetWorkspace()
|
|
|
|
{
|
|
|
|
treeRoot.removeAllChildren();
|
|
|
|
tree.updateUI();
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
2021-07-05 02:06:15 +00:00
|
|
|
public void search()
|
|
|
|
{
|
2019-04-17 06:45:15 +00:00
|
|
|
treeRoot.removeAllChildren();
|
|
|
|
searchType = (SearchType) typeBox.getSelectedItem();
|
2021-07-05 02:06:15 +00:00
|
|
|
final SearchRadius radius = (SearchRadius) searchRadiusBox.getSelectedItem();
|
|
|
|
|
|
|
|
if (radius == SearchRadius.All_Classes)
|
|
|
|
{
|
|
|
|
if (performSearchThread == null || performSearchThread.finished)
|
|
|
|
{
|
|
|
|
BytecodeViewer.viewer.searchBoxPane.search.setEnabled(false);
|
|
|
|
BytecodeViewer.viewer.searchBoxPane.search.setText("Searching, please wait..");
|
|
|
|
|
2021-07-30 02:32:32 +00:00
|
|
|
performSearchThread = new PerformSearch(this);
|
2021-07-05 02:06:15 +00:00
|
|
|
performSearchThread.start();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // this should really never be called.
|
2021-06-21 23:37:55 +00:00
|
|
|
BytecodeViewer.showMessage("You currently have a search performing in the background, please wait for that to finish.");
|
2019-04-17 06:45:15 +00:00
|
|
|
}
|
2021-07-05 02:06:15 +00:00
|
|
|
}
|
|
|
|
else if (radius == SearchRadius.Current_Class)
|
|
|
|
{
|
2021-07-07 03:05:35 +00:00
|
|
|
final ResourceViewer cv = BytecodeViewer.getActiveResource();
|
|
|
|
|
2021-07-05 02:06:15 +00:00
|
|
|
if (cv != null)
|
2021-07-30 02:32:32 +00:00
|
|
|
searchType.panel.search(cv.resource.container, cv.resource.workingName, cv.resource.getResourceClassNode(), exact.isSelected());
|
2019-04-17 06:45:15 +00:00
|
|
|
}
|
|
|
|
}
|
2021-06-26 01:13:46 +00:00
|
|
|
|
2021-07-30 03:28:10 +00:00
|
|
|
private void showContextMenu(LDCSearchTreeNodeResult selectedNode, int x, int y)
|
2021-07-05 02:06:15 +00:00
|
|
|
{
|
2021-07-30 03:28:10 +00:00
|
|
|
if (selectedNode == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ContextMenu.buildMenu(null, null, selectedNode, rightClickMenu);
|
|
|
|
rightClickMenu.show(this.tree, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Opens and decompiles the LDCSearchTreeNodeResult in a new tab
|
|
|
|
*/
|
|
|
|
public void quickDecompile(Decompiler decompiler, LDCSearchTreeNodeResult result, boolean quickEdit)
|
|
|
|
{
|
|
|
|
Decompiler tempDecompiler1 = BytecodeViewer.viewer.viewPane1.getSelectedDecompiler();
|
|
|
|
boolean editable1 = BytecodeViewer.viewer.viewPane1.isPaneEditable();
|
|
|
|
Decompiler tempDecompiler2 = BytecodeViewer.viewer.viewPane2.getSelectedDecompiler();
|
|
|
|
boolean editable2 = BytecodeViewer.viewer.viewPane2.isPaneEditable();
|
|
|
|
Decompiler tempDecompiler3 = BytecodeViewer.viewer.viewPane3.getSelectedDecompiler();
|
|
|
|
boolean editable3 = BytecodeViewer.viewer.viewPane3.isPaneEditable();
|
|
|
|
|
|
|
|
BytecodeViewer.viewer.viewPane1.setSelectedDecompiler(decompiler);
|
|
|
|
BytecodeViewer.viewer.viewPane1.setPaneEditable(quickEdit);
|
|
|
|
BytecodeViewer.viewer.viewPane2.setSelectedDecompiler(Decompiler.NONE);
|
|
|
|
BytecodeViewer.viewer.viewPane2.setPaneEditable(false);
|
|
|
|
BytecodeViewer.viewer.viewPane3.setSelectedDecompiler(Decompiler.NONE);
|
|
|
|
BytecodeViewer.viewer.viewPane3.setPaneEditable(false);
|
|
|
|
|
|
|
|
BytecodeViewer.viewer.workPane.addClassResource(result.container, result.resourceWorkingName);
|
|
|
|
|
|
|
|
BytecodeViewer.viewer.viewPane1.setSelectedDecompiler(tempDecompiler1);
|
|
|
|
BytecodeViewer.viewer.viewPane1.setPaneEditable(editable1);
|
|
|
|
BytecodeViewer.viewer.viewPane2.setSelectedDecompiler(tempDecompiler2);
|
|
|
|
BytecodeViewer.viewer.viewPane2.setPaneEditable(editable2);
|
|
|
|
BytecodeViewer.viewer.viewPane3.setSelectedDecompiler(tempDecompiler3);
|
|
|
|
BytecodeViewer.viewer.viewPane3.setPaneEditable(editable3);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-06-26 01:13:46 +00:00
|
|
|
|
2021-07-05 02:06:15 +00:00
|
|
|
private static final long serialVersionUID = -1098524689236993932L;
|
2021-08-26 21:59:07 +00:00
|
|
|
}
|