mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
quick-hide/filter WIP 3
This commit is contained in:
parent
56358568f0
commit
b290534f07
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.coreutils;
|
||||
|
||||
import java.util.Objects;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||
|
@ -1076,6 +1076,7 @@ public class EventDB {
|
||||
+ "\n GROUP BY interval, " + typeColumn + " , " + descriptionColumn // NON-NLS
|
||||
+ "\n ORDER BY min(time)"; // NON-NLS
|
||||
|
||||
System.out.println(query);
|
||||
// perform query and map results to AggregateEvent objects
|
||||
List<EventCluster> events = new ArrayList<>();
|
||||
|
||||
|
@ -89,6 +89,4 @@ public abstract class CompoundFilter<SubFilterType extends Filter> extends Abstr
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class DescriptionFilter extends AbstractFilter {
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return getFilterMode().getDisplayName() + " Description";
|
||||
return getFilterMode().getDisplayName() + " " + getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -86,10 +86,6 @@ public class DescriptionFilter extends AbstractFilter {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean test(String t) {
|
||||
return (filterMode == FilterMode.INCLUDE) == getDescription().equals(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
|
BIN
Core/src/org/sleuthkit/autopsy/timeline/images/eye--minus.png
Normal file
BIN
Core/src/org/sleuthkit/autopsy/timeline/images/eye--minus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 595 B |
BIN
Core/src/org/sleuthkit/autopsy/timeline/images/eye--plus.png
Normal file
BIN
Core/src/org/sleuthkit/autopsy/timeline/images/eye--plus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 661 B |
@ -304,7 +304,7 @@ public abstract class AbstractVisualization<X, Y, N, C extends XYChart<X, Y> & T
|
||||
//x-positions (pixels) of the current branch and leaf labels
|
||||
double leafLabelX = 0;
|
||||
|
||||
if (dateTime.branch.equals("")) {
|
||||
if (dateTime.branch.isEmpty()) {
|
||||
//if there is only one part to the date (ie only year), just add a label for each tick
|
||||
for (Axis.TickMark<X> t : tickMarks) {
|
||||
assignLeafLabel(new TwoPartDateTime(getTickMarkLabel(t.getValue())).leaf,
|
||||
|
@ -85,7 +85,7 @@ public abstract class AbstractDetailViewNode< T extends EventBundle, S extends A
|
||||
static final Image HASH_PIN = new Image("/org/sleuthkit/autopsy/images/hashset_hits.png");
|
||||
static final Image PLUS = new Image("/org/sleuthkit/autopsy/timeline/images/plus-button.png"); // NON-NLS
|
||||
static final Image MINUS = new Image("/org/sleuthkit/autopsy/timeline/images/minus-button.png"); // NON-NLS
|
||||
static final Image HIDE = new Image("/org/sleuthkit/autopsy/timeline/images/funnel.png"); // NON-NLS
|
||||
|
||||
static final Image TAG = new Image("/org/sleuthkit/autopsy/images/green-tag-icon-16.png"); // NON-NLS
|
||||
static final CornerRadii CORNER_RADII = new CornerRadii(3);
|
||||
/**
|
||||
@ -166,9 +166,9 @@ public abstract class AbstractDetailViewNode< T extends EventBundle, S extends A
|
||||
|
||||
private final Region spacer = new Region();
|
||||
|
||||
private final CollapseClusterAction collapseClusterAction;
|
||||
private final CollapseBundleAction collapseClusterAction;
|
||||
private final ExpandClusterAction expandClusterAction;
|
||||
private final HideClusterAction hideClusterAction;
|
||||
private final EventDetailChart.HideBundleAction hideClusterAction;
|
||||
|
||||
public AbstractDetailViewNode(EventDetailChart chart, T bundle, S parentEventNode) {
|
||||
this.eventBundle = bundle;
|
||||
@ -186,7 +186,7 @@ public abstract class AbstractDetailViewNode< T extends EventBundle, S extends A
|
||||
show(tagIV, false);
|
||||
}
|
||||
|
||||
hideClusterAction = new HideClusterAction();
|
||||
hideClusterAction = chart.new HideBundleAction(getEventBundle());
|
||||
hideButton = ActionUtils.createButton(hideClusterAction, ActionUtils.ActionTextBehavior.HIDE);
|
||||
configureLODButton(hideButton);
|
||||
|
||||
@ -194,7 +194,7 @@ public abstract class AbstractDetailViewNode< T extends EventBundle, S extends A
|
||||
plusButton = ActionUtils.createButton(expandClusterAction, ActionUtils.ActionTextBehavior.HIDE);
|
||||
configureLODButton(plusButton);
|
||||
|
||||
collapseClusterAction = new CollapseClusterAction();
|
||||
collapseClusterAction = new CollapseBundleAction();
|
||||
minusButton = ActionUtils.createButton(collapseClusterAction, ActionUtils.ActionTextBehavior.HIDE);
|
||||
configureLODButton(minusButton);
|
||||
|
||||
@ -545,9 +545,9 @@ public abstract class AbstractDetailViewNode< T extends EventBundle, S extends A
|
||||
}
|
||||
}
|
||||
|
||||
private class CollapseClusterAction extends Action {
|
||||
private class CollapseBundleAction extends Action {
|
||||
|
||||
CollapseClusterAction() {
|
||||
CollapseBundleAction() {
|
||||
super("Collapse");
|
||||
|
||||
setGraphic(new ImageView(MINUS));
|
||||
@ -561,20 +561,4 @@ public abstract class AbstractDetailViewNode< T extends EventBundle, S extends A
|
||||
}
|
||||
}
|
||||
|
||||
private class HideClusterAction extends Action {
|
||||
|
||||
HideClusterAction() {
|
||||
super("Hide");
|
||||
setGraphic(new ImageView(HIDE));
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
DescriptionFilter descriptionFilter = new DescriptionFilter(getDescLOD(), getDescription(), DescriptionFilter.FilterMode.EXCLUDE);
|
||||
chart.getBundleFilters().add(descriptionFilter);
|
||||
RootFilter rootFilter = eventsModel.getFilter();
|
||||
rootFilter.getSubFilters().add(descriptionFilter);
|
||||
chart.getController().pushFilters(rootFilter.copyOf());
|
||||
chart.setRequiresLayout(true);
|
||||
chart.requestChartLayout();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,10 +68,10 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.EventBundle;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
||||
import org.sleuthkit.autopsy.timeline.ui.AbstractVisualization;
|
||||
import org.sleuthkit.autopsy.timeline.ui.countsview.CountsViewPane;
|
||||
import org.sleuthkit.autopsy.timeline.ui.detailview.tree.NavTreeNode;
|
||||
@ -243,8 +243,8 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
|
||||
});
|
||||
}
|
||||
|
||||
public ObservableList<DescriptionFilter> getBundleFilters() {
|
||||
return chart.getBundleFilters();
|
||||
public ObservableList<String> getQuickHideMasks() {
|
||||
return chart.getQuickHideMasks();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -301,11 +301,12 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
if (isCancelled() == false) {
|
||||
|
||||
if (isCancelled() == false) {
|
||||
Platform.runLater(() -> {
|
||||
setCursor(Cursor.WAIT);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
updateProgress(-1, 1);
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.preparing"));
|
||||
@ -315,6 +316,7 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
|
||||
final long upperBound = rangeInfo.getUpperBound();
|
||||
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.queryDb"));
|
||||
getQuickHideMasks().clear();
|
||||
aggregatedEvents.setAll(filteredEvents.getAggregatedEvents());
|
||||
|
||||
Platform.runLater(() -> {
|
||||
@ -336,12 +338,11 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
|
||||
updateProgress(i++, size);
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.updateUI"));
|
||||
final XYChart.Data<DateTime, EventCluster> xyData = new BarChart.Data<>(new DateTime(e.getSpan().getStartMillis()), e);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
if (isCancelled() == false) {
|
||||
if (isCancelled() == false) {
|
||||
Platform.runLater(() -> {
|
||||
getSeries(e.getEventType()).getData().add(xyData);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
@ -485,4 +486,11 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
|
||||
|
||||
}
|
||||
|
||||
public EventDetailChart.UnhideBundleAction newUnhideBundleAction(String description) {
|
||||
return chart.new UnhideBundleAction(description);
|
||||
}
|
||||
|
||||
public EventDetailChart.HideBundleAction newHideBundleAction(EventBundle bundle) {
|
||||
return chart.new HideBundleAction(bundle);
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,9 @@ import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||
*/
|
||||
public final class EventDetailChart extends XYChart<DateTime, EventCluster> implements TimeLineChart<DateTime> {
|
||||
|
||||
static final Image HIDE = new Image("/org/sleuthkit/autopsy/timeline/images/eye--minus.png"); // NON-NLS
|
||||
static final Image SHOW = new Image("/org/sleuthkit/autopsy/timeline/images/eye--plus.png"); // NON-NLS
|
||||
|
||||
private static final int PROJECTED_LINE_Y_OFFSET = 5;
|
||||
|
||||
private static final int PROJECTED_LINE_STROKE_WIDTH = 5;
|
||||
@ -203,7 +206,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
*/
|
||||
private final SimpleDoubleProperty truncateWidth = new SimpleDoubleProperty(200.0);
|
||||
private final SimpleBooleanProperty alternateLayout = new SimpleBooleanProperty(true);
|
||||
private ObservableList<DescriptionFilter> bundleFilters = FXCollections.observableArrayList();
|
||||
private ObservableList<String> quickHideMasks = FXCollections.observableArrayList();
|
||||
|
||||
EventDetailChart(DateAxis dateAxis, final Axis<EventCluster> verticalAxis, ObservableList<DetailViewNode<?>> selectedNodes) {
|
||||
super(dateAxis, verticalAxis);
|
||||
@ -499,8 +502,8 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
shownPartition = bundleStream
|
||||
.map(nodeMap::get)
|
||||
.sorted(Comparator.comparing(AbstractDetailViewNode<?, ?>::getStartMillis))
|
||||
.collect(Collectors.partitioningBy(node -> getBundleFilters().stream()
|
||||
.allMatch(filter -> filter.test(node.getDescription()))));
|
||||
.collect(Collectors.partitioningBy(node -> getQuickHideMasks().stream()
|
||||
.anyMatch(mask -> mask.equals(node.getDescription()))));
|
||||
|
||||
layoutNodesHelper(shownPartition.get(false), shownPartition.get(true), minY);
|
||||
minY = maxY.get();
|
||||
@ -508,9 +511,9 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
} else {
|
||||
shownPartition = nodeMap.values().stream()
|
||||
.sorted(Comparator.comparing(AbstractDetailViewNode<?, ?>::getStartMillis))
|
||||
.collect(Collectors.partitioningBy(node -> getBundleFilters().stream()
|
||||
.allMatch(filter -> filter.test(node.getDescription()))));
|
||||
layoutNodesHelper(shownPartition.get(false), shownPartition.get(true), 0);
|
||||
.collect(Collectors.partitioningBy(node -> getQuickHideMasks().stream()
|
||||
.anyMatch(mask -> mask.equals(node.getDescription()))));
|
||||
layoutNodesHelper(shownPartition.get(true), shownPartition.get(false), 0);
|
||||
}
|
||||
setCursor(null);
|
||||
requiresLayout = false;
|
||||
@ -756,8 +759,8 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
return alternateLayout;
|
||||
}
|
||||
|
||||
ObservableList<DescriptionFilter> getBundleFilters() {
|
||||
return bundleFilters;
|
||||
ObservableList<String> getQuickHideMasks() {
|
||||
return quickHideMasks;
|
||||
}
|
||||
|
||||
private class DetailIntervalSelector extends IntervalSelector<DateTime> {
|
||||
@ -798,4 +801,36 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
|
||||
void applySelectionEffect(DetailViewNode<?> c1, Boolean selected) {
|
||||
c1.applySelectionEffect(selected);
|
||||
}
|
||||
|
||||
public class HideBundleAction extends Action {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param description the value of description
|
||||
*/
|
||||
public HideBundleAction(final EventBundle bundle) {
|
||||
super("Hide");
|
||||
setGraphic(new ImageView(HIDE));
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
getQuickHideMasks().add(bundle.getDescription());
|
||||
filteredEvents.getFilter().getSubFilters().add(new DescriptionFilter(bundle.getDescriptionLOD(), bundle.getDescription(), DescriptionFilter.FilterMode.EXCLUDE));
|
||||
setRequiresLayout(true);
|
||||
requestChartLayout();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class UnhideBundleAction extends Action {
|
||||
|
||||
public UnhideBundleAction(String description) {
|
||||
|
||||
super("Unhide");
|
||||
setGraphic(new ImageView(SHOW));
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
getQuickHideMasks().removeAll(description);
|
||||
setRequiresLayout(true);
|
||||
requestChartLayout();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.ui.detailview.tree;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import javafx.application.Platform;
|
||||
@ -36,13 +37,13 @@ import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import org.controlsfx.control.action.ActionUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
||||
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewNode;
|
||||
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
|
||||
|
||||
@ -144,30 +145,35 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
||||
ImageView imageView = new ImageView(item.getType().getFXImage());
|
||||
|
||||
setGraphic(new StackPane(rect, imageView));
|
||||
detailViewPane.getBundleFilters().addListener((Observable observable) -> {
|
||||
asdasd(item, rect, imageView);
|
||||
detailViewPane.getQuickHideMasks().addListener((Observable observable) -> {
|
||||
configureHiddenState(item, rect, imageView);
|
||||
});
|
||||
asdasd(item, rect, imageView);
|
||||
configureHiddenState(item, rect, imageView);
|
||||
|
||||
} else {
|
||||
setText(null);
|
||||
setTooltip(null);
|
||||
setGraphic(null);
|
||||
setContextMenu(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void asdasd(NavTreeNode item, Rectangle rect, ImageView imageView) {
|
||||
if (detailViewPane.getBundleFilters().stream().allMatch((DescriptionFilter t) -> t.test(item.getDescription())) == false) {
|
||||
private void configureHiddenState(NavTreeNode item, Rectangle rect, ImageView imageView) {
|
||||
if (detailViewPane.getQuickHideMasks().stream().anyMatch(mask -> mask.equals(item.getDescription()))) {
|
||||
setTextFill(Color.gray(0, .6));
|
||||
imageView.setOpacity(.6);
|
||||
rect.setStroke(item.getType().getColor().deriveColor(0, .6, 1, .6));
|
||||
rect.setFill(item.getType().getColor().deriveColor(0, .6, .6, 0.1));
|
||||
setContextMenu(ActionUtils.createContextMenu(ImmutableList.of(detailViewPane.newUnhideBundleAction(item.getDescription()))));
|
||||
} else {
|
||||
setTextFill(Color.BLACK);
|
||||
imageView.setOpacity(1);
|
||||
rect.setStroke(item.getType().getColor());
|
||||
rect.setFill(item.getType().getColor().deriveColor(0, 1, 1, 0.1));
|
||||
// setContextMenu(ActionUtils.createContextMenu(ImmutableList.of(detailViewPane.newHideBundleAction(item.getDescription()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.EventBundle;
|
||||
@ -69,8 +68,7 @@ class RootItem extends NavTreeItem {
|
||||
Platform.runLater(() -> {
|
||||
synchronized (getChildren()) {
|
||||
getChildren().add(newTreeItem);
|
||||
|
||||
FXCollections.sort(getChildren(), TreeComparator.Type);
|
||||
getChildren().sort(TreeComparator.Type);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -89,7 +89,7 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
assert applyButton != null : "fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'."; // NON-NLS
|
||||
|
||||
applyButton.setOnAction(e -> {
|
||||
controller.pushFilters((RootFilter) filterTreeTable.getRoot().getValue().copyOf());
|
||||
controller.pushFilters((RootFilter) filterTreeTable.getRoot().getValue());
|
||||
});
|
||||
applyButton.setText(Bundle.FilterSetPanel_applyButton_text());
|
||||
defaultButton.setText(Bundle.FilterSetPanel_defaultButton_text());
|
||||
@ -173,7 +173,6 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
@Override
|
||||
public void setModel(FilteredEventsModel filteredEvents) {
|
||||
this.filteredEvents = filteredEvents;
|
||||
filteredEvents.registerForEvents(this);
|
||||
refresh();
|
||||
this.filteredEvents.filterProperty().addListener((Observable o) -> {
|
||||
refresh();
|
||||
@ -182,7 +181,7 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
private void refresh() {
|
||||
Platform.runLater(() -> {
|
||||
filterTreeTable.setRoot(new FilterTreeItem(filteredEvents.getFilter().copyOf(), expansionMap));
|
||||
filterTreeTable.setRoot(new FilterTreeItem(filteredEvents.getFilter(), expansionMap));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user