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

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

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