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 @@
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.control.TreeTableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
......@@ -27,12 +26,8 @@
<HBox prefHeight="40.0" prefWidth="148.0" spacing="5.0">
<children>
<Label minHeight="20.0" text="Filter:" />
<RadioButton fx:id="radBtnFilterModelElements" minHeight="20.0" mnemonicParsing="false" text="model elements">
<toggleGroup>
<ToggleGroup fx:id="filterGroup" />
</toggleGroup>
</RadioButton>
<RadioButton fx:id="radBtnFilterAnnotationNames" minHeight="20.0" mnemonicParsing="false" text="annotation names:" toggleGroup="$filterGroup" />
<RadioButton fx:id="radBtnFilterModelElements" minHeight="20.0" mnemonicParsing="false" text="model elements" />
<RadioButton fx:id="radBtnFilterAnnotationNames" minHeight="20.0" mnemonicParsing="false" text="annotation names:" />
<CheckBox fx:id="chkBoxMatchCase" mnemonicParsing="false" text="match case" />
</children>
</HBox>
......
AnnotationFxViewPart.java 34c845f7162a8a8bb680df6ee08160ce63a5a5a3 YELLOW
AnnotationViewFXController.java 50e745f4f700b165c3d138d9f9cd2463252da31d RED
FXAnnotationFilter.java 05bc78a530becbce573545d67e5b0ef9ac3f697f YELLOW
AnnotationViewFXController.java 00c64dbad1bd9ae071360ebe3d071705c8d2a68c YELLOW
FXAnnotationFilterContentProvider.java 6c92d9c96fb2a2441256f70e20a20b1287018a9f YELLOW
......@@ -15,11 +15,13 @@
+--------------------------------------------------------------------------*/
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.DOTALL;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getModelElementAncestor;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getModelElementLevel;
import java.util.Collection;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
......@@ -27,21 +29,25 @@ import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
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.common.ui.javafx.control.treetableview.DynamicTreeContentProviderBase;
import org.fortiss.tooling.kernel.model.INamedElement;
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>
* {@link FXAnnotationFilter#passesColumnFilter(ColumnHandle)} that is evaluated
* during the update of the {@link AnnotationViewFXController}.</li>
* {@link FXAnnotationFilterContentProvider#passesColumnFilter(ColumnHandle)}
* that is evaluated during the update of the
* {@link AnnotationViewFXController}.</li>
* </ul>
*
* @author barner
* @author bayha
*/
public class FXAnnotationFilter {
public class FXAnnotationFilterContentProvider
extends DynamicTreeContentProviderBase<AnnotationEntry> {
/** Filter hint text. */
static final String FILTER_HINT_TEXT = "type filter text (regex)";
......@@ -83,6 +89,13 @@ public class FXAnnotationFilter {
/** Column filter option based on annotation type. */
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
* filter specified by {@code filterString}.
......@@ -91,12 +104,12 @@ public class FXAnnotationFilter {
// Null-filter accepts every input. This covers also the case when the pattern
// provided by
// the user is invalid.
if (filterPattern == null) {
if(filterPattern == null) {
return true;
}
// Null-input cannot be accepted by a non-null filter
if (input == null) {
if(input == null) {
return false;
}
......@@ -108,30 +121,31 @@ public class FXAnnotationFilter {
* model element (or if this particular filter option is turned off).
*/
private boolean passesSelectedElementTypeFilter(AnnotationEntry annotationEntry) {
boolean selectedElementIsInvalid = currentlySelectedModelElement == null
|| currentlySelectedModelElement instanceof IProjectRootElement;
boolean selectedElementIsInvalid = currentlySelectedModelElement == null ||
currentlySelectedModelElement instanceof IProjectRootElement;
if (selectedElementIsInvalid || hierarchyLevelFilter == null) {
if(selectedElementIsInvalid || hierarchyLevelFilter == null) {
return true;
}
IModelElement modelElement = annotationEntry.getModelElement();
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
if (modelElementLevel != currentlySelectedModelElementLevel) {
if(modelElementLevel != currentlySelectedModelElementLevel) {
return false;
}
if (currentlySelectedModelElement.eContainer() != modelElement.eContainer()) {
if(currentlySelectedModelElement.eContainer() != modelElement.eContainer()) {
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
if (modelElementLevel < currentlySelectedModelElementLevel) {
if(modelElementLevel < currentlySelectedModelElementLevel) {
return false;
}
......@@ -141,20 +155,23 @@ public class FXAnnotationFilter {
// identical
// to the currently selected model element.
int levelsUp = modelElementLevel - currentlySelectedModelElementLevel;
EObject modelElementAncestor = getModelElementAncestor(annotationEntry.getModelElement(), levelsUp);
EObject modelElementAncestor =
getModelElementAncestor(annotationEntry.getModelElement(), levelsUp);
if (currentlySelectedModelElement != modelElementAncestor) {
if(currentlySelectedModelElement != modelElementAncestor) {
return false;
}
}
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
// has the same
// type as the selected one
return !restrictToSelectedModelElementType || modelElementClass.equals(currentlySelectedModelElementClass);
return !restrictToSelectedModelElementType ||
modelElementClass.equals(currentlySelectedModelElementClass);
}
/**
......@@ -176,7 +193,8 @@ public class FXAnnotationFilter {
.isHidden(columnHandle.getAnnotatedSpecification().getClass());
// 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
// @CodeFormatterOff
......@@ -195,21 +213,21 @@ public class FXAnnotationFilter {
// Pass name filter, if: name is not filtered, element is not a INamedElement,
// or it
// actually passes the filter
boolean passesNameFilter = !filterRowName || !(modelElement instanceof INamedElement)
|| passesNameFilter(((INamedElement) modelElement).getName());
boolean passesNameFilter = !filterRowName || !(modelElement instanceof INamedElement) ||
passesNameFilter(((INamedElement)modelElement).getName());
return passesNameFilter && passesSelectedElementTypeFilter(annotationEntry);
}
/** Sets the model element / annotation name filter pattern. */
public void setNameFilterPattern(String filterPatternString) {
if (filterPatternString.equals(FILTER_HINT_TEXT)) {
private void setNameFilterPattern(String filterPatternString) {
if(filterPatternString.equals(FILTER_HINT_TEXT)) {
filterPattern = null;
} else {
try {
final int patternFlags = (filterNameMatchCase ? 0 : CASE_INSENSITIVE) | DOTALL;
filterPattern = Pattern.compile(".*" + filterPatternString + ".*", patternFlags);
} catch (PatternSyntaxException e) {
} catch(PatternSyntaxException e) {
filterPattern = null;
}
}
......@@ -229,7 +247,7 @@ public class FXAnnotationFilter {
public void setFilterNameMatchCase(boolean filterNameMatchCase) {
this.filterNameMatchCase = filterNameMatchCase;
// Recompile pattern
if (filterPattern != null) {
if(filterPattern != null) {
setNameFilterPattern(filterPattern.pattern());
}
}
......@@ -248,7 +266,8 @@ public class FXAnnotationFilter {
}
/** Sets the annotation type filter option. */
public void setAnnotationTypeFilter(Class<? extends IAnnotatedSpecification> annotationTypeFilter) {
public void
setAnnotationTypeFilter(Class<? extends IAnnotatedSpecification> annotationTypeFilter) {
this.annotationTypeFilter = annotationTypeFilter;
}
......@@ -256,4 +275,34 @@ public class FXAnnotationFilter {
public void setCurrentySelectedModelElement(IModelElement 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