case insensitive option for searches
This commit is contained in:
committed by
Jan Peter Stotz
parent
d9b0365c9f
commit
f0a57e6714
@@ -54,6 +54,7 @@ public abstract class CommonSearchDialog extends JDialog {
|
||||
protected ProgressPanel progressPane;
|
||||
|
||||
protected String highlightText;
|
||||
protected boolean highlightTextCaseInsensitive = false;
|
||||
|
||||
public CommonSearchDialog(MainWindow mainWindow) {
|
||||
super(mainWindow);
|
||||
@@ -359,7 +360,7 @@ public abstract class CommonSearchDialog extends JDialog {
|
||||
textArea.setColumns(textArea.getText().length());
|
||||
if (highlightText != null) {
|
||||
SearchContext searchContext = new SearchContext(highlightText);
|
||||
searchContext.setMatchCase(true);
|
||||
searchContext.setMatchCase(!highlightTextCaseInsensitive);
|
||||
searchContext.setMarkAll(true);
|
||||
SearchEngine.markAll(textArea, searchContext);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
private Set<SearchOptions> options = EnumSet.allOf(SearchOptions.class);
|
||||
|
||||
private JTextField searchField;
|
||||
private JCheckBox caseChBox;
|
||||
|
||||
public SearchDialog(MainWindow mainWindow, Set<SearchOptions> options) {
|
||||
super(mainWindow);
|
||||
@@ -65,19 +66,21 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
resultsTable.updateTable();
|
||||
return;
|
||||
}
|
||||
boolean caseInsensitive = caseChBox.isSelected();
|
||||
if (options.contains(SearchOptions.CLASS)) {
|
||||
resultsModel.addAll(index.searchClsName(text));
|
||||
resultsModel.addAll(index.searchClsName(text, caseInsensitive));
|
||||
}
|
||||
if (options.contains(SearchOptions.METHOD)) {
|
||||
resultsModel.addAll(index.searchMthName(text));
|
||||
resultsModel.addAll(index.searchMthName(text, caseInsensitive));
|
||||
}
|
||||
if (options.contains(SearchOptions.FIELD)) {
|
||||
resultsModel.addAll(index.searchFldName(text));
|
||||
resultsModel.addAll(index.searchFldName(text, caseInsensitive));
|
||||
}
|
||||
if (options.contains(SearchOptions.CODE)) {
|
||||
resultsModel.addAll(index.searchCode(text));
|
||||
resultsModel.addAll(index.searchCode(text, caseInsensitive));
|
||||
}
|
||||
highlightText = text;
|
||||
highlightTextCaseInsensitive = caseInsensitive;
|
||||
resultsTable.updateTable();
|
||||
}
|
||||
|
||||
@@ -114,24 +117,38 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
|
||||
private void initUI() {
|
||||
JLabel findLabel = new JLabel(NLS.str("search_dialog.open_by_name"));
|
||||
|
||||
searchField = new JTextField();
|
||||
searchField.setAlignmentX(LEFT_ALIGNMENT);
|
||||
searchField.getDocument().addDocumentListener(new SearchFieldListener());
|
||||
new TextStandardActions(searchField);
|
||||
|
||||
caseChBox = new JCheckBox(NLS.str("search_dialog.ignorecase"));
|
||||
caseChBox.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
performSearch();
|
||||
}
|
||||
});
|
||||
|
||||
JCheckBox clsChBox = makeOptionsCheckBox(NLS.str("search_dialog.class"), SearchOptions.CLASS);
|
||||
JCheckBox mthChBox = makeOptionsCheckBox(NLS.str("search_dialog.method"), SearchOptions.METHOD);
|
||||
JCheckBox fldChBox = makeOptionsCheckBox(NLS.str("search_dialog.field"), SearchOptions.FIELD);
|
||||
JCheckBox codeChBox = makeOptionsCheckBox(NLS.str("search_dialog.code"), SearchOptions.CODE);
|
||||
|
||||
JPanel searchInPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
searchInPanel.setBorder(BorderFactory.createTitledBorder(NLS.str("search_dialog.search_in")));
|
||||
searchInPanel.add(clsChBox);
|
||||
searchInPanel.add(mthChBox);
|
||||
searchInPanel.add(fldChBox);
|
||||
searchInPanel.add(codeChBox);
|
||||
|
||||
JPanel searchOptions = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
searchOptions.setBorder(BorderFactory.createTitledBorder(NLS.str("search_dialog.search_in")));
|
||||
searchOptions.add(clsChBox);
|
||||
searchOptions.add(mthChBox);
|
||||
searchOptions.add(fldChBox);
|
||||
searchOptions.add(codeChBox);
|
||||
searchOptions.setAlignmentX(LEFT_ALIGNMENT);
|
||||
searchOptions.setBorder(BorderFactory.createTitledBorder(NLS.str("search_dialog.options")));
|
||||
searchOptions.add(caseChBox);
|
||||
|
||||
Box box = Box.createHorizontalBox();
|
||||
box.setAlignmentX(LEFT_ALIGNMENT);
|
||||
box.add(searchInPanel);
|
||||
box.add(searchOptions);
|
||||
|
||||
JPanel searchPane = new JPanel();
|
||||
searchPane.setLayout(new BoxLayout(searchPane, BoxLayout.PAGE_AXIS));
|
||||
@@ -140,7 +157,7 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
searchPane.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||
searchPane.add(searchField);
|
||||
searchPane.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||
searchPane.add(searchOptions);
|
||||
searchPane.add(box);
|
||||
searchPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
|
||||
initCommon();
|
||||
|
||||
@@ -109,4 +109,11 @@ public class Utils {
|
||||
private static String format(long mem) {
|
||||
return Long.toString((long) (mem / 1024. / 1024.)) + "MB";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt character case for case insensitive searches
|
||||
*/
|
||||
public static char caseChar(char ch, boolean toLower) {
|
||||
return toLower ? Character.toLowerCase(ch) : ch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
public class CodeIndex<T> implements SearchIndex<T> {
|
||||
|
||||
private final List<StringRef> keys = new ArrayList<>();
|
||||
private final List<T> values = new ArrayList<>();
|
||||
private final List<T> values = new ArrayList<T>();
|
||||
|
||||
@Override
|
||||
public void put(String str, T value) {
|
||||
@@ -29,15 +29,18 @@ public class CodeIndex<T> implements SearchIndex<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getValuesForKeysContaining(String str) {
|
||||
public List<T> getValuesForKeysContaining(String str, boolean caseInsensitive) {
|
||||
int size = size();
|
||||
if (size == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (caseInsensitive) {
|
||||
str = str.toLowerCase();
|
||||
}
|
||||
List<T> results = new ArrayList<>();
|
||||
for (int i = 0; i < size; i++) {
|
||||
StringRef key = keys.get(i);
|
||||
if (key.indexOf(str) != -1) {
|
||||
if (key.indexOf(str, caseInsensitive) != -1) {
|
||||
results.add(values.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public interface SearchIndex<V> {
|
||||
|
||||
boolean isStringRefSupported();
|
||||
|
||||
List<V> getValuesForKeysContaining(String str);
|
||||
List<V> getValuesForKeysContaining(String str, boolean caseInsensitive);
|
||||
|
||||
int size();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
public class SimpleIndex<T> implements SearchIndex<T> {
|
||||
|
||||
private final List<String> keys = new ArrayList<>();
|
||||
private final List<T> values = new ArrayList<>();
|
||||
private final List<T> values = new ArrayList<T>();
|
||||
|
||||
@Override
|
||||
public void put(String str, T value) {
|
||||
@@ -26,14 +26,20 @@ public class SimpleIndex<T> implements SearchIndex<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getValuesForKeysContaining(String str) {
|
||||
public List<T> getValuesForKeysContaining(String str, boolean caseInsensitive) {
|
||||
int size = size();
|
||||
if (size == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (caseInsensitive) {
|
||||
str = str.toLowerCase();
|
||||
}
|
||||
List<T> results = new ArrayList<>();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String key = keys.get(i);
|
||||
if (caseInsensitive) {
|
||||
key = key.toLowerCase();
|
||||
}
|
||||
if (key.contains(str)) {
|
||||
results.add(values.get(i));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.gui.utils.search;
|
||||
|
||||
import static jadx.gui.utils.Utils.caseChar;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -68,13 +69,21 @@ public class StringRef implements CharSequence {
|
||||
return indexOf(str, 0);
|
||||
}
|
||||
|
||||
public int indexOf(String str, boolean caseInsensitive) {
|
||||
return indexOf(str, 0, caseInsensitive);
|
||||
}
|
||||
|
||||
public int indexOf(String str, int from, boolean caseInsensitive) {
|
||||
return indexOf(refStr, offset, length, str, 0, str.length(), from, caseInsensitive);
|
||||
}
|
||||
|
||||
public int indexOf(String str, int from) {
|
||||
return indexOf(refStr, offset, length, str, 0, str.length(), from);
|
||||
return indexOf(refStr, offset, length, str, 0, str.length(), from, false);
|
||||
}
|
||||
|
||||
private static int indexOf(String source, int sourceOffset, int sourceCount,
|
||||
String target, int targetOffset, int targetCount,
|
||||
int fromIndex) {
|
||||
int fromIndex, boolean caseInsensitive) {
|
||||
if (fromIndex >= sourceCount) {
|
||||
return (targetCount == 0 ? sourceCount : -1);
|
||||
}
|
||||
@@ -84,18 +93,18 @@ public class StringRef implements CharSequence {
|
||||
if (targetCount == 0) {
|
||||
return -1;
|
||||
}
|
||||
char first = target.charAt(targetOffset);
|
||||
char first = caseChar(target.charAt(targetOffset), caseInsensitive);
|
||||
int max = sourceOffset + (sourceCount - targetCount);
|
||||
for (int i = sourceOffset + fromIndex; i <= max; i++) {
|
||||
if (source.charAt(i) != first) {
|
||||
while (++i <= max && source.charAt(i) != first) {
|
||||
if (caseChar(source.charAt(i), caseInsensitive) != first) {
|
||||
while (++i <= max && caseChar(source.charAt(i), caseInsensitive) != first) {
|
||||
}
|
||||
}
|
||||
if (i <= max) {
|
||||
int j = i + 1;
|
||||
int end = j + targetCount - 1;
|
||||
int k = targetOffset + 1;
|
||||
while (j < end && source.charAt(j) == target.charAt(k)) {
|
||||
while (j < end && caseChar(source.charAt(j), caseInsensitive) == caseChar(target.charAt(k), caseInsensitive)) {
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
@@ -117,7 +126,7 @@ public class StringRef implements CharSequence {
|
||||
List<StringRef> list = new ArrayList<>();
|
||||
while (true) {
|
||||
int start = pos + targetLen;
|
||||
pos = indexOf(str, 0, len, splitBy, 0, targetLen, start);
|
||||
pos = indexOf(str, 0, len, splitBy, 0, targetLen, start, false);
|
||||
if (pos == -1) {
|
||||
if (start != len) {
|
||||
list.add(subString(str, start, len));
|
||||
@@ -178,4 +187,5 @@ public class StringRef implements CharSequence {
|
||||
int offset = this.offset;
|
||||
return refStr.substring(offset, offset + len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,22 +73,22 @@ public class TextSearchIndex {
|
||||
}
|
||||
}
|
||||
|
||||
public List<JNode> searchClsName(String text) {
|
||||
return clsNamesIndex.getValuesForKeysContaining(text);
|
||||
public List<JNode> searchClsName(String text, boolean caseInsensitive) {
|
||||
return clsNamesIndex.getValuesForKeysContaining(text, caseInsensitive);
|
||||
}
|
||||
|
||||
public List<JNode> searchMthName(String text) {
|
||||
return mthNamesIndex.getValuesForKeysContaining(text);
|
||||
public List<JNode> searchMthName(String text, boolean caseInsensitive) {
|
||||
return mthNamesIndex.getValuesForKeysContaining(text, caseInsensitive);
|
||||
}
|
||||
|
||||
public List<JNode> searchFldName(String text) {
|
||||
return fldNamesIndex.getValuesForKeysContaining(text);
|
||||
public List<JNode> searchFldName(String text, boolean caseInsensitive) {
|
||||
return fldNamesIndex.getValuesForKeysContaining(text, caseInsensitive);
|
||||
}
|
||||
|
||||
public List<CodeNode> searchCode(String text) {
|
||||
public List<CodeNode> searchCode(String text, boolean caseInsensitive) {
|
||||
List<CodeNode> items;
|
||||
if (codeIndex.size() > 0) {
|
||||
items = codeIndex.getValuesForKeysContaining(text);
|
||||
items = codeIndex.getValuesForKeysContaining(text, caseInsensitive);
|
||||
if (skippedClasses.isEmpty()) {
|
||||
return items;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user