Unverified Commit a7903f31 authored by skylot's avatar skylot Committed by GitHub

Merge pull request #228 from jpstotz/master

Search dialog improvements
parents d9b0365c c134837c
...@@ -12,11 +12,8 @@ import java.awt.event.MouseAdapter; ...@@ -12,11 +12,8 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.util.ArrayList; import java.util.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
...@@ -30,7 +27,6 @@ import jadx.gui.jobs.BackgroundJob; ...@@ -30,7 +27,6 @@ import jadx.gui.jobs.BackgroundJob;
import jadx.gui.jobs.BackgroundWorker; import jadx.gui.jobs.BackgroundWorker;
import jadx.gui.jobs.DecompileJob; import jadx.gui.jobs.DecompileJob;
import jadx.gui.treemodel.JNode; import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.TextNode;
import jadx.gui.utils.CacheObject; import jadx.gui.utils.CacheObject;
import jadx.gui.utils.NLS; import jadx.gui.utils.NLS;
import jadx.gui.utils.Position; import jadx.gui.utils.Position;
...@@ -41,7 +37,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -41,7 +37,7 @@ public abstract class CommonSearchDialog extends JDialog {
private static final Logger LOG = LoggerFactory.getLogger(CommonSearchDialog.class); private static final Logger LOG = LoggerFactory.getLogger(CommonSearchDialog.class);
private static final long serialVersionUID = 8939332306115370276L; private static final long serialVersionUID = 8939332306115370276L;
public static final int MAX_RESULTS_COUNT = 100; public static final int RESULTS_PER_PAGE = 100;
protected final transient TabbedPane tabbedPane; protected final transient TabbedPane tabbedPane;
protected final transient CacheObject cache; protected final transient CacheObject cache;
...@@ -50,10 +46,12 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -50,10 +46,12 @@ public abstract class CommonSearchDialog extends JDialog {
protected ResultsModel resultsModel; protected ResultsModel resultsModel;
protected ResultsTable resultsTable; protected ResultsTable resultsTable;
protected JLabel resultsInfoLabel;
protected JLabel warnLabel; protected JLabel warnLabel;
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);
...@@ -93,6 +91,11 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -93,6 +91,11 @@ public abstract class CommonSearchDialog extends JDialog {
}); });
} }
protected synchronized void performSearch() {
resultsTable.updateTable();
updateProgressLabel();
}
protected void openSelectedItem() { protected void openSelectedItem() {
int selectedId = resultsTable.getSelectedRow(); int selectedId = resultsTable.getSelectedRow();
if (selectedId == -1) { if (selectedId == -1) {
...@@ -140,6 +143,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -140,6 +143,7 @@ public abstract class CommonSearchDialog extends JDialog {
protected JPanel initResultsTable() { protected JPanel initResultsTable() {
ResultsTableCellRenderer renderer = new ResultsTableCellRenderer(); ResultsTableCellRenderer renderer = new ResultsTableCellRenderer();
resultsModel = new ResultsModel(renderer); resultsModel = new ResultsModel(renderer);
resultsModel.addTableModelListener((e) -> updateProgressLabel());
resultsTable = new ResultsTable(resultsModel); resultsTable = new ResultsTable(resultsModel);
resultsTable.setShowHorizontalLines(false); resultsTable.setShowHorizontalLines(false);
resultsTable.setDragEnabled(false); resultsTable.setDragEnabled(false);
...@@ -148,12 +152,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -148,12 +152,7 @@ public abstract class CommonSearchDialog extends JDialog {
resultsTable.setColumnSelectionAllowed(false); resultsTable.setColumnSelectionAllowed(false);
resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
resultsTable.setAutoscrolls(false); resultsTable.setAutoscrolls(false);
resultsTable.setDefaultRenderer(Object.class, renderer);
Enumeration<TableColumn> columns = resultsTable.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn column = columns.nextElement();
column.setCellRenderer(renderer);
}
resultsTable.addMouseListener(new MouseAdapter() { resultsTable.addMouseListener(new MouseAdapter() {
@Override @Override
...@@ -182,10 +181,43 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -182,10 +181,43 @@ public abstract class CommonSearchDialog extends JDialog {
resultsPanel.add(new JScrollPane(resultsTable, resultsPanel.add(new JScrollPane(resultsTable,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED)); ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED));
JPanel paginationPanel = new JPanel();
paginationPanel.setAlignmentX( Component.LEFT_ALIGNMENT );
paginationPanel.setLayout(new BoxLayout(paginationPanel, BoxLayout.X_AXIS));
resultsInfoLabel = new JLabel("");
JButton nextPageButton = new JButton("->");
nextPageButton.setToolTipText(NLS.str("search_dialog.next_page"));
nextPageButton.addActionListener((e) -> {
resultsModel.nextPage();
resultsTable.updateTable();
resultsTable.scrollRectToVisible(new Rectangle(0,0,1,1));
});
JButton prevPageButton = new JButton("<-");
prevPageButton.setToolTipText(NLS.str("search_dialog.prev_page"));
prevPageButton.addActionListener((e) -> {
resultsModel.prevPage();
resultsTable.updateTable();
resultsTable.scrollRectToVisible(new Rectangle(0,0,1,1));
});
paginationPanel.add(prevPageButton);
paginationPanel.add(nextPageButton);
paginationPanel.add(resultsInfoLabel);
resultsPanel.add(paginationPanel);
resultsPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); resultsPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
return resultsPanel; return resultsPanel;
} }
protected void updateProgressLabel() {
String statusText = String.format(NLS.str("search_dialog.info_label"), resultsModel.getDisplayedResultsStart(),
resultsModel.getDisplayedResultsEnd(), resultsModel.getResultCount());
resultsInfoLabel.setText(statusText);
}
protected static class ResultsTable extends JTable { protected static class ResultsTable extends JTable {
private static final long serialVersionUID = 3901184054736618969L; private static final long serialVersionUID = 3901184054736618969L;
...@@ -238,23 +270,18 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -238,23 +270,18 @@ public abstract class CommonSearchDialog extends JDialog {
private static final long serialVersionUID = -7821286846923903208L; private static final long serialVersionUID = -7821286846923903208L;
private static final String[] COLUMN_NAMES = {"Node", "Code"}; private static final String[] COLUMN_NAMES = {"Node", "Code"};
private final transient List<JNode> rows = new ArrayList<>(); private final transient ArrayList<JNode> rows = new ArrayList<>();
private final transient ResultsTableCellRenderer renderer; private final transient ResultsTableCellRenderer renderer;
private transient boolean addDescColumn; private transient boolean addDescColumn;
private transient int start = 0;
public ResultsModel(ResultsTableCellRenderer renderer) { public ResultsModel(ResultsTableCellRenderer renderer) {
this.renderer = renderer; this.renderer = renderer;
} }
protected void addAll(Iterable<? extends JNode> nodes) { protected void addAll(Collection<? extends JNode> nodes) {
rows.ensureCapacity(rows.size() + nodes.size());
for (JNode node : nodes) { for (JNode node : nodes) {
int size = getRowCount();
if (size >= MAX_RESULTS_COUNT) {
if (size == MAX_RESULTS_COUNT) {
add(new TextNode("Search results truncated (limit: " + MAX_RESULTS_COUNT + ")"));
}
return;
}
add(node); add(node);
} }
} }
...@@ -267,6 +294,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -267,6 +294,7 @@ public abstract class CommonSearchDialog extends JDialog {
} }
public void clear() { public void clear() {
start = 0;
addDescColumn = false; addDescColumn = false;
rows.clear(); rows.clear();
renderer.clear(); renderer.clear();
...@@ -276,9 +304,39 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -276,9 +304,39 @@ public abstract class CommonSearchDialog extends JDialog {
return addDescColumn; return addDescColumn;
} }
public int getResultCount() {
return rows.size();
}
public int getDisplayedResultsStart() {
if (rows.size() == 0)
return 0;
return start + 1;
}
public int getDisplayedResultsEnd() {
return Math.min(rows.size(), start + RESULTS_PER_PAGE);
}
public void nextPage() {
if (start + RESULTS_PER_PAGE < rows.size()) {
renderer.clear();
start += RESULTS_PER_PAGE;
fireTableStructureChanged();
}
}
public void prevPage() {
if (start - RESULTS_PER_PAGE >= 0) {
renderer.clear();
start -= RESULTS_PER_PAGE;
fireTableStructureChanged();
}
}
@Override @Override
public int getRowCount() { public int getRowCount() {
return rows.size(); return rows.size() - start;
} }
@Override @Override
...@@ -293,7 +351,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -293,7 +351,7 @@ public abstract class CommonSearchDialog extends JDialog {
@Override @Override
public Object getValueAt(int rowIndex, int columnIndex) { public Object getValueAt(int rowIndex, int columnIndex) {
return rows.get(rowIndex); return rows.get(rowIndex + start);
} }
} }
...@@ -359,7 +417,7 @@ public abstract class CommonSearchDialog extends JDialog { ...@@ -359,7 +417,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);
...@@ -52,33 +53,37 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -52,33 +53,37 @@ public class SearchDialog extends CommonSearchDialog {
searchField.requestFocus(); searchField.requestFocus();
} }
private synchronized void performSearch() { @Override
protected synchronized void performSearch() {
resultsModel.clear(); resultsModel.clear();
String text = searchField.getText(); String text = searchField.getText();
if (text == null || text.isEmpty() || options.isEmpty()) { if (text == null || text.isEmpty() || options.isEmpty()) {
resultsTable.updateTable();
return; return;
} }
try {
cache.setLastSearch(text); cache.setLastSearch(text);
TextSearchIndex index = cache.getTextIndex(); TextSearchIndex index = cache.getTextIndex();
if (index == null) { if (index == null) {
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;
resultsTable.updateTable(); highlightTextCaseInsensitive = caseInsensitive;
} finally {
super.performSearch();
}
} }
private class SearchFieldListener implements DocumentListener, ActionListener { private class SearchFieldListener implements DocumentListener, ActionListener {
...@@ -89,7 +94,8 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -89,7 +94,8 @@ public class SearchDialog extends CommonSearchDialog {
if (timer != null) { if (timer != null) {
timer.restart(); timer.restart();
} else { } else {
timer = new Timer(300, this); timer = new Timer(400, this);
timer.setRepeats(false);
timer.start(); timer.start();
} }
} }
...@@ -114,24 +120,38 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -114,24 +120,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 +160,7 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -140,7 +160,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();
......
...@@ -37,7 +37,8 @@ public class UsageDialog extends CommonSearchDialog { ...@@ -37,7 +37,8 @@ public class UsageDialog extends CommonSearchDialog {
// no op // no op
} }
private synchronized void performSearch() { @Override
protected synchronized void performSearch() {
resultsModel.clear(); resultsModel.clear();
CodeUsageInfo usageInfo = cache.getUsageInfo(); CodeUsageInfo usageInfo = cache.getUsageInfo();
...@@ -47,7 +48,7 @@ public class UsageDialog extends CommonSearchDialog { ...@@ -47,7 +48,7 @@ public class UsageDialog extends CommonSearchDialog {
resultsModel.addAll(usageInfo.getUsageList(node)); resultsModel.addAll(usageInfo.getUsageList(node));
// TODO: highlight only needed node usage // TODO: highlight only needed node usage
highlightText = null; highlightText = null;
resultsTable.updateTable(); super.performSearch();
} }
private void initUI() { private void initUI() {
......
...@@ -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;
} }
...@@ -106,7 +106,7 @@ public class TextSearchIndex { ...@@ -106,7 +106,7 @@ public class TextSearchIndex {
while (pos != -1) { while (pos != -1) {
pos = searchNext(list, text, javaClass, code, pos); pos = searchNext(list, text, javaClass, code, pos);
} }
if (list.size() > CommonSearchDialog.MAX_RESULTS_COUNT) { if (list.size() > CommonSearchDialog.RESULTS_PER_PAGE) {
return; return;
} }
} }
......
...@@ -49,6 +49,11 @@ search_dialog.class=Class ...@@ -49,6 +49,11 @@ 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
search_dialog.next_page=Show next page
search_dialog.prev_page=Show previous page
search_dialog.info_label=Showing results %d to %d of %d
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