feat(gui): save project search history
This commit is contained in:
@@ -43,6 +43,8 @@ public class JadxProject {
|
||||
private static final int CURRENT_PROJECT_VERSION = 1;
|
||||
public static final String PROJECT_EXTENSION = "jadx";
|
||||
|
||||
private static final int SEARCH_HISTORY_LIMIT = 30;
|
||||
|
||||
private final transient MainWindow mainWindow;
|
||||
|
||||
private transient String name = "New Project";
|
||||
@@ -195,6 +197,27 @@ public class JadxProject {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getSearchHistory() {
|
||||
return data.getSearchHistory();
|
||||
}
|
||||
|
||||
public void addToSearchHistory(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> list = data.getSearchHistory();
|
||||
if (!list.isEmpty() && list.get(0).equals(str)) {
|
||||
return;
|
||||
}
|
||||
list.remove(str);
|
||||
list.add(0, str);
|
||||
if (list.size() > SEARCH_HISTORY_LIMIT) {
|
||||
list.remove(list.size() - 1);
|
||||
}
|
||||
data.setSearchHistory(list);
|
||||
changed();
|
||||
}
|
||||
|
||||
private void changed() {
|
||||
JadxSettings settings = mainWindow.getSettings();
|
||||
if (settings != null && settings.isAutoSaveProject()) {
|
||||
|
||||
@@ -20,6 +20,7 @@ public class ProjectData {
|
||||
private int activeTab = -1;
|
||||
private @Nullable Path cacheDir;
|
||||
private boolean enableLiveReload = false;
|
||||
private List<String> searchHistory = new ArrayList<>();
|
||||
|
||||
public List<Path> getFiles() {
|
||||
return files;
|
||||
@@ -103,4 +104,12 @@ public class ProjectData {
|
||||
public void setEnableLiveReload(boolean enableLiveReload) {
|
||||
this.enableLiveReload = enableLiveReload;
|
||||
}
|
||||
|
||||
public List<String> getSearchHistory() {
|
||||
return searchHistory;
|
||||
}
|
||||
|
||||
public void setSearchHistory(List<String> searchHistory) {
|
||||
this.searchHistory = searchHistory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.event.ChangeListener;
|
||||
@@ -29,6 +31,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon;
|
||||
|
||||
import io.reactivex.BackpressureStrategy;
|
||||
import io.reactivex.Emitter;
|
||||
import io.reactivex.Flowable;
|
||||
@@ -207,6 +212,8 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
searchFieldDefaultBgColor = searchField.getBackground();
|
||||
searchField.setAlignmentX(LEFT_ALIGNMENT);
|
||||
TextStandardActions.attach(searchField);
|
||||
addSearchHistoryButton();
|
||||
searchField.putClientProperty(FlatClientProperties.TEXT_FIELD_SHOW_CLEAR_BUTTON, true);
|
||||
|
||||
boolean autoSearch = mainWindow.getSettings().isUseAutoSearch();
|
||||
JButton searchBtn = new JButton(NLS.str("search_dialog.search_button"));
|
||||
@@ -286,6 +293,25 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
}
|
||||
|
||||
private void addSearchHistoryButton() {
|
||||
JButton searchHistoryButton = new JButton(new FlatSearchWithHistoryIcon(true));
|
||||
searchHistoryButton.setToolTipText(NLS.str("search_dialog.search_history"));
|
||||
searchHistoryButton.addActionListener(e -> {
|
||||
JPopupMenu popupMenu = new JPopupMenu();
|
||||
List<String> searchHistory = mainWindow.getProject().getSearchHistory();
|
||||
if (searchHistory.isEmpty()) {
|
||||
popupMenu.add("(empty)");
|
||||
} else {
|
||||
for (String str : searchHistory) {
|
||||
JMenuItem item = popupMenu.add(str);
|
||||
item.addActionListener(ev -> searchField.setText(str));
|
||||
}
|
||||
}
|
||||
popupMenu.show(searchHistoryButton, 0, searchHistoryButton.getHeight());
|
||||
});
|
||||
searchField.putClientProperty(FlatClientProperties.TEXT_FIELD_LEADING_COMPONENT, searchHistoryButton);
|
||||
}
|
||||
|
||||
protected void addResultsActions(JPanel resultsActionsPanel) {
|
||||
loadAllButton = new JButton(NLS.str("search_dialog.load_all"));
|
||||
loadAllButton.addActionListener(e -> loadMoreResults(true));
|
||||
@@ -463,6 +489,15 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void openItem(JNode node) {
|
||||
if (mainWindow.getSettings().isUseAutoSearch()) {
|
||||
// for auto search save only searches which leads to node opening
|
||||
mainWindow.getProject().addToSearchHistory(searchField.getText());
|
||||
}
|
||||
super.openItem(node);
|
||||
}
|
||||
|
||||
private void pauseSearch() {
|
||||
stopBtn.setEnabled(false);
|
||||
searchBackgroundExecutor.execute(() -> {
|
||||
@@ -539,6 +574,9 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
updateHighlightContext(text, !options.contains(IGNORE_CASE), options.contains(USE_REGEX));
|
||||
cache.setLastSearch(text);
|
||||
cache.getLastSearchOptions().put(searchPreset, options);
|
||||
if (!mainWindow.getSettings().isUseAutoSearch()) {
|
||||
mainWindow.getProject().addToSearchHistory(text);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgress(ITaskProgress progress) {
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=Öffnen
|
||||
search_dialog.cancel=Beenden
|
||||
search_dialog.open_by_name=Nach Text suchen:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.search_history=Search history
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Suche in Definitionen von:
|
||||
search_dialog.class=Klassen
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=Open
|
||||
search_dialog.cancel=Cancel
|
||||
search_dialog.open_by_name=Search for text:
|
||||
search_dialog.search_button=Search
|
||||
search_dialog.search_history=Search history
|
||||
search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Search definitions of:
|
||||
search_dialog.class=Class
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=Abrir
|
||||
search_dialog.cancel=Cancelar
|
||||
search_dialog.open_by_name=Buscar texto:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.search_history=Search history
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Buscar definiciones de:
|
||||
search_dialog.class=Clase
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=열기
|
||||
search_dialog.cancel=취소
|
||||
search_dialog.open_by_name=텍스트 검색 :
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.search_history=Search history
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=정의 검색 :
|
||||
search_dialog.class=클래스
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=Abrir
|
||||
search_dialog.cancel=Cancelar
|
||||
search_dialog.open_by_name=Buscar por text:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.search_history=Search history
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Buscar definições de:
|
||||
search_dialog.class=Classe
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=转到
|
||||
search_dialog.cancel=取消
|
||||
search_dialog.open_by_name=搜索文本:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.search_history=Search history
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=在以下位置搜索:
|
||||
search_dialog.class=类名
|
||||
|
||||
@@ -97,6 +97,7 @@ search_dialog.open=開啟
|
||||
search_dialog.cancel=取消
|
||||
search_dialog.open_by_name=搜尋文字:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.search_history=Search history
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=搜尋定義:
|
||||
search_dialog.class=類別
|
||||
|
||||
Reference in New Issue
Block a user