From a6e5adbc733ad0a45800f9b9d64a99462ece82bf Mon Sep 17 00:00:00 2001 From: jmillman Date: Mon, 21 Mar 2016 13:24:47 -0400 Subject: [PATCH 1/3] disable subfilters if parent filter is unselected --- .../autopsy/timeline/filters/AbstractFilter.java | 6 +++--- .../autopsy/timeline/filters/CompoundFilter.java | 4 ++++ .../timeline/filters/DataSourcesFilter.java | 4 ++-- .../autopsy/timeline/filters/Filter.java | 2 +- .../autopsy/timeline/filters/HashHitsFilter.java | 2 +- .../autopsy/timeline/filters/RootFilter.java | 16 +++++++++++++++- .../autopsy/timeline/filters/TagsFilter.java | 2 +- .../ui/filtering/FilterCheckBoxCellFactory.java | 5 ++--- 8 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java index c5871454d8..798f8aeb9c 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java @@ -38,7 +38,7 @@ public abstract class AbstractFilter implements Filter { } @Override - public SimpleBooleanProperty getDisabledProperty() { + public SimpleBooleanProperty disabledProperty() { return disabled; } @@ -67,11 +67,11 @@ public abstract class AbstractFilter implements Filter { return "[" + (isSelected() ? "x" : " ") + "]"; // NON-NLS } - public final boolean isActive() { + public boolean isActive() { return activeProperty.get(); } - public final BooleanBinding activeProperty() { + public BooleanBinding activeProperty() { return activeProperty; } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java index bf4c6a1b07..6f8f656bcf 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java @@ -67,6 +67,10 @@ public abstract class CompoundFilter extends Abstr } }); this.subFilters.setAll(subFilters); + + this.activeProperty().addListener(activeProperty1 -> { + getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false)); + }); } private void addSubFilterListeners(List newSubfilters) { diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java index 06198052af..a1d348b8b8 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java @@ -29,7 +29,7 @@ import org.openide.util.NbBundle; public class DataSourcesFilter extends UnionFilter { public DataSourcesFilter() { - getDisabledProperty().bind(Bindings.size(getSubFilters()).lessThanOrEqualTo(1)); + disabledProperty().bind(Bindings.size(getSubFilters()).lessThanOrEqualTo(1)); setSelected(false); } @@ -69,7 +69,7 @@ public class DataSourcesFilter extends UnionFilter { .map(DataSourceFilter::getDataSourceID) .filter(t -> t == dataSourceFilter.getDataSourceID()) .findAny().isPresent() == false) { - dataSourceFilter.getDisabledProperty().bind(getDisabledProperty()); + dataSourceFilter.disabledProperty().bind(disabledProperty()); getSubFilters().add(dataSourceFilter); getSubFilters().sort(Comparator.comparing(DataSourceFilter::getDisplayName)); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java index dc44c8912b..9ea652355f 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java @@ -77,7 +77,7 @@ public interface Filter { */ void setDisabled(Boolean act); - SimpleBooleanProperty getDisabledProperty(); + SimpleBooleanProperty disabledProperty(); boolean isDisabled(); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java index 838144fadd..18d2b43bc9 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java @@ -22,7 +22,7 @@ public class HashHitsFilter extends UnionFilter { } public HashHitsFilter() { - getDisabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1)); + disabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1)); setSelected(false); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/RootFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/RootFilter.java index 9034810ed7..2b31978d7b 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/RootFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/RootFilter.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Set; import java.util.stream.Collectors; +import javafx.beans.binding.BooleanBinding; import javafx.collections.FXCollections; /** @@ -70,7 +71,7 @@ public class RootFilter extends IntersectionFilter { public RootFilter copyOf() { Set annonymousSubFilters = getSubFilters().stream() .filter(subFilter -> - !(subFilter.equals(knownFilter) + !(subFilter.equals(knownFilter) || subFilter.equals(tagsFilter) || subFilter.equals(hashFilter) || subFilter.equals(typeFilter) @@ -108,4 +109,17 @@ public class RootFilter extends IntersectionFilter { } return areSubFiltersEqual(this, (CompoundFilter) obj); } + + public boolean isActive() { + return true; + } + + public BooleanBinding activeProperty() { + return new BooleanBinding() { + @Override + protected boolean computeValue() { + return true; + } + }; + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java index 6d90482157..f2c0e79152 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java @@ -23,7 +23,7 @@ public class TagsFilter extends UnionFilter { } public TagsFilter() { - getDisabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1)); + disabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1)); setSelected(false); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java index 535289c6aa..2b432b525f 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java @@ -41,13 +41,12 @@ class FilterCheckBoxCellFactory extends AbstractFXCell } if (item == null) { - cell.setText(null); cell.setGraphic(null); } else { - cell.setText(item.getDisplayName()); + checkBox.setText(item.getDisplayName()); selectedProperty = item.selectedProperty(); checkBox.selectedProperty().bindBidirectional(selectedProperty); - disabledProperty = item.getDisabledProperty(); + disabledProperty = item.disabledProperty(); checkBox.disableProperty().bindBidirectional(disabledProperty); cell.setGraphic(checkBox); } From 2a7c0e33ce848f515f1f1f3ecae1fbaa48dd0064 Mon Sep 17 00:00:00 2001 From: jmillman Date: Wed, 23 Mar 2016 16:29:53 -0400 Subject: [PATCH 2/3] stop disabling filters when there is only one possible value because it conflicted with disabling them if no children are selected --- .../sleuthkit/autopsy/timeline/filters/CompoundFilter.java | 5 ++++- .../autopsy/timeline/filters/DataSourcesFilter.java | 3 --- .../sleuthkit/autopsy/timeline/filters/HashHitsFilter.java | 2 -- .../org/sleuthkit/autopsy/timeline/filters/TagsFilter.java | 3 --- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java index 6f8f656bcf..eacb17d642 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java @@ -68,7 +68,10 @@ public abstract class CompoundFilter extends Abstr }); this.subFilters.setAll(subFilters); - this.activeProperty().addListener(activeProperty1 -> { + this.selectedProperty().addListener(activeProperty1 -> { + getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false)); + }); + this.disabledProperty().addListener(activeProperty1 -> { getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false)); }); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java index a1d348b8b8..3b33ddbe0c 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Comparator; import java.util.stream.Collectors; -import javafx.beans.binding.Bindings; import org.openide.util.NbBundle; /** @@ -29,7 +28,6 @@ import org.openide.util.NbBundle; public class DataSourcesFilter extends UnionFilter { public DataSourcesFilter() { - disabledProperty().bind(Bindings.size(getSubFilters()).lessThanOrEqualTo(1)); setSelected(false); } @@ -69,7 +67,6 @@ public class DataSourcesFilter extends UnionFilter { .map(DataSourceFilter::getDataSourceID) .filter(t -> t == dataSourceFilter.getDataSourceID()) .findAny().isPresent() == false) { - dataSourceFilter.disabledProperty().bind(disabledProperty()); getSubFilters().add(dataSourceFilter); getSubFilters().sort(Comparator.comparing(DataSourceFilter::getDisplayName)); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java index 18d2b43bc9..ad2c04baa0 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java @@ -7,7 +7,6 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Comparator; import java.util.stream.Collectors; -import javafx.beans.binding.Bindings; import org.openide.util.NbBundle; /** @@ -22,7 +21,6 @@ public class HashHitsFilter extends UnionFilter { } public HashHitsFilter() { - disabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1)); setSelected(false); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java index f2c0e79152..2e3fec6693 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java @@ -7,7 +7,6 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Comparator; import java.util.stream.Collectors; -import javafx.beans.binding.Bindings; import org.openide.util.NbBundle; import org.sleuthkit.datamodel.TagName; @@ -23,7 +22,6 @@ public class TagsFilter extends UnionFilter { } public TagsFilter() { - disabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1)); setSelected(false); } @@ -89,5 +87,4 @@ public class TagsFilter extends UnionFilter { getSubFilters().sort(Comparator.comparing(TagNameFilter::getDisplayName)); } - } From 2e36dcb0408c8c9644e48e687747242639d4b9e8 Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 24 Mar 2016 13:32:41 -0400 Subject: [PATCH 3/3] support subfilter disabling and [parent filter diabling based on nunber of subfilters. --- .../autopsy/timeline/filters/AbstractFilter.java | 7 ++++--- .../autopsy/timeline/filters/CompoundFilter.java | 4 ++-- .../autopsy/timeline/filters/DataSourcesFilter.java | 8 ++++++++ .../org/sleuthkit/autopsy/timeline/filters/Filter.java | 3 ++- .../autopsy/timeline/filters/HashHitsFilter.java | 7 +++++++ .../sleuthkit/autopsy/timeline/filters/TagsFilter.java | 6 ++++++ .../timeline/ui/filtering/FilterCheckBoxCellFactory.java | 7 ++++--- 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java index 798f8aeb9c..c51b3a82ed 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/AbstractFilter.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.filters; import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.value.ObservableBooleanValue; /** * Base implementation of a {@link Filter}. Implements active property. @@ -38,7 +39,7 @@ public abstract class AbstractFilter implements Filter { } @Override - public SimpleBooleanProperty disabledProperty() { + public ObservableBooleanValue disabledProperty() { return disabled; } @@ -67,11 +68,11 @@ public abstract class AbstractFilter implements Filter { return "[" + (isSelected() ? "x" : " ") + "]"; // NON-NLS } - public boolean isActive() { + public boolean isActive() { return activeProperty.get(); } - public BooleanBinding activeProperty() { + public BooleanBinding activeProperty() { return activeProperty; } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java index eacb17d642..dff26b1e61 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/CompoundFilter.java @@ -68,10 +68,10 @@ public abstract class CompoundFilter extends Abstr }); this.subFilters.setAll(subFilters); - this.selectedProperty().addListener(activeProperty1 -> { + this.selectedProperty().addListener(activeProperty -> { getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false)); }); - this.disabledProperty().addListener(activeProperty1 -> { + this.disabledProperty().addListener(activeProperty -> { getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false)); }); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java index 3b33ddbe0c..02318310f1 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/DataSourcesFilter.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Comparator; import java.util.stream.Collectors; +import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableBooleanValue; import org.openide.util.NbBundle; /** @@ -97,4 +99,10 @@ public class DataSourcesFilter extends UnionFilter { public int hashCode() { return 9; } + + @Override + public ObservableBooleanValue disabledProperty() { + return Bindings.or(super.disabledProperty(), Bindings.size(getSubFilters()).lessThanOrEqualTo(1)); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java index 9ea652355f..435998a183 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/Filter.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.timeline.filters; import javafx.beans.binding.BooleanBinding; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.value.ObservableBooleanValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -77,7 +78,7 @@ public interface Filter { */ void setDisabled(Boolean act); - SimpleBooleanProperty disabledProperty(); + ObservableBooleanValue disabledProperty(); boolean isDisabled(); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java index ad2c04baa0..b7a13184f7 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/HashHitsFilter.java @@ -7,6 +7,8 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Comparator; import java.util.stream.Collectors; +import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableBooleanValue; import org.openide.util.NbBundle; /** @@ -79,4 +81,9 @@ public class HashHitsFilter extends UnionFilter { getSubFilters().sort(Comparator.comparing(HashSetFilter::getDisplayName)); } } + + @Override + public ObservableBooleanValue disabledProperty() { + return Bindings.or(super.disabledProperty(), Bindings.isEmpty(getSubFilters())); + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java index 2e3fec6693..1ab69a3909 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/filters/TagsFilter.java @@ -7,6 +7,8 @@ package org.sleuthkit.autopsy.timeline.filters; import java.util.Comparator; import java.util.stream.Collectors; +import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableBooleanValue; import org.openide.util.NbBundle; import org.sleuthkit.datamodel.TagName; @@ -87,4 +89,8 @@ public class TagsFilter extends UnionFilter { getSubFilters().sort(Comparator.comparing(TagNameFilter::getDisplayName)); } + @Override + public ObservableBooleanValue disabledProperty() { + return Bindings.or(super.disabledProperty(), Bindings.isEmpty(getSubFilters())); + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java index 2b432b525f..689bb47702 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/filtering/FilterCheckBoxCellFactory.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.timeline.ui.filtering; import java.util.function.Supplier; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.value.ObservableBooleanValue; import javafx.scene.control.CheckBox; import javafx.scene.control.IndexedCell; import org.sleuthkit.autopsy.timeline.filters.AbstractFilter; @@ -29,7 +30,7 @@ class FilterCheckBoxCellFactory extends AbstractFXCell private final CheckBox checkBox = new CheckBox(); private SimpleBooleanProperty selectedProperty; - private SimpleBooleanProperty disabledProperty; + private ObservableBooleanValue disabledProperty; @Override protected void configureCell(IndexedCell cell, X item, boolean empty, Supplier supplier) { @@ -37,7 +38,7 @@ class FilterCheckBoxCellFactory extends AbstractFXCell checkBox.selectedProperty().unbindBidirectional(selectedProperty); } if (disabledProperty != null) { - checkBox.disableProperty().unbindBidirectional(disabledProperty); + checkBox.disableProperty().unbind();//disabledProperty); } if (item == null) { @@ -47,7 +48,7 @@ class FilterCheckBoxCellFactory extends AbstractFXCell selectedProperty = item.selectedProperty(); checkBox.selectedProperty().bindBidirectional(selectedProperty); disabledProperty = item.disabledProperty(); - checkBox.disableProperty().bindBidirectional(disabledProperty); + checkBox.disableProperty().bind(disabledProperty); cell.setGraphic(checkBox); } }