From f0a57e6714cde83985d0f9e8db601d67de70e685 Mon Sep 17 00:00:00 2001 From: Jan Peter Stotz <> Date: Wed, 17 Aug 2016 10:48:21 +0200 Subject: [PATCH] case insensitive option for searches --- .../java/jadx/gui/ui/CommonSearchDialog.java | 3 +- .../main/java/jadx/gui/ui/SearchDialog.java | 41 +++++++++++++------ .../src/main/java/jadx/gui/utils/Utils.java | 7 ++++ .../java/jadx/gui/utils/search/CodeIndex.java | 9 ++-- .../jadx/gui/utils/search/SearchIndex.java | 2 +- .../jadx/gui/utils/search/SimpleIndex.java | 10 ++++- .../java/jadx/gui/utils/search/StringRef.java | 24 +++++++---- .../gui/utils/search/TextSearchIndex.java | 16 ++++---- .../resources/i18n/Messages_en_US.properties | 2 + 9 files changed, 80 insertions(+), 34 deletions(-) diff --git a/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java index 8c792d8e..adf7bb3e 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java @@ -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); } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java index 4f89b91f..2c68b789 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java @@ -31,6 +31,7 @@ public class SearchDialog extends CommonSearchDialog { private Set options = EnumSet.allOf(SearchOptions.class); private JTextField searchField; + private JCheckBox caseChBox; public SearchDialog(MainWindow mainWindow, Set 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(); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/Utils.java b/jadx-gui/src/main/java/jadx/gui/utils/Utils.java index ff5e08b6..c4e7c156 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/Utils.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/Utils.java @@ -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; + } } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java b/jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java index 4ed5851d..f71ca174 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java @@ -7,7 +7,7 @@ import java.util.List; public class CodeIndex implements SearchIndex { private final List keys = new ArrayList<>(); - private final List values = new ArrayList<>(); + private final List values = new ArrayList(); @Override public void put(String str, T value) { @@ -29,15 +29,18 @@ public class CodeIndex implements SearchIndex { } @Override - public List getValuesForKeysContaining(String str) { + public List getValuesForKeysContaining(String str, boolean caseInsensitive) { int size = size(); if (size == 0) { return Collections.emptyList(); } + if (caseInsensitive) { + str = str.toLowerCase(); + } List 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)); } } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/search/SearchIndex.java b/jadx-gui/src/main/java/jadx/gui/utils/search/SearchIndex.java index d381b0a4..9b3fed0b 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/search/SearchIndex.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/search/SearchIndex.java @@ -10,7 +10,7 @@ public interface SearchIndex { boolean isStringRefSupported(); - List getValuesForKeysContaining(String str); + List getValuesForKeysContaining(String str, boolean caseInsensitive); int size(); } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java b/jadx-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java index 4252fe15..32985a05 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java @@ -7,7 +7,7 @@ import java.util.List; public class SimpleIndex implements SearchIndex { private final List keys = new ArrayList<>(); - private final List values = new ArrayList<>(); + private final List values = new ArrayList(); @Override public void put(String str, T value) { @@ -26,14 +26,20 @@ public class SimpleIndex implements SearchIndex { } @Override - public List getValuesForKeysContaining(String str) { + public List getValuesForKeysContaining(String str, boolean caseInsensitive) { int size = size(); if (size == 0) { return Collections.emptyList(); } + if (caseInsensitive) { + str = str.toLowerCase(); + } List 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)); } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/search/StringRef.java b/jadx-gui/src/main/java/jadx/gui/utils/search/StringRef.java index bf6f7804..92eb375a 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/search/StringRef.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/search/StringRef.java @@ -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 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); } + } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/search/TextSearchIndex.java b/jadx-gui/src/main/java/jadx/gui/utils/search/TextSearchIndex.java index ca702504..ea4119d3 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/search/TextSearchIndex.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/search/TextSearchIndex.java @@ -73,22 +73,22 @@ public class TextSearchIndex { } } - public List searchClsName(String text) { - return clsNamesIndex.getValuesForKeysContaining(text); + public List searchClsName(String text, boolean caseInsensitive) { + return clsNamesIndex.getValuesForKeysContaining(text, caseInsensitive); } - public List searchMthName(String text) { - return mthNamesIndex.getValuesForKeysContaining(text); + public List searchMthName(String text, boolean caseInsensitive) { + return mthNamesIndex.getValuesForKeysContaining(text, caseInsensitive); } - public List searchFldName(String text) { - return fldNamesIndex.getValuesForKeysContaining(text); + public List searchFldName(String text, boolean caseInsensitive) { + return fldNamesIndex.getValuesForKeysContaining(text, caseInsensitive); } - public List searchCode(String text) { + public List searchCode(String text, boolean caseInsensitive) { List items; if (codeIndex.size() > 0) { - items = codeIndex.getValuesForKeysContaining(text); + items = codeIndex.getValuesForKeysContaining(text, caseInsensitive); if (skippedClasses.isEmpty()) { return items; } diff --git a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties index 00b887a4..b85c9240 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties @@ -49,6 +49,8 @@ search_dialog.class=Class search_dialog.method=Method search_dialog.field=Field search_dialog.code=Code +search_dialog.options=Search options \: +search_dialog.ignorecase=Case insensitive usage_dialog.title=Usage search usage_dialog.label=Usage for: -- GitLab