mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
fix another bug in EventsTree and make it more general (takes TimeLineEvent instead of EventStripe)
This commit is contained in:
parent
2f087fb022
commit
395f248a06
@ -132,6 +132,11 @@ public class EventCluster implements MultiEvent<EventStripe> {
|
|||||||
return Optional.ofNullable(parent);
|
return Optional.ofNullable(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<EventStripe> getParentStripe() {
|
||||||
|
return getParent();
|
||||||
|
}
|
||||||
|
|
||||||
public Interval getSpan() {
|
public Interval getSpan() {
|
||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -50,10 +51,12 @@ public class SingleEvent implements TimeLineEvent {
|
|||||||
private final boolean hashHit;
|
private final boolean hashHit;
|
||||||
private final boolean tagged;
|
private final boolean tagged;
|
||||||
|
|
||||||
|
private MultiEvent<?> parent = null;
|
||||||
|
|
||||||
public SingleEvent(long eventID, long dataSourceID, long objID, @Nullable Long artifactID, long time, EventType type, String fullDescription, String medDescription, String shortDescription, TskData.FileKnown known, boolean hashHit, boolean tagged) {
|
public SingleEvent(long eventID, long dataSourceID, long objID, @Nullable Long artifactID, long time, EventType type, String fullDescription, String medDescription, String shortDescription, TskData.FileKnown known, boolean hashHit, boolean tagged) {
|
||||||
this.eventID = eventID;
|
this.eventID = eventID;
|
||||||
this.fileID = objID;
|
this.fileID = objID;
|
||||||
this.artifactID = artifactID == 0 ? null : artifactID;
|
this.artifactID = (artifactID == null || artifactID == 0) ? null : artifactID;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.subType = type;
|
this.subType = type;
|
||||||
descriptions = ImmutableMap.<DescriptionLoD, String>of(DescriptionLoD.FULL, fullDescription,
|
descriptions = ImmutableMap.<DescriptionLoD, String>of(DescriptionLoD.FULL, fullDescription,
|
||||||
@ -66,6 +69,12 @@ public class SingleEvent implements TimeLineEvent {
|
|||||||
this.dataSourceID = dataSourceID;
|
this.dataSourceID = dataSourceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SingleEvent withParent(MultiEvent<?> newParent) {
|
||||||
|
SingleEvent singleEvent = new SingleEvent(eventID, dataSourceID, fileID, artifactID, time, subType, descriptions.get(DescriptionLoD.FULL), descriptions.get(DescriptionLoD.MEDIUM), descriptions.get(DescriptionLoD.SHORT), known, hashHit, tagged);
|
||||||
|
singleEvent.parent = newParent;
|
||||||
|
return singleEvent;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTagged() {
|
public boolean isTagged() {
|
||||||
return tagged;
|
return tagged;
|
||||||
}
|
}
|
||||||
@ -94,6 +103,7 @@ public class SingleEvent implements TimeLineEvent {
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public EventType getEventType() {
|
public EventType getEventType() {
|
||||||
return subType;
|
return subType;
|
||||||
}
|
}
|
||||||
@ -184,4 +194,15 @@ public class SingleEvent implements TimeLineEvent {
|
|||||||
public DescriptionLoD getDescriptionLoD() {
|
public DescriptionLoD getDescriptionLoD() {
|
||||||
return DescriptionLoD.FULL;
|
return DescriptionLoD.FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<EventStripe> getParentStripe() {
|
||||||
|
if (parent == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else if (parent instanceof EventStripe) {
|
||||||
|
return Optional.of((EventStripe) parent);
|
||||||
|
} else {
|
||||||
|
return parent.getParentStripe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.datamodel;
|
package org.sleuthkit.autopsy.timeline.datamodel;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||||
@ -32,6 +33,8 @@ public interface TimeLineEvent {
|
|||||||
|
|
||||||
public DescriptionLoD getDescriptionLoD();
|
public DescriptionLoD getDescriptionLoD();
|
||||||
|
|
||||||
|
public Optional<EventStripe> getParentStripe();
|
||||||
|
|
||||||
Set<Long> getEventIDs();
|
Set<Long> getEventIDs();
|
||||||
|
|
||||||
Set<Long> getEventIDsWithHashHits();
|
Set<Long> getEventIDsWithHashHits();
|
||||||
|
@ -114,8 +114,11 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventStr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableList<EventStripe> getAllEventStripes() {
|
/*
|
||||||
return chart.getAllNestedEventStripes();
|
* gets the tree of event stripes flattened into a list
|
||||||
|
*/
|
||||||
|
public ObservableList<TimeLineEvent> getAllNestedEvents() {
|
||||||
|
return chart.getAllNestedEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableList<TimeLineEvent> getSelectedEvents() {
|
public ObservableList<TimeLineEvent> getSelectedEvents() {
|
||||||
|
@ -66,7 +66,7 @@ public final class DetailsChart extends Control implements TimeLineChart<DateTim
|
|||||||
private final ObservableList<EventNodeBase<?>> selectedNodes;
|
private final ObservableList<EventNodeBase<?>> selectedNodes;
|
||||||
private final DetailsChartLayoutSettings layoutSettings = new DetailsChartLayoutSettings();
|
private final DetailsChartLayoutSettings layoutSettings = new DetailsChartLayoutSettings();
|
||||||
private final TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
private final ObservableList<EventStripe> nestedEventStripes = FXCollections.observableArrayList();
|
private final ObservableList<TimeLineEvent> nestedEvents = FXCollections.observableArrayList();
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private final ObservableList<EventStripe> eventStripes = FXCollections.observableArrayList();
|
private final ObservableList<EventStripe> eventStripes = FXCollections.observableArrayList();
|
||||||
@ -103,7 +103,7 @@ public final class DetailsChart extends Control implements TimeLineChart<DateTim
|
|||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
void addStripe(EventStripe stripe) {
|
void addStripe(EventStripe stripe) {
|
||||||
eventStripes.add(stripe);
|
eventStripes.add(stripe);
|
||||||
nestedEventStripes.add(stripe);
|
nestedEvents.add(stripe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearGuideLines() {
|
void clearGuideLines() {
|
||||||
@ -129,11 +129,14 @@ public final class DetailsChart extends Control implements TimeLineChart<DateTim
|
|||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
void reset() {
|
void reset() {
|
||||||
eventStripes.clear();
|
eventStripes.clear();
|
||||||
nestedEventStripes.clear();
|
nestedEvents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableList<EventStripe> getAllNestedEventStripes() {
|
/*
|
||||||
return nestedEventStripes;
|
* gets the tree of event stripes flattened into a list
|
||||||
|
*/
|
||||||
|
public ObservableList<TimeLineEvent> getAllNestedEvents() {
|
||||||
|
return nestedEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DetailIntervalSelector extends IntervalSelector<DateTime> {
|
private static class DetailIntervalSelector extends IntervalSelector<DateTime> {
|
||||||
@ -279,7 +282,7 @@ public final class DetailsChart extends Control implements TimeLineChart<DateTim
|
|||||||
DescriptionFilter descriptionFilter = chart.getController().getQuickHideFilters().stream()
|
DescriptionFilter descriptionFilter = chart.getController().getQuickHideFilters().stream()
|
||||||
.filter(testFilter::equals)
|
.filter(testFilter::equals)
|
||||||
.findFirst().orElseGet(() -> {
|
.findFirst().orElseGet(() -> {
|
||||||
testFilter.selectedProperty().addListener(observable -> chart.requestLayout());
|
testFilter.selectedProperty().addListener(observable -> chart.requestLayout());
|
||||||
chart.getController().getQuickHideFilters().add(testFilter);
|
chart.getController().getQuickHideFilters().add(testFilter);
|
||||||
return testFilter;
|
return testFilter;
|
||||||
});
|
});
|
||||||
|
@ -166,15 +166,16 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
List<EventStripe> newSubStripes = get();
|
List<EventStripe> newSubStripes = get();
|
||||||
|
|
||||||
//clear the existing subnodes
|
//clear the existing subnodes
|
||||||
List<TimeLineEvent> oldSubStripes = subNodes.stream().flatMap(new StripeFlattener()).collect(Collectors.toList());
|
List<TimeLineEvent> oldSubEvents = subNodes.stream().flatMap(new StripeFlattener()).collect(Collectors.toList());
|
||||||
getChartLane().getParentChart().getAllNestedEventStripes().removeAll(oldSubStripes);
|
getChartLane().getParentChart().getAllNestedEvents().removeAll(oldSubEvents);
|
||||||
subNodes.clear();
|
subNodes.clear();
|
||||||
if (newSubStripes.isEmpty()) {
|
if (newSubStripes.isEmpty()) {
|
||||||
getChildren().setAll(subNodePane, infoHBox);
|
getChildren().setAll(subNodePane, infoHBox);
|
||||||
setDescriptionLOD(getEvent().getDescriptionLoD());
|
setDescriptionLOD(getEvent().getDescriptionLoD());
|
||||||
} else {
|
} else {
|
||||||
getChartLane().getParentChart().getAllNestedEventStripes().addAll(newSubStripes);
|
|
||||||
subNodes.addAll(Lists.transform(newSubStripes, EventClusterNode.this::createChildNode));
|
subNodes.addAll(Lists.transform(newSubStripes, EventClusterNode.this::createChildNode));
|
||||||
|
List<TimeLineEvent> newSubEvents = subNodes.stream().flatMap(new StripeFlattener()).collect(Collectors.toList());
|
||||||
|
getChartLane().getParentChart().getAllNestedEvents().addAll(newSubEvents);
|
||||||
getChildren().setAll(new VBox(infoHBox, subNodePane));
|
getChildren().setAll(new VBox(infoHBox, subNodePane));
|
||||||
setDescriptionLOD(loadedDescriptionLoD);
|
setDescriptionLOD(loadedDescriptionLoD);
|
||||||
}
|
}
|
||||||
@ -195,7 +196,7 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
@Override
|
@Override
|
||||||
EventNodeBase<?> createChildNode(EventStripe stripe) {
|
EventNodeBase<?> createChildNode(EventStripe stripe) {
|
||||||
if (stripe.getEventIDs().size() == 1) {
|
if (stripe.getEventIDs().size() == 1) {
|
||||||
return new SingleEventNode(getChartLane(), getChartLane().getController().getEventsModel().getEventById(Iterables.getOnlyElement(stripe.getEventIDs())), this);
|
return new SingleEventNode(getChartLane(), getChartLane().getController().getEventsModel().getEventById(Iterables.getOnlyElement(stripe.getEventIDs())).withParent(stripe), this);
|
||||||
} else {
|
} else {
|
||||||
return new EventStripeNode(getChartLane(), stripe, this);
|
return new EventStripeNode(getChartLane(), stripe, this);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ final public class EventStripeNode extends MultiEventNodeBase<EventStripe, Event
|
|||||||
@Override
|
@Override
|
||||||
EventNodeBase<?> createChildNode(EventCluster cluster) {
|
EventNodeBase<?> createChildNode(EventCluster cluster) {
|
||||||
if (cluster.getEventIDs().size() == 1) {
|
if (cluster.getEventIDs().size() == 1) {
|
||||||
return new SingleEventNode(getChartLane(), getChartLane().getController().getEventsModel().getEventById(Iterables.getOnlyElement(cluster.getEventIDs())), this);
|
return new SingleEventNode(getChartLane(), getChartLane().getController().getEventsModel().getEventById(Iterables.getOnlyElement(cluster.getEventIDs())).withParent(cluster), this);
|
||||||
} else {
|
} else {
|
||||||
return new EventClusterNode(getChartLane(), cluster, this);
|
return new EventClusterNode(getChartLane(), cluster, this);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import java.util.Deque;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||||
|
|
||||||
@ -32,14 +31,14 @@ import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
|||||||
*/
|
*/
|
||||||
class BaseTypeTreeItem extends EventTypeTreeItem<EventsTreeItem> {
|
class BaseTypeTreeItem extends EventTypeTreeItem<EventsTreeItem> {
|
||||||
|
|
||||||
BaseTypeTreeItem(EventStripe stripe, Comparator<TreeItem<TimeLineEvent>> comp) {
|
BaseTypeTreeItem(TimeLineEvent stripe, Comparator<TreeItem<TimeLineEvent>> comp) {
|
||||||
super(stripe.getEventType().getBaseType(), comp);
|
super(stripe.getEventType().getBaseType(), comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
@Override
|
@Override
|
||||||
public void insert(Deque<EventStripe> path) {
|
public void insert(Deque<TimeLineEvent> path) {
|
||||||
EventStripe peek = path.peek();
|
TimeLineEvent peek = path.peek();
|
||||||
Supplier< EventsTreeItem> treeItemConstructor;
|
Supplier< EventsTreeItem> treeItemConstructor;
|
||||||
String descriptionKey;
|
String descriptionKey;
|
||||||
/*
|
/*
|
||||||
@ -51,7 +50,7 @@ class BaseTypeTreeItem extends EventTypeTreeItem<EventsTreeItem> {
|
|||||||
treeItemConstructor = () -> configureNewTreeItem(new SubTypeTreeItem(peek, getComparator()));
|
treeItemConstructor = () -> configureNewTreeItem(new SubTypeTreeItem(peek, getComparator()));
|
||||||
} else {
|
} else {
|
||||||
descriptionKey = peek.getDescription();
|
descriptionKey = peek.getDescription();
|
||||||
EventStripe stripe = path.removeFirst();
|
TimeLineEvent stripe = path.removeFirst();
|
||||||
treeItemConstructor = () -> configureNewTreeItem(new EventDescriptionTreeItem(stripe, getComparator()));
|
treeItemConstructor = () -> configureNewTreeItem(new EventDescriptionTreeItem(stripe, getComparator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,9 +63,9 @@ class BaseTypeTreeItem extends EventTypeTreeItem<EventsTreeItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void remove(Deque<EventStripe> path) {
|
void remove(Deque<TimeLineEvent> path) {
|
||||||
|
|
||||||
EventStripe head = path.peek();
|
TimeLineEvent head = path.peek();
|
||||||
|
|
||||||
EventsTreeItem descTreeItem;
|
EventsTreeItem descTreeItem;
|
||||||
if (head.getEventType().getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) {
|
if (head.getEventType().getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) {
|
||||||
|
@ -40,14 +40,14 @@ class EventDescriptionTreeItem extends EventsTreeItem {
|
|||||||
*/
|
*/
|
||||||
private final Map<String, EventDescriptionTreeItem> childMap = new HashMap<>();
|
private final Map<String, EventDescriptionTreeItem> childMap = new HashMap<>();
|
||||||
|
|
||||||
EventDescriptionTreeItem(EventStripe stripe, Comparator<TreeItem<TimeLineEvent>> comp) {
|
EventDescriptionTreeItem(TimeLineEvent stripe, Comparator<TreeItem<TimeLineEvent>> comp) {
|
||||||
super(comp);
|
super(comp);
|
||||||
setValue(stripe);
|
setValue(stripe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
public void insert(Deque<EventStripe> path) {
|
public void insert(Deque<TimeLineEvent> path) {
|
||||||
EventStripe head = path.removeFirst();
|
TimeLineEvent head = path.removeFirst();
|
||||||
String substringAfter = StringUtils.substringAfter(head.getDescription(), head.getParentStripe().map(EventStripe::getDescription).orElse(""));
|
String substringAfter = StringUtils.substringAfter(head.getDescription(), head.getParentStripe().map(EventStripe::getDescription).orElse(""));
|
||||||
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(substringAfter,
|
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(substringAfter,
|
||||||
description -> configureNewTreeItem(new EventDescriptionTreeItem(head, getComparator()))
|
description -> configureNewTreeItem(new EventDescriptionTreeItem(head, getComparator()))
|
||||||
@ -59,16 +59,19 @@ class EventDescriptionTreeItem extends EventsTreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void remove(Deque<EventStripe> path) {
|
void remove(Deque<TimeLineEvent> path) {
|
||||||
EventStripe head = path.removeFirst();
|
TimeLineEvent head = path.removeFirst();
|
||||||
String substringAfter = StringUtils.substringAfter(head.getDescription(), head.getParentStripe().map(EventStripe::getDescription).orElse(""));
|
String substringAfter = StringUtils.substringAfter(head.getDescription(), head.getParentStripe().map(EventStripe::getDescription).orElse(""));
|
||||||
EventDescriptionTreeItem descTreeItem = childMap.get(substringAfter);
|
EventDescriptionTreeItem descTreeItem = childMap.get(substringAfter);
|
||||||
if (path.isEmpty() == false) {
|
|
||||||
descTreeItem.remove(path);
|
if (descTreeItem != null) {
|
||||||
}
|
if (path.isEmpty() == false) {
|
||||||
if (descTreeItem.getChildren().isEmpty()) {
|
descTreeItem.remove(path);
|
||||||
childMap.remove(head.getDescription());
|
}
|
||||||
getChildren().remove(descTreeItem);
|
if (descTreeItem.getChildren().isEmpty()) {
|
||||||
|
childMap.remove(substringAfter);
|
||||||
|
getChildren().remove(descTreeItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* Autopsy Forensic Browser
|
||||||
* To change this template file, choose Tools | Templates
|
*
|
||||||
* and open the template in the editor.
|
* Copyright 2016 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.detailview.tree;
|
package org.sleuthkit.autopsy.timeline.ui.detailview.tree;
|
||||||
|
|
||||||
@ -13,7 +26,7 @@ import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
|||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* EventTreeItem for event types
|
||||||
*/
|
*/
|
||||||
abstract class EventTypeTreeItem<T extends EventsTreeItem> extends EventsTreeItem {
|
abstract class EventTypeTreeItem<T extends EventsTreeItem> extends EventsTreeItem {
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ final public class EventsTree extends BorderPane {
|
|||||||
public void setDetailViewPane(DetailViewPane detailViewPane) {
|
public void setDetailViewPane(DetailViewPane detailViewPane) {
|
||||||
this.detailViewPane = detailViewPane;
|
this.detailViewPane = detailViewPane;
|
||||||
|
|
||||||
detailViewPane.getAllEventStripes().addListener((ListChangeListener.Change<? extends EventStripe> c) -> {
|
detailViewPane.getAllNestedEvents().addListener((ListChangeListener.Change<? extends TimeLineEvent> c) -> {
|
||||||
//on jfx thread
|
//on jfx thread
|
||||||
while (c.next()) {
|
while (c.next()) {
|
||||||
c.getRemoved().forEach(getRoot()::remove);
|
c.getRemoved().forEach(getRoot()::remove);
|
||||||
@ -112,7 +112,7 @@ final public class EventsTree extends BorderPane {
|
|||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private void setRoot() {
|
private void setRoot() {
|
||||||
RootItem root = new RootItem(TreeComparator.Type.reversed().thenComparing(sortByBox.getSelectionModel().getSelectedItem()));
|
RootItem root = new RootItem(TreeComparator.Type.reversed().thenComparing(sortByBox.getSelectionModel().getSelectedItem()));
|
||||||
detailViewPane.getAllEventStripes().forEach(root::insert);
|
detailViewPane.getAllNestedEvents().forEach(root::insert);
|
||||||
eventsTree.setRoot(root);
|
eventsTree.setRoot(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2014-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.timeline.ui.detailview.tree;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||||
|
|
||||||
@ -58,9 +57,9 @@ abstract class EventsTreeItem extends TreeItem<TimeLineEvent> {
|
|||||||
|
|
||||||
abstract EventType getEventType();
|
abstract EventType getEventType();
|
||||||
|
|
||||||
abstract void remove(Deque<EventStripe> path);
|
abstract void remove(Deque<TimeLineEvent> path);
|
||||||
|
|
||||||
abstract void insert(Deque<EventStripe> path);
|
abstract void insert(Deque<TimeLineEvent> path);
|
||||||
|
|
||||||
<T extends EventsTreeItem> T configureNewTreeItem(T newTreeItem) {
|
<T extends EventsTreeItem> T configureNewTreeItem(T newTreeItem) {
|
||||||
newTreeItem.setExpanded(true);
|
newTreeItem.setExpanded(true);
|
||||||
|
@ -50,7 +50,7 @@ class RootItem extends EventsTreeItem {
|
|||||||
* @param stripe stripe to add
|
* @param stripe stripe to add
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
public void insert(EventStripe stripe) {
|
public void insert(TimeLineEvent stripe) {
|
||||||
|
|
||||||
BaseTypeTreeItem treeItem = childMap.computeIfAbsent(stripe.getEventType().getBaseType(),
|
BaseTypeTreeItem treeItem = childMap.computeIfAbsent(stripe.getEventType().getBaseType(),
|
||||||
baseType -> configureNewTreeItem(new BaseTypeTreeItem(stripe, getComparator()))
|
baseType -> configureNewTreeItem(new BaseTypeTreeItem(stripe, getComparator()))
|
||||||
@ -58,7 +58,7 @@ class RootItem extends EventsTreeItem {
|
|||||||
treeItem.insert(getTreePath(stripe));
|
treeItem.insert(getTreePath(stripe));
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(EventStripe stripe) {
|
void remove(TimeLineEvent stripe) {
|
||||||
BaseTypeTreeItem typeTreeItem = childMap.get(stripe.getEventType().getBaseType());
|
BaseTypeTreeItem typeTreeItem = childMap.get(stripe.getEventType().getBaseType());
|
||||||
if (typeTreeItem != null) {
|
if (typeTreeItem != null) {
|
||||||
typeTreeItem.remove(getTreePath(stripe));
|
typeTreeItem.remove(getTreePath(stripe));
|
||||||
@ -70,8 +70,8 @@ class RootItem extends EventsTreeItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Deque< EventStripe> getTreePath(EventStripe event) {
|
static Deque< TimeLineEvent> getTreePath(TimeLineEvent event) {
|
||||||
Deque<EventStripe> path = new ArrayDeque<>();
|
Deque<TimeLineEvent> path = new ArrayDeque<>();
|
||||||
path.addFirst(event);
|
path.addFirst(event);
|
||||||
Optional<EventStripe> parentOptional = event.getParentStripe();
|
Optional<EventStripe> parentOptional = event.getParentStripe();
|
||||||
while (parentOptional.isPresent()) {
|
while (parentOptional.isPresent()) {
|
||||||
@ -110,12 +110,12 @@ class RootItem extends EventsTreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void remove(Deque<EventStripe> path) {
|
void remove(Deque<TimeLineEvent> path) {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void insert(Deque<EventStripe> path) {
|
void insert(Deque<TimeLineEvent> path) {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* Autopsy Forensic Browser
|
||||||
* To change this template file, choose Tools | Templates
|
*
|
||||||
* and open the template in the editor.
|
* Copyright 2013-16 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.detailview.tree;
|
package org.sleuthkit.autopsy.timeline.ui.detailview.tree;
|
||||||
|
|
||||||
@ -9,18 +22,20 @@ import java.util.Comparator;
|
|||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventTreeItem for sub event types
|
||||||
|
*/
|
||||||
public class SubTypeTreeItem extends EventTypeTreeItem<EventDescriptionTreeItem> {
|
public class SubTypeTreeItem extends EventTypeTreeItem<EventDescriptionTreeItem> {
|
||||||
|
|
||||||
SubTypeTreeItem(EventStripe stripe, Comparator<TreeItem<TimeLineEvent>> comp) {
|
SubTypeTreeItem(TimeLineEvent stripe, Comparator<TreeItem<TimeLineEvent>> comp) {
|
||||||
super(stripe.getEventType(), comp);
|
super(stripe.getEventType(), comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
public void insert(Deque<EventStripe> path) {
|
public void insert(Deque<TimeLineEvent> path) {
|
||||||
EventStripe head = path.removeFirst();
|
TimeLineEvent head = path.removeFirst();
|
||||||
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(head.getDescription(),
|
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(head.getDescription(),
|
||||||
description -> configureNewTreeItem(new EventDescriptionTreeItem(head, getComparator()))
|
description -> configureNewTreeItem(new EventDescriptionTreeItem(head, getComparator()))
|
||||||
);
|
);
|
||||||
@ -31,8 +46,8 @@ public class SubTypeTreeItem extends EventTypeTreeItem<EventDescriptionTreeItem>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void remove(Deque<EventStripe> path) {
|
void remove(Deque<TimeLineEvent> path) {
|
||||||
EventStripe head = path.removeFirst();
|
TimeLineEvent head = path.removeFirst();
|
||||||
EventsTreeItem descTreeItem = childMap.get(head.getDescription());
|
EventsTreeItem descTreeItem = childMap.get(head.getDescription());
|
||||||
if (descTreeItem != null) {
|
if (descTreeItem != null) {
|
||||||
if (path.isEmpty() == false) {
|
if (path.isEmpty() == false) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user