Commit f0a57e67 authored by Jan Peter Stotz's avatar Jan Peter Stotz Committed by Jan Peter Stotz

case insensitive option for searches

parent d9b0365c
...@@ -54,6 +54,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -54,6 +54,7 @@ public abstract class CommonSearchDialog extends JDialog {
protected ProgressPanel progressPane; protected ProgressPanel progressPane;
protected String highlightText; protected String highlightText;
protected boolean highlightTextCaseInsensitive = false;
public CommonSearchDialog(MainWindow mainWindow) { public CommonSearchDialog(MainWindow mainWindow) {
super(mainWindow); super(mainWindow);
...@@ -359,7 +360,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -359,7 +360,7 @@ public abstract class CommonSearchDialog extends JDialog {
textArea.setColumns(textArea.getText().length()); textArea.setColumns(textArea.getText().length());
if (highlightText != null) { if (highlightText != null) {
SearchContext searchContext = new SearchContext(highlightText); SearchContext searchContext = new SearchContext(highlightText);
searchContext.setMatchCase(true); searchContext.setMatchCase(!highlightTextCaseInsensitive);
searchContext.setMarkAll(true); searchContext.setMarkAll(true);
SearchEngine.markAll(textArea, searchContext); SearchEngine.markAll(textArea, searchContext);
} }
......
...@@ -31,6 +31,7 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -31,6 +31,7 @@ public class SearchDialog extends CommonSearchDialog {
private Set<SearchOptions> options = EnumSet.allOf(SearchOptions.class); private Set<SearchOptions> options = EnumSet.allOf(SearchOptions.class);
private JTextField searchField; private JTextField searchField;
private JCheckBox caseChBox;
public SearchDialog(MainWindow mainWindow, Set<SearchOptions> options) { public SearchDialog(MainWindow mainWindow, Set<SearchOptions> options) {
super(mainWindow); super(mainWindow);
...@@ -65,19 +66,21 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -65,19 +66,21 @@ public class SearchDialog extends CommonSearchDialog {
resultsTable.updateTable(); resultsTable.updateTable();
return; return;
} }
boolean caseInsensitive = caseChBox.isSelected();
if (options.contains(SearchOptions.CLASS)) { if (options.contains(SearchOptions.CLASS)) {
resultsModel.addAll(index.searchClsName(text)); resultsModel.addAll(index.searchClsName(text, caseInsensitive));
} }
if (options.contains(SearchOptions.METHOD)) { if (options.contains(SearchOptions.METHOD)) {
resultsModel.addAll(index.searchMthName(text)); resultsModel.addAll(index.searchMthName(text, caseInsensitive));
} }
if (options.contains(SearchOptions.FIELD)) { if (options.contains(SearchOptions.FIELD)) {
resultsModel.addAll(index.searchFldName(text)); resultsModel.addAll(index.searchFldName(text, caseInsensitive));
} }
if (options.contains(SearchOptions.CODE)) { if (options.contains(SearchOptions.CODE)) {
resultsModel.addAll(index.searchCode(text)); resultsModel.addAll(index.searchCode(text, caseInsensitive));
} }
highlightText = text; highlightText = text;
highlightTextCaseInsensitive = caseInsensitive;
resultsTable.updateTable(); resultsTable.updateTable();
} }
...@@ -114,24 +117,38 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -114,24 +117,38 @@ public class SearchDialog extends CommonSearchDialog {
private void initUI() { private void initUI() {
JLabel findLabel = new JLabel(NLS.str("search_dialog.open_by_name")); JLabel findLabel = new JLabel(NLS.str("search_dialog.open_by_name"));
searchField = new JTextField(); searchField = new JTextField();
searchField.setAlignmentX(LEFT_ALIGNMENT); searchField.setAlignmentX(LEFT_ALIGNMENT);
searchField.getDocument().addDocumentListener(new SearchFieldListener()); searchField.getDocument().addDocumentListener(new SearchFieldListener());
new TextStandardActions(searchField); 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 clsChBox = makeOptionsCheckBox(NLS.str("search_dialog.class"), SearchOptions.CLASS);
JCheckBox mthChBox = makeOptionsCheckBox(NLS.str("search_dialog.method"), SearchOptions.METHOD); JCheckBox mthChBox = makeOptionsCheckBox(NLS.str("search_dialog.method"), SearchOptions.METHOD);
JCheckBox fldChBox = makeOptionsCheckBox(NLS.str("search_dialog.field"), SearchOptions.FIELD); JCheckBox fldChBox = makeOptionsCheckBox(NLS.str("search_dialog.field"), SearchOptions.FIELD);
JCheckBox codeChBox = makeOptionsCheckBox(NLS.str("search_dialog.code"), SearchOptions.CODE); 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)); JPanel searchOptions = new JPanel(new FlowLayout(FlowLayout.LEFT));
searchOptions.setBorder(BorderFactory.createTitledBorder(NLS.str("search_dialog.search_in"))); searchOptions.setBorder(BorderFactory.createTitledBorder(NLS.str("search_dialog.options")));
searchOptions.add(clsChBox); searchOptions.add(caseChBox);
searchOptions.add(mthChBox);
searchOptions.add(fldChBox); Box box = Box.createHorizontalBox();
searchOptions.add(codeChBox); box.setAlignmentX(LEFT_ALIGNMENT);
searchOptions.setAlignmentX(LEFT_ALIGNMENT); box.add(searchInPanel);
box.add(searchOptions);
JPanel searchPane = new JPanel(); JPanel searchPane = new JPanel();
searchPane.setLayout(new BoxLayout(searchPane, BoxLayout.PAGE_AXIS)); searchPane.setLayout(new BoxLayout(searchPane, BoxLayout.PAGE_AXIS));
...@@ -140,7 +157,7 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -140,7 +157,7 @@ public class SearchDialog extends CommonSearchDialog {
searchPane.add(Box.createRigidArea(new Dimension(0, 5))); searchPane.add(Box.createRigidArea(new Dimension(0, 5)));
searchPane.add(searchField); searchPane.add(searchField);
searchPane.add(Box.createRigidArea(new Dimension(0, 5))); searchPane.add(Box.createRigidArea(new Dimension(0, 5)));
searchPane.add(searchOptions); searchPane.add(box);
searchPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); searchPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
initCommon(); initCommon();
......
...@@ -109,4 +109,11 @@ public class Utils { ...@@ -109,4 +109,11 @@ public class Utils {
private static String format(long mem) { private static String format(long mem) {
return Long.toString((long) (mem / 1024. / 1024.)) + "MB"; 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; ...@@ -7,7 +7,7 @@ import java.util.List;
public class CodeIndex<T> implements SearchIndex<T> { public class CodeIndex<T> implements SearchIndex<T> {
private final List<StringRef> keys = new ArrayList<>(); private final List<StringRef> keys = new ArrayList<>();
private final List<T> values = new ArrayList<>(); private final List<T> values = new ArrayList<T>();
@Override @Override
public void put(String str, T value) { public void put(String str, T value) {
...@@ -29,15 +29,18 @@ public class CodeIndex<T> implements SearchIndex<T> { ...@@ -29,15 +29,18 @@ public class CodeIndex<T> implements SearchIndex<T> {
} }
@Override @Override
public List<T> getValuesForKeysContaining(String str) { public List<T> getValuesForKeysContaining(String str, boolean caseInsensitive) {
int size = size(); int size = size();
if (size == 0) { if (size == 0) {
return Collections.emptyList(); return Collections.emptyList();
} }
if (caseInsensitive) {
str = str.toLowerCase();
}
List<T> results = new ArrayList<>(); List<T> results = new ArrayList<>();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
StringRef key = keys.get(i); StringRef key = keys.get(i);
if (key.indexOf(str) != -1) { if (key.indexOf(str, caseInsensitive) != -1) {
results.add(values.get(i)); results.add(values.get(i));
} }
} }
......
...@@ -10,7 +10,7 @@ public interface SearchIndex<V> { ...@@ -10,7 +10,7 @@ public interface SearchIndex<V> {
boolean isStringRefSupported(); boolean isStringRefSupported();
List<V> getValuesForKeysContaining(String str); List<V> getValuesForKeysContaining(String str, boolean caseInsensitive);
int size(); int size();
} }
...@@ -7,7 +7,7 @@ import java.util.List; ...@@ -7,7 +7,7 @@ import java.util.List;
public class SimpleIndex<T> implements SearchIndex<T> { public class SimpleIndex<T> implements SearchIndex<T> {
private final List<String> keys = new ArrayList<>(); private final List<String> keys = new ArrayList<>();
private final List<T> values = new ArrayList<>(); private final List<T> values = new ArrayList<T>();
@Override @Override
public void put(String str, T value) { public void put(String str, T value) {
...@@ -26,14 +26,20 @@ public class SimpleIndex<T> implements SearchIndex<T> { ...@@ -26,14 +26,20 @@ public class SimpleIndex<T> implements SearchIndex<T> {
} }
@Override @Override
public List<T> getValuesForKeysContaining(String str) { public List<T> getValuesForKeysContaining(String str, boolean caseInsensitive) {
int size = size(); int size = size();
if (size == 0) { if (size == 0) {
return Collections.emptyList(); return Collections.emptyList();
} }
if (caseInsensitive) {
str = str.toLowerCase();
}
List<T> results = new ArrayList<>(); List<T> results = new ArrayList<>();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
String key = keys.get(i); String key = keys.get(i);
if (caseInsensitive) {
key = key.toLowerCase();
}
if (key.contains(str)) { if (key.contains(str)) {
results.add(values.get(i)); results.add(values.get(i));
} }
......
package jadx.gui.utils.search; package jadx.gui.utils.search;
import static jadx.gui.utils.Utils.caseChar;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
...@@ -68,13 +69,21 @@ public class StringRef implements CharSequence { ...@@ -68,13 +69,21 @@ public class StringRef implements CharSequence {
return indexOf(str, 0); 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) { 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, private static int indexOf(String source, int sourceOffset, int sourceCount,
String target, int targetOffset, int targetCount, String target, int targetOffset, int targetCount,
int fromIndex) { int fromIndex, boolean caseInsensitive) {
if (fromIndex >= sourceCount) { if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1); return (targetCount == 0 ? sourceCount : -1);
} }
...@@ -84,18 +93,18 @@ public class StringRef implements CharSequence { ...@@ -84,18 +93,18 @@ public class StringRef implements CharSequence {
if (targetCount == 0) { if (targetCount == 0) {
return -1; return -1;
} }
char first = target.charAt(targetOffset); char first = caseChar(target.charAt(targetOffset), caseInsensitive);
int max = sourceOffset + (sourceCount - targetCount); int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) { for (int i = sourceOffset + fromIndex; i <= max; i++) {
if (source.charAt(i) != first) { if (caseChar(source.charAt(i), caseInsensitive) != first) {
while (++i <= max && source.charAt(i) != first) { while (++i <= max && caseChar(source.charAt(i), caseInsensitive) != first) {
} }
} }
if (i <= max) { if (i <= max) {
int j = i + 1; int j = i + 1;
int end = j + targetCount - 1; int end = j + targetCount - 1;
int k = targetOffset + 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++; j++;
k++; k++;
} }
...@@ -117,7 +126,7 @@ public class StringRef implements CharSequence { ...@@ -117,7 +126,7 @@ public class StringRef implements CharSequence {
List<StringRef> list = new ArrayList<>(); List<StringRef> list = new ArrayList<>();
while (true) { while (true) {
int start = pos + targetLen; 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 (pos == -1) {
if (start != len) { if (start != len) {
list.add(subString(str, start, len)); list.add(subString(str, start, len));
...@@ -178,4 +187,5 @@ public class StringRef implements CharSequence { ...@@ -178,4 +187,5 @@ public class StringRef implements CharSequence {
int offset = this.offset; int offset = this.offset;
return refStr.substring(offset, offset + len); return refStr.substring(offset, offset + len);
} }
} }
...@@ -73,22 +73,22 @@ public class TextSearchIndex { ...@@ -73,22 +73,22 @@ public class TextSearchIndex {
} }
} }
public List<JNode> searchClsName(String text) { public List<JNode> searchClsName(String text, boolean caseInsensitive) {
return clsNamesIndex.getValuesForKeysContaining(text); return clsNamesIndex.getValuesForKeysContaining(text, caseInsensitive);
} }
public List<JNode> searchMthName(String text) { public List<JNode> searchMthName(String text, boolean caseInsensitive) {
return mthNamesIndex.getValuesForKeysContaining(text); return mthNamesIndex.getValuesForKeysContaining(text, caseInsensitive);
} }
public List<JNode> searchFldName(String text) { public List<JNode> searchFldName(String text, boolean caseInsensitive) {
return fldNamesIndex.getValuesForKeysContaining(text); return fldNamesIndex.getValuesForKeysContaining(text, caseInsensitive);
} }
public List<CodeNode> searchCode(String text) { public List<CodeNode> searchCode(String text, boolean caseInsensitive) {
List<CodeNode> items; List<CodeNode> items;
if (codeIndex.size() > 0) { if (codeIndex.size() > 0) {
items = codeIndex.getValuesForKeysContaining(text); items = codeIndex.getValuesForKeysContaining(text, caseInsensitive);
if (skippedClasses.isEmpty()) { if (skippedClasses.isEmpty()) {
return items; return items;
} }
......
...@@ -49,6 +49,8 @@ search_dialog.class=Class ...@@ -49,6 +49,8 @@ search_dialog.class=Class
search_dialog.method=Method search_dialog.method=Method
search_dialog.field=Field search_dialog.field=Field
search_dialog.code=Code search_dialog.code=Code
search_dialog.options=Search options \:
search_dialog.ignorecase=Case insensitive
usage_dialog.title=Usage search usage_dialog.title=Usage search
usage_dialog.label=Usage for: usage_dialog.label=Usage for:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment