Skip to content
Snippets Groups Projects
Commit 199c8154 authored by Andreas Bayha's avatar Andreas Bayha
Browse files

Annotations: Improved code

- The filter is now better integrated with the content provider.
- Javadoc comments.

Issue-Ref: 4014
Issue-Url: https://af3-developer.fortiss.org/issues/4014


Signed-off-by: default avatarAndreas Bayha <bayha@fortiss.org>
parent b66f1288
No related branches found
No related tags found
1 merge request!1254014
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
<?import javafx.scene.control.RadioButton?> <?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.SplitPane?> <?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?> <?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.control.TreeTableView?> <?import javafx.scene.control.TreeTableView?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
...@@ -27,12 +26,8 @@ ...@@ -27,12 +26,8 @@
<HBox prefHeight="40.0" prefWidth="148.0" spacing="5.0"> <HBox prefHeight="40.0" prefWidth="148.0" spacing="5.0">
<children> <children>
<Label minHeight="20.0" text="Filter:" /> <Label minHeight="20.0" text="Filter:" />
<RadioButton fx:id="radBtnFilterModelElements" minHeight="20.0" mnemonicParsing="false" text="model elements"> <RadioButton fx:id="radBtnFilterModelElements" minHeight="20.0" mnemonicParsing="false" text="model elements" />
<toggleGroup> <RadioButton fx:id="radBtnFilterAnnotationNames" minHeight="20.0" mnemonicParsing="false" text="annotation names:" />
<ToggleGroup fx:id="filterGroup" />
</toggleGroup>
</RadioButton>
<RadioButton fx:id="radBtnFilterAnnotationNames" minHeight="20.0" mnemonicParsing="false" text="annotation names:" toggleGroup="$filterGroup" />
<CheckBox fx:id="chkBoxMatchCase" mnemonicParsing="false" text="match case" /> <CheckBox fx:id="chkBoxMatchCase" mnemonicParsing="false" text="match case" />
</children> </children>
</HBox> </HBox>
......
AnnotationFxViewPart.java 34c845f7162a8a8bb680df6ee08160ce63a5a5a3 YELLOW AnnotationFxViewPart.java 34c845f7162a8a8bb680df6ee08160ce63a5a5a3 YELLOW
AnnotationViewFXController.java 50e745f4f700b165c3d138d9f9cd2463252da31d RED AnnotationViewFXController.java 00c64dbad1bd9ae071360ebe3d071705c8d2a68c YELLOW
FXAnnotationFilter.java 05bc78a530becbce573545d67e5b0ef9ac3f697f YELLOW FXAnnotationFilterContentProvider.java 6c92d9c96fb2a2441256f70e20a20b1287018a9f YELLOW
...@@ -15,11 +15,13 @@ ...@@ -15,11 +15,13 @@
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.annotation.view.fx; package org.fortiss.tooling.base.ui.annotation.view.fx;
import static java.util.Collections.emptyList;
import static java.util.regex.Pattern.CASE_INSENSITIVE; import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static java.util.regex.Pattern.DOTALL; import static java.util.regex.Pattern.DOTALL;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getModelElementAncestor; import static org.fortiss.tooling.kernel.utils.EcoreUtils.getModelElementAncestor;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getModelElementLevel; import static org.fortiss.tooling.kernel.utils.EcoreUtils.getModelElementLevel;
import java.util.Collection;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
...@@ -27,21 +29,25 @@ import org.eclipse.emf.ecore.EObject; ...@@ -27,21 +29,25 @@ import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.base.annotation.AnnotationEntry; import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification; import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IModelElement; import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationViewFXController.ArtificialRoot;
import org.fortiss.tooling.base.ui.annotation.view.generic.ColumnHandle; import org.fortiss.tooling.base.ui.annotation.view.generic.ColumnHandle;
import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeContentProviderBase;
import org.fortiss.tooling.kernel.model.INamedElement; import org.fortiss.tooling.kernel.model.INamedElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement; import org.fortiss.tooling.kernel.model.IProjectRootElement;
/** /**
* Row and column filter for the {@link AnnotationViewFXController}. * Content provider with row and column filter for the {@link AnnotationViewFXController}.
* <ul> * <ul>
* {@link FXAnnotationFilter#passesColumnFilter(ColumnHandle)} that is evaluated * {@link FXAnnotationFilterContentProvider#passesColumnFilter(ColumnHandle)}
* during the update of the {@link AnnotationViewFXController}.</li> * that is evaluated during the update of the
* {@link AnnotationViewFXController}.</li>
* </ul> * </ul>
* *
* @author barner * @author barner
* @author bayha * @author bayha
*/ */
public class FXAnnotationFilter { public class FXAnnotationFilterContentProvider
extends DynamicTreeContentProviderBase<AnnotationEntry> {
/** Filter hint text. */ /** Filter hint text. */
static final String FILTER_HINT_TEXT = "type filter text (regex)"; static final String FILTER_HINT_TEXT = "type filter text (regex)";
...@@ -83,6 +89,13 @@ public class FXAnnotationFilter { ...@@ -83,6 +89,13 @@ public class FXAnnotationFilter {
/** Column filter option based on annotation type. */ /** Column filter option based on annotation type. */
private Class<? extends IAnnotatedSpecification> annotationTypeFilter; private Class<? extends IAnnotatedSpecification> annotationTypeFilter;
/** Constructor */
public FXAnnotationFilterContentProvider() {
// Initialize filter expression to enable filtering also for empty patterns.
// (i.e. if only columns hall be filtered).
setFilterExpression("*");
}
/** /**
* Returns {@code true} if a given {@code input} passes a case-insensitive * Returns {@code true} if a given {@code input} passes a case-insensitive
* filter specified by {@code filterString}. * filter specified by {@code filterString}.
...@@ -91,12 +104,12 @@ public class FXAnnotationFilter { ...@@ -91,12 +104,12 @@ public class FXAnnotationFilter {
// Null-filter accepts every input. This covers also the case when the pattern // Null-filter accepts every input. This covers also the case when the pattern
// provided by // provided by
// the user is invalid. // the user is invalid.
if (filterPattern == null) { if(filterPattern == null) {
return true; return true;
} }
// Null-input cannot be accepted by a non-null filter // Null-input cannot be accepted by a non-null filter
if (input == null) { if(input == null) {
return false; return false;
} }
...@@ -108,30 +121,31 @@ public class FXAnnotationFilter { ...@@ -108,30 +121,31 @@ public class FXAnnotationFilter {
* model element (or if this particular filter option is turned off). * model element (or if this particular filter option is turned off).
*/ */
private boolean passesSelectedElementTypeFilter(AnnotationEntry annotationEntry) { private boolean passesSelectedElementTypeFilter(AnnotationEntry annotationEntry) {
boolean selectedElementIsInvalid = currentlySelectedModelElement == null boolean selectedElementIsInvalid = currentlySelectedModelElement == null ||
|| currentlySelectedModelElement instanceof IProjectRootElement; currentlySelectedModelElement instanceof IProjectRootElement;
if (selectedElementIsInvalid || hierarchyLevelFilter == null) { if(selectedElementIsInvalid || hierarchyLevelFilter == null) {
return true; return true;
} }
IModelElement modelElement = annotationEntry.getModelElement(); IModelElement modelElement = annotationEntry.getModelElement();
int modelElementLevel = getModelElementLevel(modelElement); int modelElementLevel = getModelElementLevel(modelElement);
int currentlySelectedModelElementLevel = getModelElementLevel(currentlySelectedModelElement); int currentlySelectedModelElementLevel =
getModelElementLevel(currentlySelectedModelElement);
if (hierarchyLevelFilter.equals(HIERARCHY_LEVELS_CURRENT)) { if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_CURRENT)) {
// Elements have different levels -> filter // Elements have different levels -> filter
if (modelElementLevel != currentlySelectedModelElementLevel) { if(modelElementLevel != currentlySelectedModelElementLevel) {
return false; return false;
} }
if (currentlySelectedModelElement.eContainer() != modelElement.eContainer()) { if(currentlySelectedModelElement.eContainer() != modelElement.eContainer()) {
return false; return false;
} }
} }
if (hierarchyLevelFilter.equals(HIERARCHY_LEVELS_SELECTED_SUBMODEL)) { if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_SELECTED_SUBMODEL)) {
// Model element has lower level than currently selected element -> filter // Model element has lower level than currently selected element -> filter
if (modelElementLevel < currentlySelectedModelElementLevel) { if(modelElementLevel < currentlySelectedModelElementLevel) {
return false; return false;
} }
...@@ -141,20 +155,23 @@ public class FXAnnotationFilter { ...@@ -141,20 +155,23 @@ public class FXAnnotationFilter {
// identical // identical
// to the currently selected model element. // to the currently selected model element.
int levelsUp = modelElementLevel - currentlySelectedModelElementLevel; int levelsUp = modelElementLevel - currentlySelectedModelElementLevel;
EObject modelElementAncestor = getModelElementAncestor(annotationEntry.getModelElement(), levelsUp); EObject modelElementAncestor =
getModelElementAncestor(annotationEntry.getModelElement(), levelsUp);
if (currentlySelectedModelElement != modelElementAncestor) { if(currentlySelectedModelElement != modelElementAncestor) {
return false; return false;
} }
} }
Class<? extends IModelElement> modelElementClass = modelElement.getClass(); Class<? extends IModelElement> modelElementClass = modelElement.getClass();
Class<? extends IModelElement> currentlySelectedModelElementClass = currentlySelectedModelElement.getClass(); Class<? extends IModelElement> currentlySelectedModelElementClass =
currentlySelectedModelElement.getClass();
// Pass test if either the model element type is not restricted, or the element // Pass test if either the model element type is not restricted, or the element
// has the same // has the same
// type as the selected one // type as the selected one
return !restrictToSelectedModelElementType || modelElementClass.equals(currentlySelectedModelElementClass); return !restrictToSelectedModelElementType ||
modelElementClass.equals(currentlySelectedModelElementClass);
} }
/** /**
...@@ -176,7 +193,8 @@ public class FXAnnotationFilter { ...@@ -176,7 +193,8 @@ public class FXAnnotationFilter {
.isHidden(columnHandle.getAnnotatedSpecification().getClass()); .isHidden(columnHandle.getAnnotatedSpecification().getClass());
// Pass name filter, if: name is not filtered, or the condition is met // Pass name filter, if: name is not filtered, or the condition is met
boolean passesNameFilter = !filterColumnName || passesNameFilter(columnHandle.getColumnName()); boolean passesNameFilter =
!filterColumnName || passesNameFilter(columnHandle.getColumnName());
// Check if column passes all tests // Check if column passes all tests
// @CodeFormatterOff // @CodeFormatterOff
...@@ -195,21 +213,21 @@ public class FXAnnotationFilter { ...@@ -195,21 +213,21 @@ public class FXAnnotationFilter {
// Pass name filter, if: name is not filtered, element is not a INamedElement, // Pass name filter, if: name is not filtered, element is not a INamedElement,
// or it // or it
// actually passes the filter // actually passes the filter
boolean passesNameFilter = !filterRowName || !(modelElement instanceof INamedElement) boolean passesNameFilter = !filterRowName || !(modelElement instanceof INamedElement) ||
|| passesNameFilter(((INamedElement) modelElement).getName()); passesNameFilter(((INamedElement)modelElement).getName());
return passesNameFilter && passesSelectedElementTypeFilter(annotationEntry); return passesNameFilter && passesSelectedElementTypeFilter(annotationEntry);
} }
/** Sets the model element / annotation name filter pattern. */ /** Sets the model element / annotation name filter pattern. */
public void setNameFilterPattern(String filterPatternString) { private void setNameFilterPattern(String filterPatternString) {
if (filterPatternString.equals(FILTER_HINT_TEXT)) { if(filterPatternString.equals(FILTER_HINT_TEXT)) {
filterPattern = null; filterPattern = null;
} else { } else {
try { try {
final int patternFlags = (filterNameMatchCase ? 0 : CASE_INSENSITIVE) | DOTALL; final int patternFlags = (filterNameMatchCase ? 0 : CASE_INSENSITIVE) | DOTALL;
filterPattern = Pattern.compile(".*" + filterPatternString + ".*", patternFlags); filterPattern = Pattern.compile(".*" + filterPatternString + ".*", patternFlags);
} catch (PatternSyntaxException e) { } catch(PatternSyntaxException e) {
filterPattern = null; filterPattern = null;
} }
} }
...@@ -229,7 +247,7 @@ public class FXAnnotationFilter { ...@@ -229,7 +247,7 @@ public class FXAnnotationFilter {
public void setFilterNameMatchCase(boolean filterNameMatchCase) { public void setFilterNameMatchCase(boolean filterNameMatchCase) {
this.filterNameMatchCase = filterNameMatchCase; this.filterNameMatchCase = filterNameMatchCase;
// Recompile pattern // Recompile pattern
if (filterPattern != null) { if(filterPattern != null) {
setNameFilterPattern(filterPattern.pattern()); setNameFilterPattern(filterPattern.pattern());
} }
} }
...@@ -248,7 +266,8 @@ public class FXAnnotationFilter { ...@@ -248,7 +266,8 @@ public class FXAnnotationFilter {
} }
/** Sets the annotation type filter option. */ /** Sets the annotation type filter option. */
public void setAnnotationTypeFilter(Class<? extends IAnnotatedSpecification> annotationTypeFilter) { public void
setAnnotationTypeFilter(Class<? extends IAnnotatedSpecification> annotationTypeFilter) {
this.annotationTypeFilter = annotationTypeFilter; this.annotationTypeFilter = annotationTypeFilter;
} }
...@@ -256,4 +275,34 @@ public class FXAnnotationFilter { ...@@ -256,4 +275,34 @@ public class FXAnnotationFilter {
public void setCurrentySelectedModelElement(IModelElement currentySelectedModelElement) { public void setCurrentySelectedModelElement(IModelElement currentySelectedModelElement) {
this.currentlySelectedModelElement = currentySelectedModelElement; this.currentlySelectedModelElement = currentySelectedModelElement;
} }
/** {@inheritDoc} */
@Override
protected Collection<? extends AnnotationEntry> getChildren(AnnotationEntry parent) {
if(parent instanceof ArtificialRoot) {
return ((ArtificialRoot)parent).elements;
}
return emptyList();
}
/** {@inheritDoc} */
@Override
protected boolean filter(AnnotationEntry entry, String filterValue) {
return passesRowFilter(entry);
}
/** {@inheritDoc} */
@Override
public void setFilterExpression(String filterExpression) {
// An empty expression would permit the content provider from calling the filter
// method. Hence it an empty expression is replaced by "*".
if(filterExpression == null || filterExpression.isEmpty()) {
setNameFilterPattern("*");
super.setFilterExpression("*");
} else {
setNameFilterPattern(filterExpression);
super.setFilterExpression(filterExpression);
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment