Merge pull request #4124 from millmanorama/select-subfilters

select subfilters automatically when base filter is selected and no s…
This commit is contained in:
Brian Carrier 2018-09-20 10:35:42 -04:00 committed by GitHub
commit 290411d1d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 23 deletions

View File

@ -18,6 +18,8 @@
*/ */
package org.sleuthkit.autopsy.timeline.ui.filtering; package org.sleuthkit.autopsy.timeline.ui.filtering;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.ObservableMap; import javafx.collections.ObservableMap;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
@ -71,6 +73,15 @@ final public class FilterTreeItem extends TreeItem<FilterState<?>> {
} }
} }
}); });
compoundFilter.selectedProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
if (compoundFilter.isSelected()) {
setExpanded(true);
}
}
});
} }
} }
} }

View File

@ -33,28 +33,41 @@ class CompoundFilterStateImpl<SubFilterType extends TimelineFilter, C extends Co
private final ObservableList<FilterState<SubFilterType>> subFilterStates = FXCollections.observableArrayList(); private final ObservableList<FilterState<SubFilterType>> subFilterStates = FXCollections.observableArrayList();
CompoundFilterStateImpl(C delegate) { /**
super(delegate); * A constructor that automatically makes sub FilterStates for all the
* subfilters of the given compound filter.
delegate.getSubFilters().forEach(this::addSubFilterState); *
delegate.getSubFilters().addListener((ListChangeListener.Change<? extends SubFilterType> change) -> { * @param filter The CompoundFilter this will represent the state of.
*/
CompoundFilterStateImpl(C filter) {
super(filter);
filter.getSubFilters().forEach(this::addSubFilterState);
filter.getSubFilters().addListener((ListChangeListener.Change<? extends SubFilterType> change) -> {
while (change.next()) { while (change.next()) {
change.getAddedSubList().forEach(CompoundFilterStateImpl.this::addSubFilterState); change.getAddedSubList().forEach(CompoundFilterStateImpl.this::addSubFilterState);
} }
}); });
/*
* enforce the following relationship between a compound filter and its configureListeners();
* subfilters: if a compound filter's active property changes, disable
* the subfilters if the compound filter is not active.
*/
activeProperty().addListener(activeProperty -> disableSubFiltersIfNotActive());
disableSubFiltersIfNotActive();
} }
CompoundFilterStateImpl(C delegate, Collection<FilterState<SubFilterType>> subFilterStates) { /**
super(delegate); * A constructor that doesn't make subfilter states automatically, but
* instead uses the given collection of sub filter states. Designed
* primarily for use when making a copy of an existing filterstate tree.
*
* @param filter The CompoundFilter this will represent the state
* of.
* @param subFilterStates The filter states to use as the sub filter states.
*/
CompoundFilterStateImpl(C filter, Collection<FilterState<SubFilterType>> subFilterStates) {
super(filter);
subFilterStates.forEach(this::addSubFilterState); subFilterStates.forEach(this::addSubFilterState);
configureListeners();
}
private void configureListeners() {
/* /*
* enforce the following relationship between a compound filter and its * enforce the following relationship between a compound filter and its
* subfilters: if a compound filter's active property changes, disable * subfilters: if a compound filter's active property changes, disable
@ -62,6 +75,12 @@ class CompoundFilterStateImpl<SubFilterType extends TimelineFilter, C extends Co
*/ */
activeProperty().addListener(activeProperty -> disableSubFiltersIfNotActive()); activeProperty().addListener(activeProperty -> disableSubFiltersIfNotActive());
disableSubFiltersIfNotActive(); disableSubFiltersIfNotActive();
selectedProperty().addListener(selectedProperty -> {
if (isSelected() && getSubFilterStates().stream().noneMatch(FilterState::isSelected)) {
getSubFilterStates().forEach(subFilterState -> subFilterState.setSelected(true));
}
});
} }
/** /**

View File

@ -32,10 +32,10 @@ import org.sleuthkit.datamodel.timeline.TimelineFilter;
*/ */
public class DefaultFilterState<FilterType extends TimelineFilter> implements FilterState<FilterType> { public class DefaultFilterState<FilterType extends TimelineFilter> implements FilterState<FilterType> {
private final FilterType delegate; private final FilterType filter;
public DefaultFilterState(FilterType delegate) { public DefaultFilterState(FilterType filter) {
this.delegate = delegate; this.filter = filter;
} }
private final SimpleBooleanProperty selected = new SimpleBooleanProperty(false); private final SimpleBooleanProperty selected = new SimpleBooleanProperty(false);
@ -84,21 +84,21 @@ public class DefaultFilterState<FilterType extends TimelineFilter> implements Fi
@Override @Override
public String getDisplayName() { public String getDisplayName() {
return delegate.getDisplayName(); return filter.getDisplayName();
} }
@Override @Override
public DefaultFilterState<FilterType> copyOf() { public DefaultFilterState<FilterType> copyOf() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
DefaultFilterState<FilterType> copy = new DefaultFilterState<>((FilterType) delegate.copyOf()); DefaultFilterState<FilterType> copy = new DefaultFilterState<>((FilterType) filter.copyOf());
copy.setSelected(isSelected( )); copy.setSelected(isSelected());
copy.setDisabled(isDisabled()); copy.setDisabled(isDisabled());
return copy; return copy;
} }
@Override @Override
public FilterType getFilter() { public FilterType getFilter() {
return delegate; return filter;
} }
@Override @Override