1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-06 02:24:30 +00:00

WIP Cleanup, verification that all existing features till work in new alternate layout mode.

This commit is contained in:
jmillman
2015-09-11 15:13:26 -04:00
parent dbdf8bffc9
commit d48ff72098
13 changed files with 174 additions and 140 deletions

View File

@@ -5,6 +5,7 @@
*/
package org.sleuthkit.autopsy.timeline.datamodel;
import com.google.common.collect.Range;
import java.util.Set;
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLOD;
@@ -18,16 +19,18 @@ public interface EventBundle {
DescriptionLOD getDescriptionLOD();
long getEndMillis();
Set<Long> getEventIDs();
Set<Long> getEventIDsWithHashHits();
Set<Long> getEventIDsWithTags();
EventType getEventType();
long getEndMillis();
long getStartMillis();
EventType getType();
Iterable<Range<Long>> getRanges();
}

View File

@@ -115,7 +115,7 @@ public class EventCluster implements EventBundle {
return description;
}
public EventType getType() {
public EventType getEventType() {
return type;
}
@@ -135,7 +135,7 @@ public class EventCluster implements EventBundle {
*/
public static EventCluster merge(EventCluster aggEvent1, EventCluster ag2) {
if (aggEvent1.getType() != ag2.getType()) {
if (aggEvent1.getEventType() != ag2.getEventType()) {
throw new IllegalArgumentException("aggregate events are not compatible they have different types");
}
@@ -146,7 +146,7 @@ public class EventCluster implements EventBundle {
Sets.SetView<Long> hashHitsUnion = Sets.union(aggEvent1.getEventIDsWithHashHits(), ag2.getEventIDsWithHashHits());
Sets.SetView<Long> taggedUnion = Sets.union(aggEvent1.getEventIDsWithTags(), ag2.getEventIDsWithTags());
return new EventCluster(IntervalUtils.span(aggEvent1.span, ag2.span), aggEvent1.getType(), idsUnion, hashHitsUnion, taggedUnion, aggEvent1.getDescription(), aggEvent1.lod);
return new EventCluster(IntervalUtils.span(aggEvent1.span, ag2.span), aggEvent1.getEventType(), idsUnion, hashHitsUnion, taggedUnion, aggEvent1.getDescription(), aggEvent1.lod);
}
Range<Long> getRange() {
@@ -156,4 +156,10 @@ public class EventCluster implements EventBundle {
return Range.singleton(getStartMillis());
}
}
@Override
public Iterable<Range<Long>> getRanges() {
return Collections.singletonList(getRange());
}
}

View File

@@ -63,7 +63,7 @@ public final class EventStripe implements EventBundle {
public EventStripe(EventCluster aggEvent) {
spans.add(aggEvent.getRange());
spanMap.put(aggEvent.getRange(), aggEvent);
type = aggEvent.getType();
type = aggEvent.getEventType();
description = aggEvent.getDescription();
lod = aggEvent.getDescriptionLOD();
eventIDs.addAll(aggEvent.getEventIDs());
@@ -76,7 +76,7 @@ public final class EventStripe implements EventBundle {
spans.addAll(v.spans);
spanMap.putAll(u.spanMap);
spanMap.putAll(v.spanMap);
type = u.getType();
type = u.getEventType();
description = u.getDescription();
lod = u.getDescriptionLOD();
eventIDs.addAll(u.getEventIDs());
@@ -96,38 +96,47 @@ public final class EventStripe implements EventBundle {
return new EventStripe(u, v);
}
@Override
public String getDescription() {
return description;
}
public EventType getType() {
@Override
public EventType getEventType() {
return type;
}
@Override
public DescriptionLOD getDescriptionLOD() {
return lod;
}
@Override
public Set<Long> getEventIDs() {
return Collections.unmodifiableSet(eventIDs);
}
@Override
public Set<Long> getEventIDsWithHashHits() {
return Collections.unmodifiableSet(hashHits);
}
@Override
public Set<Long> getEventIDsWithTags() {
return Collections.unmodifiableSet(tagged);
}
@Override
public long getStartMillis() {
return spans.span().lowerEndpoint();
}
@Override
public long getEndMillis() {
return spans.span().upperEndpoint();
}
@Override
public Iterable<Range<Long>> getRanges() {
return spans.asRanges();
}

View File

@@ -1140,7 +1140,7 @@ public class EventDB {
Map<EventType, SetMultimap< String, EventCluster>> typeMap = new HashMap<>();
for (EventCluster aggregateEvent : preMergedEvents) {
typeMap.computeIfAbsent(aggregateEvent.getType(), eventType -> HashMultimap.create())
typeMap.computeIfAbsent(aggregateEvent.getEventType(), eventType -> HashMultimap.create())
.put(aggregateEvent.getDescription(), aggregateEvent);
}
//result list to return

View File

@@ -27,13 +27,13 @@ public interface DetailViewNode<S extends DetailViewNode<S>> {
public void setDescriptionWidth(double max);
public EventType getType();
public EventType getEventType();
public Set<Long> getEventIDs();
public String getDescription();
public EventBundle getBundleDescriptor();
public EventBundle getEventBundle();
/**
* apply the 'effect' to visually indicate highlighted nodes

View File

@@ -70,6 +70,7 @@ 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;
@@ -100,7 +101,7 @@ import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
* TODO: refactor common code out of this class and CountsChartPane into
* {@link AbstractVisualization}
*/
public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster, DetailViewNode<?>, EventDetailChart> {
public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster, EventBundle, EventDetailChart> {
private final static Logger LOGGER = Logger.getLogger(CountsViewPane.class.getName());
@@ -336,7 +337,7 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
Platform.runLater(() -> {
if (isCancelled() == false) {
getSeries(e.getType()).getData().add(xyData);
getSeries(e.getEventType()).getData().add(xyData);
}
});
}
@@ -357,8 +358,9 @@ public class DetailViewPane extends AbstractVisualization<DateTime, EventCluster
}
@Override
protected void applySelectionEffect(DetailViewNode<?> c1, Boolean applied) {
c1.applySelectionEffect(applied);
protected void applySelectionEffect(EventBundle c1, Boolean selected) {
chart.applySelectionEffect(c1, selected);
}
private class DetailViewSettingsPane extends HBox {

View File

@@ -99,7 +99,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
/**
* The event this AggregateEventNode represents visually
*/
private EventCluster aggEvent;
private EventCluster eventCluster;
private final EventClusterNode parentEventNode;
@@ -177,7 +177,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
private final ImageView tagIV = new ImageView(TAG);
public EventClusterNode(final EventCluster aggEvent, EventClusterNode parentEventNode, EventDetailChart chart) {
this.aggEvent = aggEvent;
this.eventCluster = aggEvent;
descLOD.set(aggEvent.getDescriptionLOD());
this.parentEventNode = parentEventNode;
this.chart = chart;
@@ -222,7 +222,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
subNodePane.setPickOnBounds(false);
//setup description label
eventTypeImageView.setImage(aggEvent.getType().getFXImage());
eventTypeImageView.setImage(aggEvent.getEventType().getFXImage());
descrLabel.setGraphic(eventTypeImageView);
descrLabel.setPrefWidth(USE_COMPUTED_SIZE);
descrLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
@@ -231,7 +231,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
setDescriptionVisibility(chart.getDescrVisibility().get());
//setup backgrounds
final Color evtColor = aggEvent.getType().getColor();
final Color evtColor = aggEvent.getEventType().getColor();
spanFill = new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
setBackground(spanFill);
setCursor(Cursor.HAND);
@@ -283,10 +283,10 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
//TODO: all this work should probably go on a background thread...
if (tooltip == null) {
HashMap<String, Long> hashSetCounts = new HashMap<>();
if (!aggEvent.getEventIDsWithHashHits().isEmpty()) {
if (!eventCluster.getEventIDsWithHashHits().isEmpty()) {
hashSetCounts = new HashMap<>();
try {
for (TimeLineEvent tle : eventsModel.getEventsById(aggEvent.getEventIDsWithHashHits())) {
for (TimeLineEvent tle : eventsModel.getEventsById(eventCluster.getEventIDsWithHashHits())) {
Set<String> hashSetNames = sleuthkitCase.getAbstractFileById(tle.getFileID()).getHashSetNames();
for (String hashSetName : hashSetNames) {
hashSetCounts.merge(hashSetName, 1L, Long::sum);
@@ -298,8 +298,8 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
}
Map<String, Long> tagCounts = new HashMap<>();
if (!aggEvent.getEventIDsWithTags().isEmpty()) {
tagCounts.putAll(eventsModel.getTagCountsByTagName(aggEvent.getEventIDsWithTags()));
if (!eventCluster.getEventIDsWithTags().isEmpty()) {
tagCounts.putAll(eventsModel.getTagCountsByTagName(eventCluster.getEventIDsWithTags()));
}
@@ -312,7 +312,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
tooltip = new Tooltip(
NbBundle.getMessage(this.getClass(), "AggregateEventNode.installTooltip.text",
getEvent().getEventIDs().size(), getEvent().getType(), getEvent().getDescription(),
getEvent().getEventIDs().size(), getEvent().getEventType(), getEvent().getDescription(),
getEvent().getSpan().getStart().toString(TimeLineController.getZonedFormatter()),
getEvent().getSpan().getEnd().toString(TimeLineController.getZonedFormatter()))
+ (hashSetCountsString.isEmpty() ? "" : "\n\nHash Set Hits\n" + hashSetCountsString)
@@ -330,7 +330,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
}
synchronized public EventCluster getEvent() {
return aggEvent;
return eventCluster;
}
/**
@@ -367,7 +367,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
@Override
public final synchronized void setDescriptionVisibility(DescriptionVisibility descrVis) {
this.descrVis = descrVis;
final int size = aggEvent.getEventIDs().size();
final int size = eventCluster.getEventIDs().size();
switch (descrVis) {
case COUNT_ONLY:
@@ -380,7 +380,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
break;
default:
case SHOWN:
String description = aggEvent.getDescription();
String description = eventCluster.getDescription();
description = parentEventNode != null
? " ..." + StringUtils.substringAfter(description, parentEventNode.getEvent().getDescription())
: description;
@@ -408,7 +408,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
@Override
public String getDescription() {
return aggEvent.getDescription();
return eventCluster.getDescription();
}
/**
@@ -420,14 +420,14 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
if (applied) {
descrLabel.setStyle("-fx-font-weight: bold;"); // NON-NLS
spanFill = new Background(new BackgroundFill(aggEvent.getType().getColor().deriveColor(0, 1, 1, .3), CORNER_RADII, Insets.EMPTY));
spanFill = new Background(new BackgroundFill(eventCluster.getEventType().getColor().deriveColor(0, 1, 1, .3), CORNER_RADII, Insets.EMPTY));
spanRegion.setBackground(spanFill);
setBackground(new Background(new BackgroundFill(aggEvent.getType().getColor().deriveColor(0, 1, 1, .2), CORNER_RADII, Insets.EMPTY)));
setBackground(new Background(new BackgroundFill(eventCluster.getEventType().getColor().deriveColor(0, 1, 1, .2), CORNER_RADII, Insets.EMPTY)));
} else {
descrLabel.setStyle("-fx-font-weight: normal;"); // NON-NLS
spanFill = new Background(new BackgroundFill(aggEvent.getType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
spanFill = new Background(new BackgroundFill(eventCluster.getEventType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
spanRegion.setBackground(spanFill);
setBackground(new Background(new BackgroundFill(aggEvent.getType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
setBackground(new Background(new BackgroundFill(eventCluster.getEventType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
}
}
@@ -461,17 +461,17 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
*/
synchronized private void loadSubClusters(DescriptionLOD newDescriptionLOD) {
subNodePane.getChildren().clear();
if (newDescriptionLOD == aggEvent.getDescriptionLOD()) {
if (newDescriptionLOD == eventCluster.getDescriptionLOD()) {
chart.setRequiresLayout(true);
chart.requestChartLayout();
} else {
RootFilter combinedFilter = eventsModel.filterProperty().get().copyOf();
//make a new filter intersecting the global filter with text(description) and type filters to restrict sub-clusters
combinedFilter.getSubFilters().addAll(new TextFilter(aggEvent.getDescription()),
new TypeFilter(aggEvent.getType()));
combinedFilter.getSubFilters().addAll(new TextFilter(eventCluster.getDescription()),
new TypeFilter(eventCluster.getEventType()));
//make a new end inclusive span (to 'filter' with)
final Interval span = aggEvent.getSpan().withEndMillis(aggEvent.getSpan().getEndMillis() + 1000);
final Interval span = eventCluster.getSpan().withEndMillis(eventCluster.getSpan().getEndMillis() + 1000);
//make a task to load the subnodes
LoggedTask<List<EventClusterNode>> loggedTask = new LoggedTask<List<EventClusterNode>>(
@@ -523,11 +523,11 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
if (t.getButton() == MouseButton.PRIMARY) {
t.consume();
if (t.isShiftDown()) {
if (chart.selectedNodes.contains(EventClusterNode.this) == false) {
chart.selectedNodes.add(EventClusterNode.this);
if (chart.selectedBundles.contains(eventCluster) == false) {
chart.selectedBundles.add(eventCluster);
}
} else if (t.isShortcutDown()) {
chart.selectedNodes.removeAll(EventClusterNode.this);
chart.selectedBundles.removeAll(eventCluster);
} else if (t.getClickCount() > 1) {
final DescriptionLOD next = descLOD.get().next();
if (next != null) {
@@ -535,7 +535,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
descLOD.set(next);
}
} else {
chart.selectedNodes.setAll(EventClusterNode.this);
chart.selectedBundles.setAll(eventCluster);
}
}
}
@@ -552,8 +552,8 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
}
@Override
public EventType getType() {
return getEvent().getType();
public EventType getEventType() {
return getEvent().getEventType();
}
@Override
@@ -562,7 +562,7 @@ public class EventClusterNode extends StackPane implements DetailViewNode<EventC
}
@Override
public EventBundle getBundleDescriptor() {
return aggEvent;
public EventBundle getEventBundle() {
return eventCluster;
}
}

View File

@@ -45,9 +45,7 @@ import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
@@ -77,6 +75,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.timeline.TimeLineController;
import org.sleuthkit.autopsy.timeline.actions.Back;
import org.sleuthkit.autopsy.timeline.actions.Forward;
import org.sleuthkit.autopsy.timeline.datamodel.EventBundle;
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
@@ -158,7 +157,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
/**
* map from event to node
*/
private final Map<EventCluster, EventClusterNode> nodeMap = new HashMap<>();
private final Map<EventCluster, EventClusterNode> clusterNodeMap = new HashMap<>();
private final Map<ImmutablePair<EventType, String>, EventStripe> stripeDescMap = new HashMap<>();
private final Map<EventStripe, EventStripeNode> stripeNodeMap = new HashMap<>();
/**
@@ -168,7 +167,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
*/
private final SimpleBooleanProperty oneEventPerRow = new SimpleBooleanProperty(false);
private final ObservableMap<DetailViewNode<?>, Line> projectionMap = FXCollections.observableHashMap();
private final Map<Range<Long>, Line> projectionMap = new HashMap<>();
/**
* flag indicating whether this chart actually needs a layout pass
@@ -176,7 +175,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
@GuardedBy(value = "this")
private boolean requiresLayout = true;
final ObservableList<DetailViewNode<?>> selectedNodes;
final ObservableList<EventBundle> selectedBundles;
/**
* list of series of data added to this chart TODO: replace this with a map
@@ -206,11 +205,11 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
private final SimpleDoubleProperty truncateWidth = new SimpleDoubleProperty(200.0);
private final SimpleBooleanProperty alternateLayout = new SimpleBooleanProperty(true);
EventDetailChart(DateAxis dateAxis, final Axis<EventCluster> verticalAxis, ObservableList<DetailViewNode<?>> selectedNodes) {
EventDetailChart(DateAxis dateAxis, final Axis<EventCluster> verticalAxis, ObservableList<EventBundle> selectedNodes) {
super(dateAxis, verticalAxis);
dateAxis.setAutoRanging(false);
//yAxis.setVisible(false);//TODO: why doesn't this hide the vertical axis, instead we have to turn off all parts individually? -jm
//verticalAxis.setVisible(false);//TODO: why doesn't this hide the vertical axis, instead we have to turn off all parts individually? -jm
verticalAxis.setTickLabelsVisible(false);
verticalAxis.setTickMarkVisible(false);
@@ -224,7 +223,6 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
//bind listener to events that should trigger layout
widthProperty().addListener(layoutInvalidationListener);
heightProperty().addListener(layoutInvalidationListener);
// boundsInLocalProperty().addListener(layoutInvalidationListener);
bandByType.addListener(layoutInvalidationListener);
oneEventPerRow.addListener(layoutInvalidationListener);
@@ -286,34 +284,41 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
setOnMouseReleased(dragHandler);
setOnMouseDragged(dragHandler);
projectionMap.addListener((MapChangeListener.Change<? extends DetailViewNode<?>, ? extends Line> change) -> {
final Line valueRemoved = change.getValueRemoved();
if (valueRemoved != null) {
getChartChildren().removeAll(valueRemoved);
}
final Line valueAdded = change.getValueAdded();
if (valueAdded != null) {
getChartChildren().add(valueAdded);
}
});
this.selectedNodes = selectedNodes;
this.selectedNodes.addListener((
ListChangeListener.Change<? extends DetailViewNode<?>> c) -> {
// projectionMap.addListener((MapChangeListener.Change<? extends DetailViewNode<?>, ? extends Line> change) -> {
// final Line valueRemoved = change.getValueRemoved();
// if (valueRemoved != null) {
// getChartChildren().removeAll(valueRemoved);
// }
// final Line valueAdded = change.getValueAdded();
// if (valueAdded != null) {
// getChartChildren().add(valueAdded);
// }
// });
this.selectedBundles = selectedNodes;
this.selectedBundles.addListener((
ListChangeListener.Change<? extends EventBundle> c) -> {
while (c.next()) {
c.getRemoved().forEach((DetailViewNode<?> t) -> {
projectionMap.remove(t);
});
c.getAddedSubList().forEach((DetailViewNode<?> t) -> {
Line line = new Line(dateAxis.localToParent(dateAxis.getDisplayPosition(new DateTime(t.getStartMillis(), TimeLineController.getJodaTimeZone())), 0).getX(), dateAxis.getLayoutY() + PROJECTED_LINE_Y_OFFSET,
dateAxis.localToParent(dateAxis.getDisplayPosition(new DateTime(t.getEndMillis(), TimeLineController.getJodaTimeZone())), 0).getX(), dateAxis.getLayoutY() + PROJECTED_LINE_Y_OFFSET
);
line.setStroke(t.getType().getColor().deriveColor(0, 1, 1, .5));
line.setStrokeWidth(PROJECTED_LINE_STROKE_WIDTH);
line.setStrokeLineCap(StrokeLineCap.ROUND);
projectionMap.put(t, line);
});
c.getRemoved().forEach((EventBundle t) -> {
t.getRanges().forEach((Range<Long> t1) -> {
Line removeAll = projectionMap.remove(t1);
getChartChildren().removeAll(removeAll);
});
});
c.getAddedSubList().forEach((EventBundle t) -> {
for (Range<Long> r : t.getRanges()) {
Line line = new Line(dateAxis.localToParent(dateAxis.getDisplayPosition(new DateTime(r.lowerEndpoint(), TimeLineController.getJodaTimeZone())), 0).getX(), dateAxis.getLayoutY() + PROJECTED_LINE_Y_OFFSET,
dateAxis.localToParent(dateAxis.getDisplayPosition(new DateTime(r.upperEndpoint(), TimeLineController.getJodaTimeZone())), 0).getX(), dateAxis.getLayoutY() + PROJECTED_LINE_Y_OFFSET
);
line.setStroke(t.getEventType().getColor().deriveColor(0, 1, 1, .5));
line.setStrokeWidth(PROJECTED_LINE_STROKE_WIDTH);
line.setStrokeLineCap(StrokeLineCap.ROUND);
projectionMap.put(r, line);
getChartChildren().add(line);
}
});
}
this.controller.selectEventIDs(selectedNodes.stream()
@@ -348,7 +353,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
clearGuideLine();
clearIntervalSelector();
selectedNodes.clear();
selectedBundles.clear();
projectionMap.clear();
controller.selectEventIDs(Collections.emptyList());
});
@@ -411,7 +416,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
protected synchronized void dataItemAdded(Series<DateTime, EventCluster> series, int i, Data<DateTime, EventCluster> data) {
final EventCluster aggEvent = data.getYValue();
if (alternateLayout.get()) {
EventStripe eventCluster = stripeDescMap.merge(ImmutablePair.of(aggEvent.getType(), aggEvent.getDescription()),
EventStripe eventCluster = stripeDescMap.merge(ImmutablePair.of(aggEvent.getEventType(), aggEvent.getDescription()),
new EventStripe(aggEvent),
(EventStripe u, EventStripe v) -> {
EventStripeNode remove = stripeNodeMap.remove(u);
@@ -425,10 +430,10 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
stripeNodeMap.put(eventCluster, clusterNode);
nodeGroup.getChildren().add(clusterNode);
} else {
nodeMap.computeIfAbsent(aggEvent, (EventCluster t) -> {
clusterNodeMap.computeIfAbsent(aggEvent, (EventCluster t) -> {
EventClusterNode eventNode = new EventClusterNode(aggEvent, null, EventDetailChart.this);
eventNode.setLayoutX(getXAxis().getDisplayPosition(new DateTime(aggEvent.getSpan().getStartMillis())));
nodeMap.put(aggEvent, eventNode);
clusterNodeMap.put(aggEvent, eventNode);
nodeGroup.getChildren().add(eventNode);
return eventNode;
});
@@ -444,10 +449,10 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
@Override
protected synchronized void dataItemRemoved(Data<DateTime, EventCluster> data, Series<DateTime, EventCluster> series) {
EventCluster aggEvent = data.getYValue();
Node removedNode = nodeMap.remove(aggEvent);
Node removedNode = clusterNodeMap.remove(aggEvent);
nodeGroup.getChildren().remove(removedNode);
EventStripe removedCluster = stripeDescMap.remove(ImmutablePair.of(aggEvent.getType(), aggEvent.getDescription()));
EventStripe removedCluster = stripeDescMap.remove(ImmutablePair.of(aggEvent.getEventType(), aggEvent.getDescription()));
removedNode = stripeNodeMap.remove(removedCluster);
nodeGroup.getChildren().remove(removedNode);
@@ -490,7 +495,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
nodes.sort(Comparator.comparing(DetailViewNode<?>::getStartMillis));
layoutNodes(nodes, minY, 0);
} else {
List<EventClusterNode> nodes = new ArrayList<>(nodeMap.values());
List<EventClusterNode> nodes = new ArrayList<>(clusterNodeMap.values());
nodes.sort(Comparator.comparing(DetailViewNode<?>::getStartMillis));
layoutNodes(nodes, minY, 0);
}
@@ -500,7 +505,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
if (alternateLayout.get() == true) {
List<EventStripeNode> nodes = s.getData().stream()
.map(Data::getYValue)
.map(cluster -> stripeDescMap.get(ImmutablePair.of(cluster.getType(), cluster.getDescription())))
.map(cluster -> stripeDescMap.get(ImmutablePair.of(cluster.getEventType(), cluster.getDescription())))
.distinct()
.sorted(Comparator.comparing(EventStripe::getStartMillis))
.map(stripeNodeMap::get)
@@ -509,7 +514,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
} else {
List<EventClusterNode> nodes = s.getData().stream()
.map(Data::getYValue)
.map(nodeMap::get)
.map(clusterNodeMap::get)
.filter(Objects::nonNull)
.sorted(Comparator.comparing(EventClusterNode::getStartMillis))
.collect(Collectors.toList());
@@ -553,7 +558,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
Iterable<DetailViewNode<?>> getNodes(Predicate<DetailViewNode<?>> p) {
Collection<? extends DetailViewNode<?>> values = alternateLayout.get()
? stripeNodeMap.values()
: nodeMap.values();
: clusterNodeMap.values();
//collapse tree of DetailViewNoeds to list and then filter on given predicate
return values.stream()
@@ -626,7 +631,7 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
List<Double> spanWidths = new ArrayList<>();
double x = getXAxis().getDisplayPosition(new DateTime(cn.getStartMillis()));;
double x2;
Iterator<Range<Long>> ranges = cn.getCluster().getRanges().iterator();
Iterator<Range<Long>> ranges = cn.getStripe().getRanges().iterator();
Range<Long> range = ranges.next();
do {
x2 = getXAxis().getDisplayPosition(new DateTime(range.upperEndpoint()));
@@ -708,12 +713,12 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
private static final int DEFAULT_ROW_HEIGHT = 24;
private void layoutProjectionMap() {
for (final Map.Entry<DetailViewNode<?>, Line> entry : projectionMap.entrySet()) {
final DetailViewNode<?> aggNode = entry.getKey();
for (final Map.Entry<Range<Long>, Line> entry : projectionMap.entrySet()) {
final Range<Long> eventBundle = entry.getKey();
final Line line = entry.getValue();
line.setStartX(getParentXForValue(new DateTime(aggNode.getStartMillis(), TimeLineController.getJodaTimeZone())));
line.setEndX(getParentXForValue(new DateTime(aggNode.getEndMillis(), TimeLineController.getJodaTimeZone())));
line.setStartX(getParentXForValue(new DateTime(eventBundle.lowerEndpoint(), TimeLineController.getJodaTimeZone())));
line.setEndX(getParentXForValue(new DateTime(eventBundle.upperEndpoint(), TimeLineController.getJodaTimeZone())));
line.setStartY(getXAxis().getLayoutY() + PROJECTED_LINE_Y_OFFSET);
line.setEndY(getXAxis().getLayoutY() + PROJECTED_LINE_Y_OFFSET);
}
@@ -791,4 +796,13 @@ public final class EventDetailChart extends XYChart<DateTime, EventCluster> impl
protected void requestChartLayout() {
super.requestChartLayout();
}
void applySelectionEffect(EventBundle c1, Boolean selected) {
if (alternateLayout.get()) {
EventStripe eventStripe = stripeDescMap.get(ImmutablePair.of(c1.getEventType(), c1.getDescription()));
stripeNodeMap.get(eventStripe).applySelectionEffect(selected);
} else {
clusterNodeMap.get(c1).applySelectionEffect(selected);
}
}
}

View File

@@ -75,7 +75,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
private final static Image TAG = new Image("/org/sleuthkit/autopsy/images/green-tag-icon-16.png"); // NON-NLS
private final Pane subNodePane = new Pane();
private final EventStripe cluster;
private final EventStripe eventStripe;
private final EventStripeNode parentNode;
private final EventDetailChart chart;
private SimpleObjectProperty<DescriptionLOD> descLOD = new SimpleObjectProperty<>();
@@ -124,23 +124,23 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
private Background spanFill;
private static final CornerRadii CORNER_RADII = new CornerRadii(3);
EventStripeNode(EventStripe cluster, EventStripeNode parentNode, EventDetailChart chart) {
EventStripeNode(EventStripe eventStripe, EventStripeNode parentNode, EventDetailChart chart) {
this.chart = chart;
sleuthkitCase = chart.getController().getAutopsyCase().getSleuthkitCase();
eventsModel = chart.getController().getEventsModel();
this.parentNode = parentNode;
this.cluster = cluster;
descLOD.set(cluster.getDescriptionLOD());
this.eventStripe = eventStripe;
descLOD.set(eventStripe.getDescriptionLOD());
final Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
final HBox header = new HBox(descrLabel, countLabel, hashIV, tagIV, spacer, minusButton, plusButton);
if (cluster.getEventIDsWithHashHits().isEmpty()) {
if (eventStripe.getEventIDsWithHashHits().isEmpty()) {
show(hashIV, false);
}
if (cluster.getEventIDsWithTags().isEmpty()) {
if (eventStripe.getEventIDsWithTags().isEmpty()) {
show(tagIV, false);
}
header.setMinWidth(USE_PREF_SIZE);
@@ -149,10 +149,10 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
final VBox internalVBox = new VBox(header, subNodePane);
internalVBox.setAlignment(Pos.CENTER_LEFT);
final Color evtColor = cluster.getType().getColor();
final Color evtColor = eventStripe.getEventType().getColor();
spanFill = new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .2), CORNER_RADII, Insets.EMPTY));
for (Range<Long> r : cluster.getRanges()) {
for (Range<Long> r : eventStripe.getRanges()) {
Region spanRegion = new Region();
spanRegion.setStyle("-fx-border-width:2 1 2 1; -fx-border-radius: 1; -fx-border-color: " + ColorUtilities.getRGBCode(evtColor.deriveColor(0, 1, 1, .3)) + ";"); // NON-NLS
spanRegion.setBackground(spanFill);
@@ -162,7 +162,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
spansHBox.setMaxWidth(USE_PREF_SIZE);
setMaxWidth(USE_PREF_SIZE);
getChildren().addAll(spansHBox, internalVBox);
setBackground(new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .05), CORNER_RADII, Insets.EMPTY)));
setBackground(new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
setAlignment(Pos.TOP_LEFT);
setMinHeight(24);
minWidthProperty().bind(spansHBox.widthProperty());
@@ -178,7 +178,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
subNodePane.setPickOnBounds(false);
//setup description label
eventTypeImageView.setImage(cluster.getType().getFXImage());
eventTypeImageView.setImage(eventStripe.getEventType().getFXImage());
descrLabel.setGraphic(eventTypeImageView);
descrLabel.setPrefWidth(USE_COMPUTED_SIZE);
descrLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
@@ -208,7 +208,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
});
plusButton.disableProperty().bind(descLOD.isEqualTo(DescriptionLOD.FULL));
minusButton.disableProperty().bind(descLOD.isEqualTo(cluster.getDescriptionLOD()));
minusButton.disableProperty().bind(descLOD.isEqualTo(eventStripe.getDescriptionLOD()));
plusButton.setOnMouseClicked(e -> {
final DescriptionLOD next = descLOD.get().next();
@@ -228,7 +228,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
@Override
public long getStartMillis() {
return cluster.getStartMillis();
return eventStripe.getStartMillis();
}
@Override
@@ -244,7 +244,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
public void setDescriptionVisibility(DescriptionVisibility descrVis) {
this.descrVis = descrVis;
final int size = cluster.getEventIDs().size();
final int size = eventStripe.getEventIDs().size();
switch (descrVis) {
case COUNT_ONLY:
@@ -257,7 +257,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
break;
default:
case SHOWN:
String description = cluster.getDescription();
String description = eventStripe.getDescription();
description = parentNode != null
? " ..." + StringUtils.substringAfter(description, parentNode.getDescription())
: description;
@@ -267,8 +267,8 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
}
}
EventStripe getCluster() {
return cluster;
EventStripe getStripe() {
return eventStripe;
}
@Override
@@ -278,7 +278,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
@Override
public long getEndMillis() {
return cluster.getEndMillis();
return eventStripe.getEndMillis();
}
@Override
@@ -298,11 +298,11 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
if (t.getButton() == MouseButton.PRIMARY) {
t.consume();
if (t.isShiftDown()) {
if (chart.selectedNodes.contains(EventStripeNode.this) == false) {
chart.selectedNodes.add(EventStripeNode.this);
if (chart.selectedBundles.contains(eventStripe) == false) {
chart.selectedBundles.add(eventStripe);
}
} else if (t.isShortcutDown()) {
chart.selectedNodes.removeAll(EventStripeNode.this);
chart.selectedBundles.removeAll(eventStripe);
} else if (t.getClickCount() > 1) {
final DescriptionLOD next = descLOD.get().next();
if (next != null) {
@@ -310,20 +310,20 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
descLOD.set(next);
}
} else {
chart.selectedNodes.setAll(EventStripeNode.this);
chart.selectedBundles.setAll(eventStripe);
}
}
}
}
@Override
public EventType getType() {
return cluster.getType();
public EventType getEventType() {
return eventStripe.getEventType();
}
@Override
public Set<Long> getEventIDs() {
return cluster.getEventIDs();
return eventStripe.getEventIDs();
}
private static final Border selectionBorder = new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CORNER_RADII, new BorderWidths(2)));
@@ -352,25 +352,25 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
public synchronized void applyHighlightEffect(boolean applied) {
if (applied) {
descrLabel.setStyle("-fx-font-weight: bold;"); // NON-NLS
spanFill = new Background(new BackgroundFill(cluster.getType().getColor().deriveColor(0, 1, 1, .3), CORNER_RADII, Insets.EMPTY));
spanFill = new Background(new BackgroundFill(getEventType().getColor().deriveColor(0, 1, 1, .3), CORNER_RADII, Insets.EMPTY));
spansHBox.setBackground(spanFill);
setBackground(new Background(new BackgroundFill(cluster.getType().getColor().deriveColor(0, 1, 1, .2), CORNER_RADII, Insets.EMPTY)));
setBackground(new Background(new BackgroundFill(getEventType().getColor().deriveColor(0, 1, 1, .2), CORNER_RADII, Insets.EMPTY)));
} else {
descrLabel.setStyle("-fx-font-weight: normal;"); // NON-NLS
spanFill = new Background(new BackgroundFill(cluster.getType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
spanFill = new Background(new BackgroundFill(getEventType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
spansHBox.setBackground(spanFill);
setBackground(new Background(new BackgroundFill(cluster.getType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
setBackground(new Background(new BackgroundFill(getEventType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
}
}
@Override
public String getDescription() {
return cluster.getDescription();
return eventStripe.getDescription();
}
@Override
public EventBundle getBundleDescriptor() {
return getCluster();
public EventBundle getEventBundle() {
return getStripe();
}
/**
@@ -381,7 +381,7 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
synchronized private void loadSubClusters(DescriptionLOD newDescriptionLOD) {
subNodePane.getChildren().clear();
if (newDescriptionLOD == cluster.getDescriptionLOD()) {
if (newDescriptionLOD == eventStripe.getDescriptionLOD()) {
spansHBox.setVisible(true);
chart.setRequiresLayout(true);
chart.requestChartLayout();
@@ -389,11 +389,11 @@ public class EventStripeNode extends StackPane implements DetailViewNode<EventSt
spansHBox.setVisible(false);
RootFilter combinedFilter = eventsModel.filterProperty().get().copyOf();
//make a new filter intersecting the global filter with text(description) and type filters to restrict sub-clusters
combinedFilter.getSubFilters().addAll(new TextFilter(cluster.getDescription()),
new TypeFilter(cluster.getType()));
combinedFilter.getSubFilters().addAll(new TextFilter(eventStripe.getDescription()),
new TypeFilter(eventStripe.getEventType()));
//make a new end inclusive span (to 'filter' with)
final Interval span = new Interval(cluster.getStartMillis(), cluster.getEndMillis() + 1000);
final Interval span = new Interval(eventStripe.getStartMillis(), eventStripe.getEndMillis() + 1000);
//make a task to load the subnodes
LoggedTask<List<EventStripeNode>> loggedTask = new LoggedTask<List<EventStripeNode>>(

View File

@@ -29,7 +29,7 @@ import org.sleuthkit.autopsy.timeline.datamodel.EventBundle;
class EventDescriptionTreeItem extends NavTreeItem {
public EventDescriptionTreeItem(EventCluster g) {
setValue(new NavTreeNode(g.getType().getBaseType(), g.getDescription(), g.getEventIDs().size()));
setValue(new NavTreeNode(g.getEventType().getBaseType(), g.getDescription(), g.getEventIDs().size()));
}
@Override
@@ -40,7 +40,7 @@ class EventDescriptionTreeItem extends NavTreeItem {
@Override
public void insert(EventCluster g) {
NavTreeNode value = getValue();
if ((value.getType().getBaseType().equals(g.getType().getBaseType()) == false) || ((value.getDescription().equals(g.getDescription()) == false))) {
if ((value.getType().getBaseType().equals(g.getEventType().getBaseType()) == false) || ((value.getDescription().equals(g.getDescription()) == false))) {
throw new IllegalArgumentException();
}
@@ -54,7 +54,7 @@ class EventDescriptionTreeItem extends NavTreeItem {
@Override
public TreeItem<NavTreeNode> findTreeItemForEvent(EventBundle t) {
if (getValue().getType().getBaseType() == t.getType().getBaseType() && getValue().getDescription().equals(t.getDescription())) {
if (getValue().getType().getBaseType() == t.getEventType().getBaseType() && getValue().getDescription().equals(t.getDescription())) {
return this;
}
return null;

View File

@@ -37,7 +37,7 @@ class EventTypeTreeItem extends NavTreeItem {
private final Comparator<TreeItem<NavTreeNode>> comparator = TreeComparator.Description;
EventTypeTreeItem(EventCluster g) {
setValue(new NavTreeNode(g.getType().getBaseType(), g.getType().getBaseType().getDisplayName(), 0));
setValue(new NavTreeNode(g.getEventType().getBaseType(), g.getEventType().getBaseType().getDisplayName(), 0));
}
@Override
@@ -79,7 +79,7 @@ class EventTypeTreeItem extends NavTreeItem {
@Override
public TreeItem<NavTreeNode> findTreeItemForEvent(EventBundle t) {
if (t.getType().getBaseType() == getValue().getType().getBaseType()) {
if (t.getEventType().getBaseType() == getValue().getType().getBaseType()) {
for (TreeItem<NavTreeNode> child : getChildren()) {
final TreeItem<NavTreeNode> findTreeItemForEvent = ((NavTreeItem) child).findTreeItemForEvent(t);

View File

@@ -41,9 +41,9 @@ 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.EventBundle;
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewNode;
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
/**
@@ -91,8 +91,8 @@ public class NavPanel extends BorderPane implements TimeLineView {
});
detailViewPane.getSelectedNodes().addListener((Observable observable) -> {
eventsTree.getSelectionModel().clearSelection();
detailViewPane.getSelectedNodes().forEach((DetailViewNode t) -> {
eventsTree.getSelectionModel().select(((NavTreeItem) eventsTree.getRoot()).findTreeItemForEvent(t.getBundleDescriptor()));
detailViewPane.getSelectedNodes().forEach((EventBundle t) -> {
eventsTree.getSelectionModel().select(((NavTreeItem) eventsTree.getRoot()).findTreeItemForEvent(t));
});
});

View File

@@ -59,11 +59,11 @@ class RootItem extends NavTreeItem {
@Override
public void insert(EventCluster g) {
EventTypeTreeItem treeItem = childMap.get(g.getType().getBaseType());
EventTypeTreeItem treeItem = childMap.get(g.getEventType().getBaseType());
if (treeItem == null) {
final EventTypeTreeItem newTreeItem = new EventTypeTreeItem(g);
newTreeItem.setExpanded(true);
childMap.put(g.getType().getBaseType(), newTreeItem);
childMap.put(g.getEventType().getBaseType(), newTreeItem);
newTreeItem.insert(g);
Platform.runLater(() -> {