From 3d78119fe1dbea3c15ae8b035dc351e85d284601 Mon Sep 17 00:00:00 2001 From: Phillipus Date: Fri, 17 Jan 2025 11:27:03 +0000 Subject: [PATCH] Search Filter supports Regex and remembers some settings --- .../views/tree/search/SearchFilter.java | 71 ++++++++++++++++--- .../views/tree/search/SearchWidget.java | 22 ++++++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java index 2834438fa..4e4685886 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java @@ -7,6 +7,7 @@ import java.util.HashSet; import java.util.Set; +import java.util.regex.Pattern; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; @@ -41,15 +42,20 @@ public class SearchFilter extends ViewerFilter { private Set fConceptsFilter = new HashSet<>(); private Set fPropertiesFilter = new HashSet<>(); private Set fSpecializationsFilter = new HashSet<>(); - private boolean fFilterViews = false; - - private boolean fShowAllFolders = false; + + private boolean fFilterViews; + private boolean fShowAllFolders; + + private boolean fMatchCase; + private boolean fUseRegex; + private Pattern fRegexPattern; SearchFilter() { } void setSearchText(String text) { fSearchText = text; + createRegexPattern(); } void reset() { @@ -136,7 +142,7 @@ private boolean shouldShowObjectWithName(Object element) { // Normalise in case of multi-line text name = StringUtils.normaliseNewLineCharacters(name); - return name.toLowerCase().contains(fSearchText.toLowerCase()); + return matchesString(name); } return false; @@ -145,7 +151,7 @@ private boolean shouldShowObjectWithName(Object element) { private boolean shouldShowObjectWithDocumentation(Object element) { if(element instanceof IDocumentable documentable) { String text = StringUtils.safeString(documentable.getDocumentation()); - return text.toLowerCase().contains(fSearchText.toLowerCase()); + return matchesString(text); } return false; @@ -170,13 +176,45 @@ private boolean shouldShowProperty(Object element) { if(element instanceof IProperties properties) { for(IProperty property : properties.getProperties()) { if(fPropertiesFilter.contains(property.getKey())) { - return hasSearchText() ? property.getValue().toLowerCase().contains(fSearchText.toLowerCase()) : true; + return hasSearchText() ? matchesString(property.getValue()) : true; } } } return false; } + + private boolean matchesString(String str) { + if(str == null || str.length() == 0) { + return false; + } + + if(isUseRegex()) { + return matchesRegexString(str); + } + + if(isMatchCase()) { + return str.contains(fSearchText); + } + + return str.toLowerCase().contains(fSearchText.toLowerCase()); + } + + private boolean matchesRegexString(String searchString) { + return fRegexPattern != null ? fRegexPattern.matcher(searchString).find() : false; + } + + private void createRegexPattern() { + fRegexPattern = null; + + if(isUseRegex()) { + try { + fRegexPattern = Pattern.compile(fSearchText, isMatchCase() ? 0 : Pattern.CASE_INSENSITIVE); + } + catch(Exception ex) { + } + } + } public boolean isFiltering() { return isFilteringName() || isFilteringDocumentation() || isFilteringConcepts() || isFilteringPropertyKeys() || isFilteringSpecializations() || isFilteringViews(); @@ -206,7 +244,25 @@ private boolean hasSearchText() { return fSearchText.length() > 0; } - void setFilterOnName(boolean set) { + void setMatchCase(boolean set) { + fMatchCase = set; + createRegexPattern(); + } + + boolean isMatchCase() { + return fMatchCase; + } + + void setUseRegex(boolean set) { + fUseRegex = set; + createRegexPattern(); + } + + boolean isUseRegex() { + return fUseRegex; + } + + void setFilterOnName(boolean set) { fFilterName = set; } @@ -269,5 +325,4 @@ void setFilterViews(boolean set) { boolean isFilteringViews() { return fFilterViews; } - } \ No newline at end of file diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java index a1f178c67..5db69a0e2 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java @@ -338,6 +338,28 @@ public void run() { actionFolders.setChecked(fSearchFilter.isShowAllFolders()); dropDownAction.add(actionFolders); + // Match Case + IAction actionMatchCase = new Action("Match Case", IAction.AS_CHECK_BOX) { + @Override + public void run() { + fSearchFilter.setMatchCase(isChecked()); + refreshTree(); + } + }; + actionMatchCase.setChecked(fSearchFilter.isMatchCase()); + dropDownAction.add(actionMatchCase); + + // Regex + IAction actionUseRegex = new Action("Match Regular Expression", IAction.AS_CHECK_BOX) { + @Override + public void run() { + fSearchFilter.setUseRegex(isChecked()); + refreshTree(); + } + }; + actionUseRegex.setChecked(fSearchFilter.isUseRegex()); + dropDownAction.add(actionUseRegex); + dropDownAction.add(new Separator()); // Reset