mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
do all quickhiding in memory, refector some filter stuff
This commit is contained in:
parent
8aa67c830e
commit
db03049385
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* *************************************************************************
|
||||
** This data and information is proprietary to, and a valuable trade secret *
|
||||
* of, Basis Technology Corp. It is given in confidence by Basis Technology *
|
||||
* and may only be used as permitted under the license agreement under which *
|
||||
* it has been distributed, and in no other way. * * Copyright (c) 2014 Basis
|
||||
* Technology Corp. All rights reserved. * * The technical data and information
|
||||
* provided herein are provided with * `limited rights', and the computer
|
||||
* software provided herein is provided * with `restricted rights' as those
|
||||
* terms are defined in DAR and ASPR * 7-104.9(a).
|
||||
* *************************************************************************
|
||||
*/
|
||||
package org.sleuthkit.autopsy.coreutils;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import javafx.scene.control.IndexedCell;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TreeTableCell;
|
||||
import javafx.scene.control.TreeTableColumn;
|
||||
|
||||
/**
|
||||
* an abstract base class for Cell factories. This class provides the basic
|
||||
* infrustructure for implementations to be able to create similar cells for
|
||||
* listview, tableviews or treetableviews via the appropriate method call.
|
||||
* Implementations need only implement the abstract configureCell method in the
|
||||
* same spirit as IndexedCell.updateItem
|
||||
*/
|
||||
public abstract class AbstractFXCellFactory<X, Y> {
|
||||
|
||||
public TreeTableCell< X, Y> forTreeTable(TreeTableColumn< X, Y> column) {
|
||||
return new AbstractTreeTableCell();
|
||||
}
|
||||
|
||||
public TableCell<X, Y> forTable(TableColumn<X, Y> column) {
|
||||
return new AbstractTableCell();
|
||||
}
|
||||
|
||||
public ListCell< Y> forList() {
|
||||
return new AbstractListCell();
|
||||
}
|
||||
|
||||
protected abstract void configureCell(IndexedCell<? extends Y> cell, Y item, boolean empty, Supplier<X> supplier);
|
||||
|
||||
private class AbstractTableCell extends TableCell<X, Y> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"}) //we know it will be X but there is a flaw in getTableRow return type
|
||||
protected void updateItem(Y item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
configureCell(this, item, empty, (() -> (X) this.getTableRow().getItem()));
|
||||
}
|
||||
}
|
||||
|
||||
private class AbstractTreeTableCell extends TreeTableCell<X, Y> {
|
||||
|
||||
@Override
|
||||
protected void updateItem(Y item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
configureCell(this, item, empty, (() -> this.getTreeTableRow().getItem()));
|
||||
}
|
||||
}
|
||||
|
||||
private class AbstractListCell extends ListCell< Y> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") //for a list X should always equal Y
|
||||
protected void updateItem(Y item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
configureCell(this, item, empty, () -> (X) this.getItem());
|
||||
}
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ public abstract class AbstractFilter implements Filter {
|
||||
private final SimpleBooleanProperty disabled = new SimpleBooleanProperty(false);
|
||||
|
||||
@Override
|
||||
public SimpleBooleanProperty getSelectedProperty() {
|
||||
public SimpleBooleanProperty selectedProperty() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ public abstract class AbstractFilter implements Filter {
|
||||
return "[" + (isSelected() ? "x" : " ") + "]"; // NON-NLS
|
||||
}
|
||||
|
||||
final boolean isActive() {
|
||||
public final boolean isActive() {
|
||||
return isSelected() && (isDisabled() == false);
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public abstract class CompoundFilter<SubFilterType extends Filter> extends Abstr
|
||||
private void addSubFilterListeners(List<? extends SubFilterType> newSubfilters) {
|
||||
for (SubFilterType sf : newSubfilters) {
|
||||
//if a subfilter changes active state
|
||||
sf.getSelectedProperty().addListener((Observable observable) -> {
|
||||
sf.selectedProperty().addListener((Observable observable) -> {
|
||||
//set this filter acttive af any of the subfilters are active.
|
||||
setSelected(getSubFilters().parallelStream().anyMatch(Filter::isSelected));
|
||||
});
|
||||
|
@ -66,7 +66,7 @@ public interface Filter {
|
||||
|
||||
void setSelected(Boolean act);
|
||||
|
||||
SimpleBooleanProperty getSelectedProperty();
|
||||
SimpleBooleanProperty selectedProperty();
|
||||
|
||||
/*
|
||||
* TODO: disabled state only affects the state of the checkboxes in the ui
|
||||
|
@ -33,7 +33,7 @@ public class HideKnownFilter extends AbstractFilter {
|
||||
|
||||
public HideKnownFilter() {
|
||||
super();
|
||||
getSelectedProperty().set(false);
|
||||
selectedProperty().set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,6 +79,7 @@ import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
||||
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
||||
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLOD;
|
||||
@ -325,6 +326,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
public synchronized void setController(TimeLineController controller) {
|
||||
this.controller = controller;
|
||||
setModel(this.controller.getEventsModel());
|
||||
getController().getQuickHideMasks().addListener(layoutInvalidationListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -477,6 +479,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
for (Series<DateTime, EventCluster> series : sortedSeriesList) {
|
||||
hiddenPartition = series.getData().stream().map(Data::getNode).map(EventStripeNode.class::cast)
|
||||
.collect(Collectors.partitioningBy(node -> getController().getQuickHideMasks().stream()
|
||||
.filter(AbstractFilter::isActive)
|
||||
.anyMatch(mask -> mask.getDescription().equals(node.getDescription()))));
|
||||
|
||||
layoutNodesHelper(hiddenPartition.get(true), hiddenPartition.get(false), minY, 0);
|
||||
@ -485,6 +488,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
} else {
|
||||
hiddenPartition = stripeNodeMap.values().stream()
|
||||
.collect(Collectors.partitioningBy(node -> getController().getQuickHideMasks().stream()
|
||||
.filter(AbstractFilter::isActive)
|
||||
.anyMatch(mask -> mask.getDescription().equals(node.getDescription()))));
|
||||
layoutNodesHelper(hiddenPartition.get(true), hiddenPartition.get(false), 0, 0);
|
||||
}
|
||||
@ -779,20 +783,15 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
|
||||
class HideDescriptionAction extends Action {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param description the value of description
|
||||
*/
|
||||
HideDescriptionAction(String description, DescriptionLOD descriptionLoD) {
|
||||
super("Hide");
|
||||
setGraphic(new ImageView(HIDE));
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
getController().getQuickHideMasks().add(
|
||||
new DescriptionFilter(descriptionLoD,
|
||||
description,
|
||||
DescriptionFilter.FilterMode.EXCLUDE));
|
||||
setRequiresLayout(true);
|
||||
requestChartLayout();
|
||||
DescriptionFilter descriptionFilter = new DescriptionFilter(descriptionLoD,
|
||||
description,
|
||||
DescriptionFilter.FilterMode.EXCLUDE);
|
||||
descriptionFilter.selectedProperty().addListener(layoutInvalidationListener);
|
||||
getController().getQuickHideMasks().add(descriptionFilter);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -807,8 +806,6 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
getController().getQuickHideMasks().removeIf(descriptionFilter ->
|
||||
descriptionFilter.getDescriptionLoD().equals(descriptionLoD)
|
||||
&& descriptionFilter.getDescription().equals(description));
|
||||
setRequiresLayout(true);
|
||||
requestChartLayout();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2015 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.ui.filtering;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.TreeTableCell;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
||||
|
||||
/**
|
||||
* A {@link TreeTableCell} that represents the active state of a
|
||||
* {@link AbstractFilter} as a checkbox
|
||||
*/
|
||||
class FilterCheckBoxCell extends TreeTableCell<AbstractFilter, AbstractFilter> {
|
||||
|
||||
private final CheckBox checkBox = new CheckBox();
|
||||
private SimpleBooleanProperty activeProperty;
|
||||
private final TimeLineController controller;
|
||||
|
||||
FilterCheckBoxCell(TimeLineController controller) {
|
||||
this.controller = controller;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(AbstractFilter item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
Platform.runLater(() -> {
|
||||
if (activeProperty != null) {
|
||||
checkBox.selectedProperty().unbindBidirectional(activeProperty);
|
||||
}
|
||||
checkBox.disableProperty().unbind();
|
||||
if (item == null) {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
setText(item.getDisplayName());
|
||||
activeProperty = item.getSelectedProperty();
|
||||
checkBox.selectedProperty().bindBidirectional(activeProperty);
|
||||
checkBox.disableProperty().bind(item.getDisabledProperty());
|
||||
setGraphic(checkBox);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.ui.filtering;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.IndexedCell;
|
||||
import org.sleuthkit.autopsy.coreutils.AbstractFXCellFactory;
|
||||
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
||||
|
||||
class FilterCheckBoxCellFactory<X extends AbstractFilter> extends AbstractFXCellFactory<X, X> {
|
||||
|
||||
private final CheckBox checkBox = new CheckBox();
|
||||
private SimpleBooleanProperty selectedProperty;
|
||||
private SimpleBooleanProperty disabledProperty;
|
||||
|
||||
@Override
|
||||
protected void configureCell(IndexedCell<? extends X> cell, X item, boolean empty, Supplier<X> supplier) {
|
||||
if (selectedProperty != null) {
|
||||
checkBox.selectedProperty().unbindBidirectional(selectedProperty);
|
||||
}
|
||||
if (disabledProperty != null) {
|
||||
checkBox.disableProperty().unbindBidirectional(disabledProperty);
|
||||
}
|
||||
if (item == null) {
|
||||
cell.setText(null);
|
||||
cell.setGraphic(null);
|
||||
} else {
|
||||
cell.setText(item.getDisplayName());
|
||||
selectedProperty = item.selectedProperty();
|
||||
checkBox.selectedProperty().bindBidirectional(selectedProperty);
|
||||
disabledProperty = item.getDisabledProperty();
|
||||
checkBox.disableProperty().bindBidirectional(disabledProperty);
|
||||
cell.setGraphic(checkBox);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -156,7 +156,7 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
//configure tree column to show name of filter and checkbox
|
||||
treeColumn.setCellValueFactory(param -> param.getValue().valueProperty());
|
||||
treeColumn.setCellFactory(col -> new FilterCheckBoxCell(controller));
|
||||
treeColumn.setCellFactory(col -> new FilterCheckBoxCellFactory().forTreeTable(col));
|
||||
|
||||
//configure legend column to show legend (or othe supplamantal ui, eg, text field for text filter)
|
||||
legendColumn.setCellValueFactory(param -> param.getValue().valueProperty());
|
||||
@ -194,18 +194,18 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
this.setModel(timeLineController.getEventsModel());
|
||||
|
||||
hiddenDescriptionsListView.setItems(controller.getQuickHideMasks());
|
||||
hiddenDescriptionsListView.setCellFactory((ListView<DescriptionFilter> param) -> new ListCellImpl());
|
||||
hiddenDescriptionsListView.setCellFactory((ListView<DescriptionFilter> param) -> {
|
||||
final ListCell<DescriptionFilter> forList = new FilterCheckBoxCellFactory<DescriptionFilter>().forList();
|
||||
forList.setContextMenu(new ContextMenu(new MenuItem("unhide and remove from list") {
|
||||
{
|
||||
setOnAction((ActionEvent event) -> {
|
||||
controller.getQuickHideMasks().remove(forList.getItem());
|
||||
});
|
||||
}
|
||||
}));
|
||||
return forList;
|
||||
});
|
||||
|
||||
// .addListener((ListChangeListener.Change<? extends DescriptionFilter> c) -> {
|
||||
// while (c.next()) {
|
||||
// DescriptionsExclusionFilter descriptionExclusionFilter = ((RootFilter) filterTreeTable.getRoot().getValue()).getDescriptionsExclusionfilter();
|
||||
//
|
||||
// for (DescriptionFilter filter : c.getAddedSubList()) {
|
||||
// descriptionExclusionFilter.setSelected(true);
|
||||
// descriptionExclusionFilter.addSubFilter(filter);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
controller.viewModeProperty().addListener(observable -> {
|
||||
applyFilters();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user