From ff3810df09edbec09b74bd323706193f558ca39e Mon Sep 17 00:00:00 2001 From: jmillman Date: Fri, 15 Apr 2016 16:40:25 -0400 Subject: [PATCH] comments and minor cleanup --- .../timeline/filters/CompoundFilter.java | 35 ++++++---------- .../timeline/filters/DataSourcesFilter.java | 10 ++--- .../timeline/filters/HashHitsFilter.java | 5 +-- .../autopsy/timeline/filters/TagsFilter.java | 5 +-- .../autopsy/timeline/filters/TypeFilter.java | 6 +-- .../timeline/ui/filtering/FilterSetPanel.java | 5 +++ .../timeline/ui/filtering/FilterTreeItem.java | 42 +++++++++++-------- 7 files changed, 53 insertions(+), 55 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java index 51fa6decb6..285e2186d6 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.List; import java.util.Objects; -import javafx.beans.Observable; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; @@ -31,12 +30,8 @@ import javafx.collections.ObservableList; * implementations can decide how to combine the sub-filters. * * a {@link CompoundFilter} uses listeners to enforce the following - * relationships between it and its sub-filters: - *
    - * if a compound filter becomes inactive disable all of its sub-filters - * if all of a compound filter's sub-filters become un-selected, un-select - * the compound filter. - *
+ * relationships between it and its sub-filters: if all of a compound filter's + * sub-filters become un-selected, un-select the compound filter. */ public abstract class CompoundFilter extends AbstractFilter { @@ -57,27 +52,23 @@ public abstract class CompoundFilter extends Abstr public CompoundFilter(List subFilters) { super(); - //listen to changes in list of subfilters and - this.subFilters.addListener((ListChangeListener.Change c) -> { - while (c.next()) { //add active state listener to newly added filters - addSubFilterListeners(c.getAddedSubList()); + //listen to changes in list of subfilters + this.subFilters.addListener((ListChangeListener.Change change) -> { + while (change.next()) { + //add a listener to the selected property of each added subfilter + change.getAddedSubList().forEach(addedSubFilter -> { + //if a subfilter's selected property changes... + addedSubFilter.selectedProperty().addListener(selectedProperty -> { + //set this compound filter selected af any of the subfilters are selected. + setSelected(getSubFilters().parallelStream().anyMatch(Filter::isSelected)); + }); + }); } - setSelected(getSubFilters().parallelStream().anyMatch(Filter::isSelected)); }); this.subFilters.setAll(subFilters); } - private void addSubFilterListeners(List newSubfilters) { - for (SubFilterType sf : newSubfilters) { - //if a subfilter changes selected state - sf.selectedProperty().addListener((Observable observable) -> { - //set this filter selected af any of the subfilters are selected. - setSelected(getSubFilters().parallelStream().anyMatch(Filter::isSelected)); - }); - } - } - static boolean areSubFiltersEqual(final CompoundFilter oneFilter, final CompoundFilter otherFilter) { if (oneFilter.getSubFilters().size() != otherFilter.getSubFilters().size()) { return false; diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java index c36868a787..3395982ad7 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java @@ -30,21 +30,21 @@ import org.openide.util.NbBundle; */ public class DataSourcesFilter extends UnionFilter { + //keep references to the overridden properties so they don't get GC'd private final BooleanBinding activePropertyOverride; - private BooleanBinding disabledPropertyOverride; + private final BooleanBinding disabledPropertyOverride; public DataSourcesFilter() { disabledPropertyOverride = Bindings.or(super.disabledProperty(), Bindings.size(getSubFilters()).lessThanOrEqualTo(1)); - activePropertyOverride = super.activeProperty().and(Bindings.not(disabledProperty())); + activePropertyOverride = super.activeProperty().and(Bindings.not(disabledPropertyOverride)); } @Override public DataSourcesFilter copyOf() { final DataSourcesFilter filterCopy = new DataSourcesFilter(); //add a copy of each subfilter - getSubFilters().forEach(dataSourceFilter -> - filterCopy.addSubFilter(dataSourceFilter.copyOf()) - ); + getSubFilters().forEach(dataSourceFilter -> filterCopy.addSubFilter(dataSourceFilter.copyOf())); + //these need to happen after the listeners fired by adding the subfilters filterCopy.setSelected(isSelected()); filterCopy.setDisabled(isDisabled()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java index 13284683cc..ba2791ac1e 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java @@ -43,9 +43,8 @@ public class HashHitsFilter extends UnionFilter { public HashHitsFilter copyOf() { HashHitsFilter filterCopy = new HashHitsFilter(); //add a copy of each subfilter - this.getSubFilters().forEach(hashSetFilter -> - filterCopy.addSubFilter(hashSetFilter.copyOf()) - ); + this.getSubFilters().forEach(hashSetFilter -> filterCopy.addSubFilter(hashSetFilter.copyOf())); + //these need to happen after the listeners fired by adding the subfilters filterCopy.setSelected(isSelected()); filterCopy.setDisabled(isDisabled()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java index 52c0b3b559..7d23c49916 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java @@ -45,9 +45,8 @@ public class TagsFilter extends UnionFilter { public TagsFilter copyOf() { TagsFilter filterCopy = new TagsFilter(); //add a copy of each subfilter - getSubFilters().forEach(tagNameFilter -> - filterCopy.addSubFilter(tagNameFilter.copyOf()) - ); + getSubFilters().forEach(tagNameFilter -> filterCopy.addSubFilter(tagNameFilter.copyOf())); + //these need to happen after the listeners fired by adding the subfilters filterCopy.setSelected(isSelected()); filterCopy.setDisabled(isDisabled()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/TypeFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/TypeFilter.java index 9af52e99fb..b897791985 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/TypeFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/TypeFilter.java @@ -102,10 +102,8 @@ public class TypeFilter extends UnionFilter { //make a nonrecursive copy of this filter final TypeFilter filterCopy = new TypeFilter(eventType, false); //add a copy of each subfilter - getSubFilters().forEach(typeFilter -> - filterCopy.addSubFilter(typeFilter.copyOf(), comparator) - ); - + getSubFilters().forEach(typeFilter -> filterCopy.addSubFilter(typeFilter.copyOf(), comparator)); + //these need to happen after the listeners fired by adding the subfilters filterCopy.setSelected(isSelected()); filterCopy.setDisabled(isDisabled()); return filterCopy; diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterSetPanel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterSetPanel.java index 53dceb8a6f..8512c3f819 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterSetPanel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterSetPanel.java @@ -84,6 +84,10 @@ final public class FilterSetPanel extends BorderPane { private final FilteredEventsModel filteredEvents; private final TimeLineController controller; + /** + * map from filter to its expansion state in the ui, used to restore the + * expansion state as we navigate back and forward in the history + */ private final ObservableMap expansionMap = FXCollections.observableHashMap(); private double dividerPosition; @@ -112,6 +116,7 @@ final public class FilterSetPanel extends BorderPane { legendColumn.setCellValueFactory(cellDataFeatures -> cellDataFeatures.getValue().valueProperty()); legendColumn.setCellFactory(col -> new LegendCell(this.controller)); + //type is the only filter expanded initialy expansionMap.put(controller.getEventsModel().getFilter().getTypeFilter(), true); this.filteredEvents.eventTypeZoomProperty().addListener((Observable observable) -> applyFilters()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterTreeItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterTreeItem.java index ba06bfd404..59368eeab6 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterTreeItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterTreeItem.java @@ -31,50 +31,56 @@ import org.sleuthkit.autopsy.timeline.filters.Filter; final public class FilterTreeItem extends TreeItem { /** - * recursively construct a tree of treeitems to parallel the filter tree of + * recursively construct a tree of TreeItems to parallel the filter tree of * the given filter * * - * @param f the filter for this item. if f has sub-filters, tree items will - * be made for them added added to the children of this - * FilterTreeItem + * @param filter the filter for this item. if f has sub-filters, tree items + * will be made for them added added to the children of this + * FilterTreeItem */ - public FilterTreeItem(Filter f, ObservableMap expansionMap) { - super(f); + public FilterTreeItem(Filter filter, ObservableMap expansionMap) { + super(filter); + //listen to changes in the expansion map, and update expansion state of filter object expansionMap.addListener((MapChangeListener.Change change) -> { - if (change.getKey().equals(f)) { + if (change.getKey().equals(filter)) { setExpanded(expansionMap.get(change.getKey())); } }); - if (expansionMap.containsKey(f)) { - setExpanded(expansionMap.get(f)); + if (expansionMap.containsKey(filter)) { + setExpanded(expansionMap.get(filter)); } - expandedProperty().addListener(expandedProperty -> expansionMap.put(f, isExpanded())); + //keep expanion map upto date if user expands/collapses filter + expandedProperty().addListener(expandedProperty -> expansionMap.put(filter, isExpanded())); - if (f instanceof CompoundFilter) { - final CompoundFilter compoundFilter = (CompoundFilter) f; + //if the filter is a compound filter, add its subfilters to the tree + if (filter instanceof CompoundFilter) { + final CompoundFilter compoundFilter = (CompoundFilter) filter; - for (Filter subFilter : compoundFilter.getSubFilters()) { - getChildren().add(new FilterTreeItem(subFilter, expansionMap)); - } + //add all sub filters + compoundFilter.getSubFilters().forEach(subFilter -> getChildren().add(new FilterTreeItem(subFilter, expansionMap))); + //listen to changes in sub filters and keep tree in sync compoundFilter.getSubFilters().addListener((ListChangeListener.Change c) -> { while (c.next()) { for (Filter subfFilter : c.getAddedSubList()) { - setExpanded(true); + setExpanded(true); //emphasize new filters by expanding parent to make sure they are visible getChildren().add(new FilterTreeItem(subfFilter, expansionMap)); } } }); + /* + * enforce the following relationship between a compound filter and + * its subfilters: if a compound filter's active property changes, + * disable the subfilters if the compound filter is not active. + */ compoundFilter.activeProperty().addListener(activeProperty -> { compoundFilter.getSubFilters().forEach(subFilter -> subFilter.setDisabled(compoundFilter.isActive() == false)); }); - } - } }