introduce full-text-search inside i18n tool window
This commit is contained in:
parent
1b1705a661
commit
a34ae7e02f
@ -97,9 +97,9 @@ public class TableView implements BusListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSearchQuery(@Nullable String query) {
|
public void onSearchQuery(@Nullable String query) {
|
||||||
// TODO: handle search functionality
|
|
||||||
if(this.currentMapper != null) {
|
if(this.currentMapper != null) {
|
||||||
this.currentMapper.onSearchQuery(query);
|
this.currentMapper.onSearchQuery(query);
|
||||||
|
this.table.updateUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,14 +41,14 @@ public class TreeView implements BusListener {
|
|||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
|
|
||||||
|
private TreeModelMapper currentMapper;
|
||||||
|
|
||||||
private JPanel rootPanel;
|
private JPanel rootPanel;
|
||||||
private JPanel toolBarPanel;
|
private JPanel toolBarPanel;
|
||||||
private JPanel containerPanel;
|
private JPanel containerPanel;
|
||||||
|
|
||||||
private Tree tree;
|
private Tree tree;
|
||||||
|
|
||||||
private TreeModelMapper mapper;
|
|
||||||
|
|
||||||
public TreeView(Project project) {
|
public TreeView(Project project) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
|
|
||||||
@ -81,19 +81,23 @@ public class TreeView implements BusListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdateData(@NotNull TranslationData data) {
|
public void onUpdateData(@NotNull TranslationData data) {
|
||||||
tree.setModel(this.mapper = new TreeModelMapper(data, SettingsService.getInstance(project).getState(), null));
|
tree.setModel(this.currentMapper = new TreeModelMapper(data, SettingsService.getInstance(project).getState()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFocusKey(@Nullable String key) {
|
public void onFocusKey(@Nullable String key) {
|
||||||
if(key != null && mapper != null) {
|
if(key != null && currentMapper != null) {
|
||||||
this.tree.scrollPathToVisible(mapper.findTreePath(key));
|
this.tree.scrollPathToVisible(currentMapper.findTreePath(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSearchQuery(@Nullable String query) {
|
public void onSearchQuery(@Nullable String query) {
|
||||||
// TODO: handle search functionality
|
if(this.currentMapper != null) {
|
||||||
|
this.currentMapper.onSearchQuery(query);
|
||||||
|
this.expandAll().run();
|
||||||
|
this.tree.updateUI();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePopup(MouseEvent e) {
|
private void handlePopup(MouseEvent e) {
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package de.marhali.easyi18n.tabs.mapper;
|
package de.marhali.easyi18n.tabs.mapper;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.*;
|
import de.marhali.easyi18n.model.*;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.bus.BusListener;
|
|
||||||
import de.marhali.easyi18n.model.bus.SearchQueryListener;
|
import de.marhali.easyi18n.model.bus.SearchQueryListener;
|
||||||
import de.marhali.easyi18n.model.bus.UpdateDataListener;
|
|
||||||
import org.jetbrains.annotations.Nls;
|
import org.jetbrains.annotations.Nls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -12,7 +10,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@ -24,7 +21,7 @@ public class TableModelMapper implements TableModel, SearchQueryListener {
|
|||||||
|
|
||||||
private final @NotNull TranslationData data;
|
private final @NotNull TranslationData data;
|
||||||
private final @NotNull List<String> locales;
|
private final @NotNull List<String> locales;
|
||||||
private final @NotNull List<String> fullKeys;
|
private @NotNull List<String> fullKeys;
|
||||||
|
|
||||||
private final @NotNull Consumer<TranslationUpdate> updater;
|
private final @NotNull Consumer<TranslationUpdate> updater;
|
||||||
|
|
||||||
@ -38,7 +35,27 @@ public class TableModelMapper implements TableModel, SearchQueryListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSearchQuery(@Nullable String query) {
|
public void onSearchQuery(@Nullable String query) {
|
||||||
this.fullKeys = new ArrayList<>();
|
if(query == null) { // Reset
|
||||||
|
this.fullKeys = new ArrayList<>(this.data.getFullKeys());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
query = query.toLowerCase();
|
||||||
|
List<String> matches = new ArrayList<>();
|
||||||
|
|
||||||
|
for(String key : this.data.getFullKeys()) {
|
||||||
|
if(key.toLowerCase().contains(query)) {
|
||||||
|
matches.add(key);
|
||||||
|
} else {
|
||||||
|
for(String content : this.data.getTranslation(key).values()) {
|
||||||
|
if(content.toLowerCase().contains(query)) {
|
||||||
|
matches.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fullKeys = matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,6 +6,7 @@ import com.intellij.ui.JBColor;
|
|||||||
import de.marhali.easyi18n.model.SettingsState;
|
import de.marhali.easyi18n.model.SettingsState;
|
||||||
import de.marhali.easyi18n.model.TranslationData;
|
import de.marhali.easyi18n.model.TranslationData;
|
||||||
import de.marhali.easyi18n.model.TranslationNode;
|
import de.marhali.easyi18n.model.TranslationNode;
|
||||||
|
import de.marhali.easyi18n.model.bus.SearchQueryListener;
|
||||||
import de.marhali.easyi18n.util.PathUtil;
|
import de.marhali.easyi18n.util.PathUtil;
|
||||||
import de.marhali.easyi18n.util.UiUtil;
|
import de.marhali.easyi18n.util.UiUtil;
|
||||||
|
|
||||||
@ -20,31 +21,46 @@ import java.util.Map;
|
|||||||
* Mapping {@link TranslationData} to {@link TreeModel}.
|
* Mapping {@link TranslationData} to {@link TreeModel}.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
public class TreeModelMapper extends DefaultTreeModel {
|
public class TreeModelMapper extends DefaultTreeModel implements SearchQueryListener {
|
||||||
|
|
||||||
private final TranslationData data;
|
private final TranslationData data;
|
||||||
private final SettingsState state;
|
private final SettingsState state;
|
||||||
|
|
||||||
public TreeModelMapper(TranslationData data, SettingsState state, String searchQuery) {
|
public TreeModelMapper(TranslationData data, SettingsState state) {
|
||||||
super(null);
|
super(null);
|
||||||
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
|
||||||
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||||
this.generateNodes(rootNode, this.data.getRootNode());
|
this.generateNodes(rootNode, this.data.getRootNode(), null);
|
||||||
super.setRoot(rootNode);
|
super.setRoot(rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateNodes(DefaultMutableTreeNode parent, TranslationNode translationNode) {
|
@Override
|
||||||
|
public void onSearchQuery(@Nullable String query) {
|
||||||
|
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||||
|
this.generateNodes(rootNode, this.data.getRootNode(), query);
|
||||||
|
super.setRoot(rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateNodes(@NotNull DefaultMutableTreeNode parent,
|
||||||
|
@NotNull TranslationNode translationNode, @Nullable String searchQuery) {
|
||||||
for(Map.Entry<String, TranslationNode> entry : translationNode.getChildren().entrySet()) {
|
for(Map.Entry<String, TranslationNode> entry : translationNode.getChildren().entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
TranslationNode childTranslationNode = entry.getValue();
|
TranslationNode childTranslationNode = entry.getValue();
|
||||||
|
|
||||||
|
if(searchQuery != null) {
|
||||||
|
searchQuery = searchQuery.toLowerCase();
|
||||||
|
if(!this.isApplicable(key, childTranslationNode, searchQuery)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!childTranslationNode.isLeaf()) {
|
if(!childTranslationNode.isLeaf()) {
|
||||||
// Nested node - run recursively
|
// Nested node - run recursively
|
||||||
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(key);
|
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(key);
|
||||||
this.generateNodes(childNode, childTranslationNode);
|
this.generateNodes(childNode, childTranslationNode, searchQuery);
|
||||||
parent.add(childNode);
|
parent.add(childNode);
|
||||||
} else {
|
} else {
|
||||||
String previewLocale = this.state.getPreviewLocale();
|
String previewLocale = this.state.getPreviewLocale();
|
||||||
@ -63,6 +79,35 @@ public class TreeModelMapper extends DefaultTreeModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provided tree (@node) is applicable for the search string.
|
||||||
|
* A full-text-search is applied and section keys and every value will be evaluated.
|
||||||
|
* @param key Section key
|
||||||
|
* @param node Node which has @key as key
|
||||||
|
* @param searchQuery Search query to search for
|
||||||
|
* @return True if this node or ANY child is relevant for the search context
|
||||||
|
*/
|
||||||
|
private boolean isApplicable(@NotNull String key, @NotNull TranslationNode node, @NotNull String searchQuery) {
|
||||||
|
if(key.toLowerCase().contains(searchQuery)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!node.isLeaf()) {
|
||||||
|
for(Map.Entry<String, TranslationNode> entry : node.getChildren().entrySet()) {
|
||||||
|
if(this.isApplicable(entry.getKey(), entry.getValue(), searchQuery)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(String content : node.getValue().values()) {
|
||||||
|
if(content.toLowerCase().contains(searchQuery)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public @NotNull TreePath findTreePath(@NotNull String fullPath) {
|
public @NotNull TreePath findTreePath(@NotNull String fullPath) {
|
||||||
List<String> sections = new PathUtil(this.state.isNestedKeys()).split(fullPath);
|
List<String> sections = new PathUtil(this.state.isNestedKeys()).split(fullPath);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user