feat(gui): add manual search, stop and sort actions to search dialog (#1600)
This commit is contained in:
@@ -79,6 +79,7 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
private boolean codeAreaLineWrap = false;
|
||||
private int srhResourceSkipSize = 1000;
|
||||
private String srhResourceFileExt = ".xml|.html|.js|.json|.txt";
|
||||
private boolean useAutoSearch = true;
|
||||
private boolean keepCommonDialogOpen = false;
|
||||
private boolean smaliAreaShowBytecode = false;
|
||||
private LineNumbersMode lineNumbersMode = LineNumbersMode.AUTO;
|
||||
@@ -540,6 +541,15 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
srhResourceFileExt = all.trim();
|
||||
}
|
||||
|
||||
public boolean isUseAutoSearch() {
|
||||
return useAutoSearch;
|
||||
}
|
||||
|
||||
public void setUseAutoSearch(boolean useAutoSearch) {
|
||||
this.useAutoSearch = useAutoSearch;
|
||||
partialSync(settings -> settings.useAutoSearch = useAutoSearch);
|
||||
}
|
||||
|
||||
public void setKeepCommonDialogOpen(boolean yes) {
|
||||
keepCommonDialogOpen = yes;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
@@ -250,15 +251,13 @@ public abstract class CommonSearchDialog extends JFrame {
|
||||
|
||||
JScrollPane scroll = new JScrollPane(resultsTable, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
|
||||
resultsInfoLabel = new JLabel("");
|
||||
resultsInfoLabel.setFont(mainWindow.getSettings().getFont());
|
||||
|
||||
JPanel resultsActionsPanel = new JPanel();
|
||||
resultsActionsPanel.setLayout(new BoxLayout(resultsActionsPanel, BoxLayout.LINE_AXIS));
|
||||
resultsActionsPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
|
||||
addCustomResultsActions(resultsActionsPanel);
|
||||
resultsInfoLabel = new JLabel("");
|
||||
resultsInfoLabel.setFont(mainWindow.getSettings().getFont());
|
||||
resultsActionsPanel.add(Box.createRigidArea(new Dimension(20, 0)));
|
||||
resultsActionsPanel.add(resultsInfoLabel);
|
||||
resultsActionsPanel.add(Box.createHorizontalGlue());
|
||||
addResultsActions(resultsActionsPanel);
|
||||
|
||||
JPanel resultsPanel = new JPanel();
|
||||
resultsPanel.setLayout(new BoxLayout(resultsPanel, BoxLayout.PAGE_AXIS));
|
||||
@@ -268,7 +267,10 @@ public abstract class CommonSearchDialog extends JFrame {
|
||||
return resultsPanel;
|
||||
}
|
||||
|
||||
protected void addCustomResultsActions(JPanel actionsPanel) {
|
||||
protected void addResultsActions(JPanel resultsActionsPanel) {
|
||||
resultsActionsPanel.add(Box.createRigidArea(new Dimension(20, 0)));
|
||||
resultsActionsPanel.add(resultsInfoLabel);
|
||||
resultsActionsPanel.add(Box.createHorizontalGlue());
|
||||
}
|
||||
|
||||
protected void updateProgressLabel(boolean complete) {
|
||||
@@ -365,6 +367,10 @@ public abstract class CommonSearchDialog extends JFrame {
|
||||
rows.clear();
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
Collections.sort(rows);
|
||||
}
|
||||
|
||||
public boolean isAddDescColumn() {
|
||||
return addDescColumn;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
@@ -58,7 +56,7 @@ import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.TextStandardActions;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
import jadx.gui.utils.layout.WrapLayout;
|
||||
import jadx.gui.utils.ui.DocumentUpdateListener;
|
||||
import jadx.gui.utils.rx.RxUtils;
|
||||
|
||||
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.ACTIVE_TAB;
|
||||
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.CLASS;
|
||||
@@ -119,6 +117,8 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
private transient @Nullable SearchTask searchTask;
|
||||
private transient JButton loadAllButton;
|
||||
private transient JButton loadMoreButton;
|
||||
private transient JButton stopBtn;
|
||||
private transient JButton sortBtn;
|
||||
|
||||
private transient Disposable searchDisposable;
|
||||
private transient SearchEventEmitter searchEmitter;
|
||||
@@ -142,7 +142,7 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
|
||||
loadWindowPos();
|
||||
initUI();
|
||||
searchFieldSubscribe();
|
||||
initSearchEvents();
|
||||
registerInitOnOpen();
|
||||
registerActiveTabListener();
|
||||
}
|
||||
@@ -208,9 +208,30 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
searchField.setAlignmentX(LEFT_ALIGNMENT);
|
||||
TextStandardActions.attach(searchField);
|
||||
|
||||
boolean autoSearch = mainWindow.getSettings().isUseAutoSearch();
|
||||
JButton searchBtn = new JButton(NLS.str("search_dialog.search_button"));
|
||||
searchBtn.setVisible(!autoSearch);
|
||||
searchBtn.addActionListener(ev -> searchEmitter.emitSearch());
|
||||
|
||||
JCheckBox autoSearchCB = new JCheckBox(NLS.str("search_dialog.auto_search"));
|
||||
autoSearchCB.setSelected(autoSearch);
|
||||
autoSearchCB.addActionListener(ev -> {
|
||||
boolean newValue = autoSearchCB.isSelected();
|
||||
mainWindow.getSettings().setUseAutoSearch(newValue);
|
||||
searchBtn.setVisible(!newValue);
|
||||
initSearchEvents();
|
||||
if (newValue) {
|
||||
searchEmitter.emitSearch();
|
||||
}
|
||||
});
|
||||
|
||||
JPanel searchLinePanel = new JPanel();
|
||||
searchLinePanel.setLayout(new BoxLayout(searchLinePanel, BoxLayout.LINE_AXIS));
|
||||
searchLinePanel.add(searchField);
|
||||
searchLinePanel.add(Box.createRigidArea(new Dimension(5, 0)));
|
||||
searchLinePanel.add(searchBtn);
|
||||
searchLinePanel.add(Box.createRigidArea(new Dimension(5, 0)));
|
||||
searchLinePanel.add(autoSearchCB);
|
||||
searchLinePanel.setAlignmentX(LEFT_ALIGNMENT);
|
||||
|
||||
JLabel findLabel = new JLabel(NLS.str("search_dialog.open_by_name"));
|
||||
@@ -261,22 +282,11 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
contentPanel.add(buttonPane, BorderLayout.PAGE_END);
|
||||
getContentPane().add(contentPanel);
|
||||
|
||||
searchField.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
if (resultsModel.getRowCount() != 0) {
|
||||
resultsTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
resultsTable.requestFocus();
|
||||
}
|
||||
}
|
||||
});
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
}
|
||||
|
||||
protected void addCustomResultsActions(JPanel resultsActionsPanel) {
|
||||
protected void addResultsActions(JPanel resultsActionsPanel) {
|
||||
loadAllButton = new JButton(NLS.str("search_dialog.load_all"));
|
||||
loadAllButton.addActionListener(e -> loadMoreResults(true));
|
||||
loadAllButton.setEnabled(false);
|
||||
@@ -285,9 +295,29 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
loadMoreButton.addActionListener(e -> loadMoreResults(false));
|
||||
loadMoreButton.setEnabled(false);
|
||||
|
||||
stopBtn = new JButton(NLS.str("search_dialog.stop"));
|
||||
stopBtn.addActionListener(e -> pauseSearch());
|
||||
stopBtn.setEnabled(false);
|
||||
|
||||
sortBtn = new JButton(NLS.str("search_dialog.sort_results"));
|
||||
sortBtn.addActionListener(e -> {
|
||||
synchronized (pendingResults) {
|
||||
resultsModel.sort();
|
||||
resultsTable.updateTable();
|
||||
}
|
||||
});
|
||||
sortBtn.setEnabled(false);
|
||||
|
||||
resultsActionsPanel.add(loadAllButton);
|
||||
resultsActionsPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
resultsActionsPanel.add(loadMoreButton);
|
||||
resultsActionsPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
resultsActionsPanel.add(stopBtn);
|
||||
resultsActionsPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
resultsActionsPanel.add(stopBtn);
|
||||
super.addResultsActions(resultsActionsPanel);
|
||||
resultsActionsPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
resultsActionsPanel.add(sortBtn);
|
||||
}
|
||||
|
||||
private class SearchEventEmitter {
|
||||
@@ -311,10 +341,19 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
}
|
||||
}
|
||||
|
||||
private void searchFieldSubscribe() {
|
||||
private void initSearchEvents() {
|
||||
if (searchDisposable != null) {
|
||||
searchDisposable.dispose();
|
||||
searchDisposable = null;
|
||||
}
|
||||
searchEmitter = new SearchEventEmitter();
|
||||
Flowable<String> textChanges = onTextFieldChanges(searchField);
|
||||
Flowable<String> searchEvents = Flowable.merge(textChanges, searchEmitter.getFlowable());
|
||||
Flowable<String> searchEvents;
|
||||
if (mainWindow.getSettings().isUseAutoSearch()) {
|
||||
searchEvents = Flowable.merge(RxUtils.textFieldChanges(searchField),
|
||||
RxUtils.textFieldEnterPress(searchField), searchEmitter.getFlowable());
|
||||
} else {
|
||||
searchEvents = Flowable.merge(RxUtils.textFieldEnterPress(searchField), searchEmitter.getFlowable());
|
||||
}
|
||||
searchDisposable = searchEvents
|
||||
.debounce(50, TimeUnit.MILLISECONDS)
|
||||
.observeOn(Schedulers.from(searchBackgroundExecutor))
|
||||
@@ -424,6 +463,15 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void pauseSearch() {
|
||||
stopBtn.setEnabled(false);
|
||||
searchBackgroundExecutor.execute(() -> {
|
||||
if (searchTask != null) {
|
||||
searchTask.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void stopSearchTask() {
|
||||
UiUtils.notUiThreadGuard();
|
||||
if (searchTask != null) {
|
||||
@@ -462,6 +510,9 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
}
|
||||
|
||||
private void prepareForSearch() {
|
||||
UiUtils.uiThreadGuard();
|
||||
stopBtn.setEnabled(true);
|
||||
sortBtn.setEnabled(false);
|
||||
showSearchState();
|
||||
progressStartCommon();
|
||||
}
|
||||
@@ -502,9 +553,11 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
LOG.debug("Search complete: {}, complete: {}", status, complete);
|
||||
loadAllButton.setEnabled(!complete);
|
||||
loadMoreButton.setEnabled(!complete);
|
||||
stopBtn.setEnabled(false);
|
||||
progressFinishedCommon();
|
||||
updateTable();
|
||||
updateProgressLabel(complete);
|
||||
sortBtn.setEnabled(resultsModel.getRowCount() != 0);
|
||||
}
|
||||
|
||||
private void unloadTempData() {
|
||||
@@ -512,30 +565,6 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
private static Flowable<String> onTextFieldChanges(final JTextField textField) {
|
||||
return Flowable.<String>create(emitter -> {
|
||||
DocumentUpdateListener listener = new DocumentUpdateListener(
|
||||
ev -> emitter.onNext(textField.getText()));
|
||||
|
||||
textField.getDocument().addDocumentListener(listener);
|
||||
emitter.setDisposable(new Disposable() {
|
||||
private boolean disposed = false;
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
textField.getDocument().removeDocumentListener(listener);
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisposed() {
|
||||
return disposed;
|
||||
}
|
||||
});
|
||||
}, BackpressureStrategy.LATEST)
|
||||
.distinctUntilChanged();
|
||||
}
|
||||
|
||||
private JCheckBox makeOptionsCheckBox(String name, final SearchOptions opt) {
|
||||
final JCheckBox chBox = new JCheckBox(name);
|
||||
chBox.setAlignmentX(LEFT_ALIGNMENT);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package jadx.gui.utils.rx;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import io.reactivex.disposables.Disposable;
|
||||
|
||||
public class CustomDisposable implements Disposable {
|
||||
|
||||
private final AtomicBoolean disposed = new AtomicBoolean(false);
|
||||
private final Runnable disposeTask;
|
||||
|
||||
public CustomDisposable(Runnable disposeTask) {
|
||||
this.disposeTask = disposeTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
disposeTask.run();
|
||||
} finally {
|
||||
disposed.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisposed() {
|
||||
return disposed.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package jadx.gui.utils.rx;
|
||||
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import io.reactivex.BackpressureStrategy;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.FlowableOnSubscribe;
|
||||
|
||||
import jadx.gui.utils.ui.DocumentUpdateListener;
|
||||
|
||||
public class RxUtils {
|
||||
|
||||
public static Flowable<String> textFieldChanges(final JTextField textField) {
|
||||
FlowableOnSubscribe<String> source = emitter -> {
|
||||
DocumentListener listener = new DocumentUpdateListener(ev -> emitter.onNext(textField.getText()));
|
||||
textField.getDocument().addDocumentListener(listener);
|
||||
emitter.setDisposable(new CustomDisposable(() -> textField.getDocument().removeDocumentListener(listener)));
|
||||
};
|
||||
return Flowable.create(source, BackpressureStrategy.LATEST).distinctUntilChanged();
|
||||
}
|
||||
|
||||
public static Flowable<String> textFieldEnterPress(final JTextField textField) {
|
||||
FlowableOnSubscribe<String> source = emitter -> {
|
||||
KeyListener keyListener = new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent ev) {
|
||||
if (ev.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
emitter.onNext(textField.getText());
|
||||
}
|
||||
}
|
||||
};
|
||||
textField.addKeyListener(keyListener);
|
||||
emitter.setDisposable(new CustomDisposable(() -> textField.removeKeyListener(keyListener)));
|
||||
};
|
||||
return Flowable.create(source, BackpressureStrategy.LATEST).distinctUntilChanged();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -96,6 +96,8 @@ file_dialog.load_dir_confirm=Alle Dateien aus dem Verzeichnis laden?
|
||||
search_dialog.open=Öffnen
|
||||
search_dialog.cancel=Beenden
|
||||
search_dialog.open_by_name=Nach Text suchen:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Suche in Definitionen von:
|
||||
search_dialog.class=Klassen
|
||||
search_dialog.method=Methoden
|
||||
@@ -105,10 +107,12 @@ search_dialog.options=Suchoptionen:
|
||||
search_dialog.ignorecase=Groß/Kleinschreibung ignorieren
|
||||
search_dialog.load_more=Mehr laden
|
||||
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.col_node=Knoten
|
||||
search_dialog.col_code=Code
|
||||
#search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=Regex
|
||||
search_dialog.active_tab=Nur aktiver Tab
|
||||
search_dialog.comments=Kommentare
|
||||
|
||||
@@ -96,19 +96,23 @@ file_dialog.load_dir_confirm=Load all files from directory?
|
||||
search_dialog.open=Open
|
||||
search_dialog.cancel=Cancel
|
||||
search_dialog.open_by_name=Search for text:
|
||||
search_dialog.search_button=Search
|
||||
search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Search definitions of:
|
||||
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
|
||||
search_dialog.ignorecase=Case-insensitive
|
||||
search_dialog.load_more=Load more
|
||||
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.col_node=Node
|
||||
search_dialog.col_code=Code
|
||||
search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=Regex
|
||||
search_dialog.active_tab=Active tab only
|
||||
search_dialog.comments=Comments
|
||||
|
||||
@@ -96,6 +96,8 @@ nav.forward=Adelante
|
||||
search_dialog.open=Abrir
|
||||
search_dialog.cancel=Cancelar
|
||||
search_dialog.open_by_name=Buscar texto:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Buscar definiciones de:
|
||||
search_dialog.class=Clase
|
||||
search_dialog.method=Método
|
||||
@@ -105,10 +107,12 @@ search_dialog.options=Opciones de búsqueda:
|
||||
search_dialog.ignorecase=Ignorar minúsculas/mayúsculas
|
||||
#search_dialog.load_more=Load more
|
||||
#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.col_node=Nodo
|
||||
search_dialog.col_code=Código
|
||||
#search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=Regex
|
||||
#search_dialog.active_tab=Active tab only
|
||||
#search_dialog.comments=Comments
|
||||
|
||||
@@ -96,6 +96,8 @@ common_dialog.remove=삭제
|
||||
search_dialog.open=열기
|
||||
search_dialog.cancel=취소
|
||||
search_dialog.open_by_name=텍스트 검색 :
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=정의 검색 :
|
||||
search_dialog.class=클래스
|
||||
search_dialog.method=메소드
|
||||
@@ -105,10 +107,12 @@ search_dialog.options=옵션 검색:
|
||||
search_dialog.ignorecase=대소문자 구분 안함
|
||||
#search_dialog.load_more=Load more
|
||||
#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.col_node=노드
|
||||
search_dialog.col_code=코드
|
||||
#search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=정규식
|
||||
search_dialog.active_tab=열려 있는 탭에서만 검색
|
||||
search_dialog.comments=주석
|
||||
|
||||
@@ -96,6 +96,8 @@ file_dialog.load_dir_confirm=Carregar todos arquivos do diretório?
|
||||
search_dialog.open=Abrir
|
||||
search_dialog.cancel=Cancelar
|
||||
search_dialog.open_by_name=Buscar por text:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=Buscar definições de:
|
||||
search_dialog.class=Classe
|
||||
search_dialog.method=Método
|
||||
@@ -105,10 +107,12 @@ search_dialog.options=Opções de busca:
|
||||
search_dialog.ignorecase=Não diferencia maiúsculas de minúsculas
|
||||
search_dialog.load_more=Carregar mais
|
||||
search_dialog.load_all=Carregar todas
|
||||
#search_dialog.stop=Stop
|
||||
search_dialog.results_incomplete=Encontradas %d+
|
||||
search_dialog.results_complete=Encontradas %d (complete)
|
||||
search_dialog.col_node=Nó
|
||||
search_dialog.col_code=Código
|
||||
#search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=Regex
|
||||
search_dialog.active_tab=Apenas abas ativas
|
||||
search_dialog.comments=Comentários
|
||||
|
||||
@@ -96,6 +96,8 @@ file_dialog.load_dir_confirm=从目录中加载所有文件?
|
||||
search_dialog.open=转到
|
||||
search_dialog.cancel=取消
|
||||
search_dialog.open_by_name=搜索文本:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=在以下位置搜索:
|
||||
search_dialog.class=类名
|
||||
search_dialog.method=方法名
|
||||
@@ -105,10 +107,12 @@ search_dialog.options=搜索选项:
|
||||
search_dialog.ignorecase=忽略大小写
|
||||
search_dialog.load_more=加载更多
|
||||
search_dialog.load_all=加载所有
|
||||
#search_dialog.stop=Stop
|
||||
search_dialog.results_incomplete=已找到 %d+
|
||||
search_dialog.results_complete=全部找到 %d
|
||||
search_dialog.col_node=节点
|
||||
search_dialog.col_code=代码
|
||||
#search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=正则表达式
|
||||
search_dialog.active_tab=只在当前页搜索
|
||||
search_dialog.comments=注释
|
||||
|
||||
@@ -96,6 +96,8 @@ file_dialog.load_dir_confirm=要載入目錄中的所有檔案嗎?
|
||||
search_dialog.open=開啟
|
||||
search_dialog.cancel=取消
|
||||
search_dialog.open_by_name=搜尋文字:
|
||||
#search_dialog.search_button=Search
|
||||
#search_dialog.auto_search=Auto search
|
||||
search_dialog.search_in=搜尋定義:
|
||||
search_dialog.class=類別
|
||||
search_dialog.method=方法
|
||||
@@ -105,10 +107,12 @@ search_dialog.options=搜尋選項:
|
||||
search_dialog.ignorecase=不區分大小寫
|
||||
search_dialog.load_more=載入更多
|
||||
search_dialog.load_all=載入全部
|
||||
#search_dialog.stop=Stop
|
||||
search_dialog.results_incomplete=找到 %d+
|
||||
search_dialog.results_complete=找到 %d (完整)
|
||||
search_dialog.col_node=無
|
||||
search_dialog.col_code=程式碼
|
||||
#search_dialog.sort_results=Sort results
|
||||
search_dialog.regex=Regex
|
||||
search_dialog.active_tab=僅使用中分頁
|
||||
search_dialog.comments=註解
|
||||
|
||||
Reference in New Issue
Block a user