未验证 提交 583a04b0 编写于 作者: S Skylot

fix(gui): show skipped resources count during search (#1808)

上级 444a04e2
...@@ -5,6 +5,7 @@ import java.util.regex.Pattern; ...@@ -5,6 +5,7 @@ import java.util.regex.Pattern;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import jadx.gui.treemodel.JClass; import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JResource;
public class SearchSettings { public class SearchSettings {
...@@ -13,6 +14,7 @@ public class SearchSettings { ...@@ -13,6 +14,7 @@ public class SearchSettings {
private final boolean ignoreCase; private final boolean ignoreCase;
private JClass activeCls; private JClass activeCls;
private JResource activeResource;
private Pattern regexPattern; private Pattern regexPattern;
private ISearchMethod searchMethod; private ISearchMethod searchMethod;
...@@ -64,6 +66,14 @@ public class SearchSettings { ...@@ -64,6 +66,14 @@ public class SearchSettings {
this.activeCls = activeCls; this.activeCls = activeCls;
} }
public JResource getActiveResource() {
return activeResource;
}
public void setActiveResource(JResource activeResource) {
this.activeResource = activeResource;
}
public ISearchMethod getSearchMethod() { public ISearchMethod getSearchMethod() {
return searchMethod; return searchMethod;
} }
......
package jadx.gui.search.providers; package jadx.gui.search.providers;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collections;
import java.util.Deque; import java.util.Deque;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet; import java.util.HashSet;
...@@ -24,12 +25,15 @@ import jadx.gui.treemodel.JResSearchNode; ...@@ -24,12 +25,15 @@ import jadx.gui.treemodel.JResSearchNode;
import jadx.gui.treemodel.JResource; import jadx.gui.treemodel.JResource;
import jadx.gui.treemodel.JRoot; import jadx.gui.treemodel.JRoot;
import jadx.gui.ui.MainWindow; import jadx.gui.ui.MainWindow;
import jadx.gui.ui.dialog.SearchDialog;
import jadx.gui.utils.NLS;
public class ResourceSearchProvider implements ISearchProvider { public class ResourceSearchProvider implements ISearchProvider {
private static final Logger LOG = LoggerFactory.getLogger(ResourceSearchProvider.class); private static final Logger LOG = LoggerFactory.getLogger(ResourceSearchProvider.class);
private final SearchSettings searchSettings; private final SearchSettings searchSettings;
private final Set<String> extSet; private final Set<String> extSet;
private final SearchDialog searchDialog;
private final int sizeLimit; private final int sizeLimit;
private boolean anyExt; private boolean anyExt;
...@@ -39,11 +43,20 @@ public class ResourceSearchProvider implements ISearchProvider { ...@@ -39,11 +43,20 @@ public class ResourceSearchProvider implements ISearchProvider {
private final Deque<JResource> resQueue; private final Deque<JResource> resQueue;
private int pos; private int pos;
public ResourceSearchProvider(MainWindow mw, SearchSettings searchSettings) { private int loadErrors = 0;
private int skipBySize = 0;
public ResourceSearchProvider(MainWindow mw, SearchSettings searchSettings, SearchDialog searchDialog) {
this.searchSettings = searchSettings; this.searchSettings = searchSettings;
this.sizeLimit = mw.getSettings().getSrhResourceSkipSize() * 1048576; this.sizeLimit = mw.getSettings().getSrhResourceSkipSize() * 1048576;
this.extSet = buildAllowedFilesExtensions(mw.getSettings().getSrhResourceFileExt()); this.extSet = buildAllowedFilesExtensions(mw.getSettings().getSrhResourceFileExt());
this.resQueue = initResQueue(mw); this.searchDialog = searchDialog;
JResource activeResource = searchSettings.getActiveResource();
if (activeResource != null) {
this.resQueue = new ArrayDeque<>(Collections.singleton(activeResource));
} else {
this.resQueue = initResQueue(mw);
}
} }
@Override @Override
...@@ -93,32 +106,49 @@ public class ResourceSearchProvider implements ISearchProvider { ...@@ -93,32 +106,49 @@ public class ResourceSearchProvider implements ISearchProvider {
private @Nullable JResource getNextResFile(Cancelable cancelable) { private @Nullable JResource getNextResFile(Cancelable cancelable) {
while (true) { while (true) {
JResource node = resQueue.peekLast(); JResource node = resQueue.peekLast();
if (node == null) { if (node == null || cancelable.isCanceled()) {
return null;
}
try {
node.loadNode();
} catch (Exception e) {
LOG.error("Error load resource node: {}", node, e);
resQueue.removeLast();
continue;
}
if (cancelable.isCanceled()) {
return null; return null;
} }
if (node.getType() == JResource.JResType.FILE) { if (node.getType() == JResource.JResType.FILE) {
if (shouldProcess(node)) { if (shouldProcess(node) && loadResNode(node)) {
return node; return node;
} }
resQueue.removeLast(); resQueue.removeLast();
} else { } else {
// dir // dir
resQueue.removeLast(); resQueue.removeLast();
loadResNode(node);
addChildren(node); addChildren(node);
} }
} }
} }
private void updateProgressInfo() {
StringBuilder sb = new StringBuilder();
if (loadErrors != 0) {
sb.append(" ").append(NLS.str("search_dialog.resources_load_errors", loadErrors));
}
if (skipBySize != 0) {
sb.append(" ").append(NLS.str("search_dialog.resources_skip_by_size", skipBySize));
}
if (sb.length() != 0) {
sb.append(" ").append(NLS.str("search_dialog.resources_check_logs"));
}
searchDialog.updateProgressLabel(sb.toString());
}
private boolean loadResNode(JResource node) {
try {
node.loadNode();
return true;
} catch (Exception e) {
LOG.error("Error load resource node: {}", node, e);
loadErrors++;
updateProgressInfo();
return false;
}
}
private void addChildren(JResource resNode) { private void addChildren(JResource resNode) {
resQueue.addAll(resNode.getSubNodes()); resQueue.addAll(resNode.getSubNodes());
} }
...@@ -167,19 +197,24 @@ public class ResourceSearchProvider implements ISearchProvider { ...@@ -167,19 +197,24 @@ public class ResourceSearchProvider implements ISearchProvider {
return false; return false;
} }
} }
if (sizeLimit == 0) { if (sizeLimit <= 0) {
return true; return true;
} }
try { try {
int charsCount = resNode.getCodeInfo().getCodeStr().length(); int charsCount = resNode.getCodeInfo().getCodeStr().length();
long size = charsCount * 8L; long size = charsCount * 8L;
if (size > sizeLimit) { if (size > sizeLimit) {
LOG.debug("Resource search skipped because of size limit: {} res size {} bytes", resNode, size); LOG.info("Resource search skipped because of size limit. Resource '{}' size {} bytes, limit: {}",
resNode.getName(), size, sizeLimit);
skipBySize++;
updateProgressInfo();
return false; return false;
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
LOG.warn("Resource load error: {}", resNode, e); LOG.warn("Resource load error: {}", resNode, e);
loadErrors++;
updateProgressInfo();
return false; return false;
} }
} }
......
...@@ -45,6 +45,8 @@ import org.jetbrains.annotations.Nullable; ...@@ -45,6 +45,8 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import jadx.api.JavaClass; import jadx.api.JavaClass;
import jadx.api.metadata.ICodeAnnotation; import jadx.api.metadata.ICodeAnnotation;
import jadx.api.metadata.annotations.NodeDeclareRef; import jadx.api.metadata.annotations.NodeDeclareRef;
...@@ -78,6 +80,7 @@ public abstract class CommonSearchDialog extends JFrame { ...@@ -78,6 +80,7 @@ public abstract class CommonSearchDialog extends JFrame {
protected ResultsModel resultsModel; protected ResultsModel resultsModel;
protected ResultsTable resultsTable; protected ResultsTable resultsTable;
protected JLabel resultsInfoLabel; protected JLabel resultsInfoLabel;
protected JLabel progressInfoLabel;
protected JLabel warnLabel; protected JLabel warnLabel;
protected ProgressPanel progressPane; protected ProgressPanel progressPane;
...@@ -297,6 +300,15 @@ public abstract class CommonSearchDialog extends JFrame { ...@@ -297,6 +300,15 @@ public abstract class CommonSearchDialog extends JFrame {
resultsInfoLabel = new JLabel(""); resultsInfoLabel = new JLabel("");
resultsInfoLabel.setFont(mainWindow.getSettings().getFont()); resultsInfoLabel.setFont(mainWindow.getSettings().getFont());
progressInfoLabel = new JLabel("");
progressInfoLabel.setFont(mainWindow.getSettings().getFont());
progressInfoLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
LogViewerDialog.openWithLevel(mainWindow, Level.INFO);
}
});
JPanel resultsActionsPanel = new JPanel(); JPanel resultsActionsPanel = new JPanel();
resultsActionsPanel.setLayout(new BoxLayout(resultsActionsPanel, BoxLayout.LINE_AXIS)); resultsActionsPanel.setLayout(new BoxLayout(resultsActionsPanel, BoxLayout.LINE_AXIS));
resultsActionsPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); resultsActionsPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
...@@ -313,6 +325,8 @@ public abstract class CommonSearchDialog extends JFrame { ...@@ -313,6 +325,8 @@ public abstract class CommonSearchDialog extends JFrame {
protected void addResultsActions(JPanel resultsActionsPanel) { protected void addResultsActions(JPanel resultsActionsPanel) {
resultsActionsPanel.add(Box.createRigidArea(new Dimension(20, 0))); resultsActionsPanel.add(Box.createRigidArea(new Dimension(20, 0)));
resultsActionsPanel.add(resultsInfoLabel); resultsActionsPanel.add(resultsInfoLabel);
resultsActionsPanel.add(Box.createRigidArea(new Dimension(20, 0)));
resultsActionsPanel.add(progressInfoLabel);
resultsActionsPanel.add(Box.createHorizontalGlue()); resultsActionsPanel.add(Box.createHorizontalGlue());
} }
......
...@@ -55,6 +55,7 @@ import jadx.gui.search.providers.MethodSearchProvider; ...@@ -55,6 +55,7 @@ import jadx.gui.search.providers.MethodSearchProvider;
import jadx.gui.search.providers.ResourceSearchProvider; import jadx.gui.search.providers.ResourceSearchProvider;
import jadx.gui.treemodel.JClass; import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode; import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.JResource;
import jadx.gui.ui.MainWindow; import jadx.gui.ui.MainWindow;
import jadx.gui.utils.JumpPosition; import jadx.gui.utils.JumpPosition;
import jadx.gui.utils.NLS; import jadx.gui.utils.NLS;
...@@ -452,9 +453,18 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -452,9 +453,18 @@ public class SearchDialog extends CommonSearchDialog {
resultsInfoLabel.setText("Can't search in current tab"); resultsInfoLabel.setText("Can't search in current tab");
return false; return false;
} }
JClass activeCls = currentPos.getNode().getRootClass(); JNode currentNode = currentPos.getNode();
searchSettings.setActiveCls(activeCls); if (currentNode instanceof JClass) {
allClasses = Collections.singletonList(activeCls.getCls()); JClass activeCls = currentNode.getRootClass();
searchSettings.setActiveCls(activeCls);
allClasses = Collections.singletonList(activeCls.getCls());
} else if (currentNode instanceof JResource) {
searchSettings.setActiveResource((JResource) currentNode);
allClasses = Collections.emptyList();
} else {
resultsInfoLabel.setText("Can't search in current tab");
return false;
}
} else { } else {
allClasses = mainWindow.getWrapper().getIncludedClassesWithInners(); allClasses = mainWindow.getWrapper().getIncludedClassesWithInners();
} }
...@@ -475,9 +485,10 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -475,9 +485,10 @@ public class SearchDialog extends CommonSearchDialog {
merged.add(new FieldSearchProvider(mainWindow, searchSettings, allClasses)); merged.add(new FieldSearchProvider(mainWindow, searchSettings, allClasses));
} }
if (options.contains(CODE)) { if (options.contains(CODE)) {
if (allClasses.size() == 1) { int clsCount = allClasses.size();
if (clsCount == 1) {
newSearchTask.addProviderJob(new CodeSearchProvider(mainWindow, searchSettings, allClasses)); newSearchTask.addProviderJob(new CodeSearchProvider(mainWindow, searchSettings, allClasses));
} else { } else if (clsCount > 1) {
List<List<JavaClass>> batches = mainWindow.getCacheObject().getDecompileBatches(); List<List<JavaClass>> batches = mainWindow.getCacheObject().getDecompileBatches();
if (batches == null) { if (batches == null) {
List<JavaClass> topClasses = ListUtils.filter(allClasses, c -> !c.isInner()); List<JavaClass> topClasses = ListUtils.filter(allClasses, c -> !c.isInner());
...@@ -490,7 +501,7 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -490,7 +501,7 @@ public class SearchDialog extends CommonSearchDialog {
} }
} }
if (options.contains(RESOURCE)) { if (options.contains(RESOURCE)) {
newSearchTask.addProviderJob(new ResourceSearchProvider(mainWindow, searchSettings)); newSearchTask.addProviderJob(new ResourceSearchProvider(mainWindow, searchSettings, this));
} }
if (options.contains(COMMENT)) { if (options.contains(COMMENT)) {
newSearchTask.addProviderJob(new CommentSearchProvider(mainWindow, searchSettings)); newSearchTask.addProviderJob(new CommentSearchProvider(mainWindow, searchSettings));
...@@ -549,6 +560,7 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -549,6 +560,7 @@ public class SearchDialog extends CommonSearchDialog {
synchronized (pendingResults) { synchronized (pendingResults) {
pendingResults.clear(); pendingResults.clear();
} }
updateProgressLabel("");
progressPane.setVisible(false); progressPane.setVisible(false);
warnLabel.setVisible(false); warnLabel.setVisible(false);
loadAllButton.setEnabled(false); loadAllButton.setEnabled(false);
...@@ -598,6 +610,10 @@ public class SearchDialog extends CommonSearchDialog { ...@@ -598,6 +610,10 @@ public class SearchDialog extends CommonSearchDialog {
}); });
} }
public void updateProgressLabel(String text) {
UiUtils.uiRun(() -> progressInfoLabel.setText(text));
}
private void searchFinished(ITaskInfo status, Boolean complete) { private void searchFinished(ITaskInfo status, Boolean complete) {
UiUtils.uiThreadGuard(); UiUtils.uiThreadGuard();
LOG.debug("Search complete: {}, complete: {}", status, complete); LOG.debug("Search complete: {}, complete: {}", status, complete);
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=Alle laden ...@@ -112,6 +112,9 @@ search_dialog.load_all=Alle laden
#search_dialog.stop=Stop #search_dialog.stop=Stop
search_dialog.results_incomplete=%d+ gefunden search_dialog.results_incomplete=%d+ gefunden
search_dialog.results_complete=%d gefunden (komplett) search_dialog.results_complete=%d gefunden (komplett)
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node=Knoten search_dialog.col_node=Knoten
search_dialog.col_code=Code search_dialog.col_code=Code
#search_dialog.sort_results=Sort results #search_dialog.sort_results=Sort results
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=Load all ...@@ -112,6 +112,9 @@ search_dialog.load_all=Load all
search_dialog.stop=Stop search_dialog.stop=Stop
search_dialog.results_incomplete=Found %d+ search_dialog.results_incomplete=Found %d+
search_dialog.results_complete=Found %d (complete) search_dialog.results_complete=Found %d (complete)
search_dialog.resources_load_errors=Load errors: %d
search_dialog.resources_skip_by_size=Skipped by size: %d
search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node=Node search_dialog.col_node=Node
search_dialog.col_code=Code search_dialog.col_code=Code
search_dialog.sort_results=Sort results search_dialog.sort_results=Sort results
...@@ -200,7 +203,7 @@ preferences.rename_printable=To make printable ...@@ -200,7 +203,7 @@ preferences.rename_printable=To make printable
preferences.search_group_title=Search preferences.search_group_title=Search
preferences.search_results_per_page=Results per page (0 - no limit) preferences.search_results_per_page=Results per page (0 - no limit)
preferences.res_file_ext=Resource files extensions ('xml|html', * for all) preferences.res_file_ext=Resource files extensions ('xml|html', * for all)
preferences.res_skip_file=Skip resources files if larger (MB) preferences.res_skip_file=Skip resources files if larger (MB) (0 - disable)
msg.open_file=Please open file msg.open_file=Please open file
msg.saving_sources=Saving sources msg.saving_sources=Saving sources
......
...@@ -112,6 +112,9 @@ search_dialog.ignorecase=Ignorar minúsculas/mayúsculas ...@@ -112,6 +112,9 @@ search_dialog.ignorecase=Ignorar minúsculas/mayúsculas
#search_dialog.stop=Stop #search_dialog.stop=Stop
#search_dialog.results_incomplete=Found %d+ #search_dialog.results_incomplete=Found %d+
#search_dialog.results_complete=Found %d (complete) #search_dialog.results_complete=Found %d (complete)
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node=Nodo search_dialog.col_node=Nodo
search_dialog.col_code=Código search_dialog.col_code=Código
#search_dialog.sort_results=Sort results #search_dialog.sort_results=Sort results
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=모두 로드 ...@@ -112,6 +112,9 @@ search_dialog.load_all=모두 로드
search_dialog.stop=정지 search_dialog.stop=정지
search_dialog.results_incomplete=%d+개 찾음 search_dialog.results_incomplete=%d+개 찾음
search_dialog.results_complete=%d개 찾음 (검색 완료) search_dialog.results_complete=%d개 찾음 (검색 완료)
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node=노드 search_dialog.col_node=노드
search_dialog.col_code=코드 search_dialog.col_code=코드
search_dialog.sort_results=결과 정렬 search_dialog.sort_results=결과 정렬
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=Carregar todas ...@@ -112,6 +112,9 @@ search_dialog.load_all=Carregar todas
search_dialog.stop=Parar search_dialog.stop=Parar
search_dialog.results_incomplete=Encontradas %d+ search_dialog.results_incomplete=Encontradas %d+
search_dialog.results_complete=Encontradas %d (completos) search_dialog.results_complete=Encontradas %d (completos)
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node= search_dialog.col_node=
search_dialog.col_code=Código search_dialog.col_code=Código
search_dialog.sort_results=Ordenar resultados search_dialog.sort_results=Ordenar resultados
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=Загрузить все ...@@ -112,6 +112,9 @@ search_dialog.load_all=Загрузить все
search_dialog.stop=Стоп search_dialog.stop=Стоп
search_dialog.results_incomplete=Найдено %d+ search_dialog.results_incomplete=Найдено %d+
search_dialog.results_complete=Найдено %d (поиск завершен) search_dialog.results_complete=Найдено %d (поиск завершен)
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node=Вхождения search_dialog.col_node=Вхождения
search_dialog.col_code=Код search_dialog.col_code=Код
search_dialog.sort_results=Сортировка результатов search_dialog.sort_results=Сортировка результатов
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=加载所有 ...@@ -112,6 +112,9 @@ search_dialog.load_all=加载所有
search_dialog.stop=停止 search_dialog.stop=停止
search_dialog.results_incomplete=已找到 %d+ search_dialog.results_incomplete=已找到 %d+
search_dialog.results_complete=全部找到 %d search_dialog.results_complete=全部找到 %d
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node=节点 search_dialog.col_node=节点
search_dialog.col_code=代码 search_dialog.col_code=代码
search_dialog.sort_results=结果分类 search_dialog.sort_results=结果分类
......
...@@ -112,6 +112,9 @@ search_dialog.load_all=載入全部 ...@@ -112,6 +112,9 @@ search_dialog.load_all=載入全部
search_dialog.stop=停止 search_dialog.stop=停止
search_dialog.results_incomplete=找到 %d+ search_dialog.results_incomplete=找到 %d+
search_dialog.results_complete=找到 %d (完整) search_dialog.results_complete=找到 %d (完整)
#search_dialog.resources_load_errors=Load errors: %d
#search_dialog.resources_skip_by_size=Skipped by size: %d
#search_dialog.resources_check_logs=(click to check logs)
search_dialog.col_node= search_dialog.col_node=
search_dialog.col_code=程式碼 search_dialog.col_code=程式碼
search_dialog.sort_results=排序結果 search_dialog.sort_results=排序結果
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册