mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
layout optimization WIP
This commit is contained in:
parent
d6543dd967
commit
31cc6ebb95
@ -87,7 +87,7 @@ public interface ArtifactEventType extends EventType {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* bundles the per event information derived from a BlackBoard Artifact into
|
* bundles the per event information derived from a BlackBoard Artifact into
|
||||||
* one object. Primarily used to have a single return value for {@link SubType#buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact).
|
* one object. Primarily used to have a single return value for null {@link SubType#buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact).
|
||||||
*/
|
*/
|
||||||
static class AttributeEventDescription {
|
static class AttributeEventDescription {
|
||||||
|
|
||||||
@ -187,6 +187,8 @@ public interface ArtifactEventType extends EventType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class EmptyExtractor implements BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> {
|
public static class EmptyExtractor implements BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
|
package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
|
||||||
|
|
||||||
|
import com.google.common.net.InternetDomainName;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -38,7 +39,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
"downloads.png", // NON-NLS
|
"downloads.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)) {
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)) {
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
"cookies.png", // NON-NLS
|
"cookies.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)),
|
||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
@ -75,7 +76,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
"bookmarks.png", // NON-NLS
|
"bookmarks.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
@ -83,7 +84,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
"history.png", // NON-NLS
|
"history.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
@ -92,7 +93,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY,
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT),
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
|
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
|
||||||
|
|
||||||
private final BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType;
|
private final BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType;
|
||||||
@ -186,4 +187,30 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TopPrivateDomainExtractor extends AttributeExtractor {
|
||||||
|
|
||||||
|
final private static TopPrivateDomainExtractor instance = new TopPrivateDomainExtractor();
|
||||||
|
|
||||||
|
static TopPrivateDomainExtractor getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
|
||||||
|
String domainString = StringUtils.substringBefore(super.apply(artf, attrMap), "/");
|
||||||
|
if (InternetDomainName.isValid(domainString)) {
|
||||||
|
InternetDomainName domain = InternetDomainName.from(domainString);
|
||||||
|
return (domain.isUnderPublicSuffix())
|
||||||
|
? domain.topPrivateDomain().toString()
|
||||||
|
: domain.toString();
|
||||||
|
} else {
|
||||||
|
return domainString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TopPrivateDomainExtractor() {
|
||||||
|
super(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
|
|||||||
}
|
}
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
setCursor(Cursor.NONE);
|
setCursor(Cursor.DEFAULT);
|
||||||
layoutDateLabels();
|
layoutDateLabels();
|
||||||
updateProgress(1, 1);
|
updateProgress(1, 1);
|
||||||
});
|
});
|
||||||
|
@ -27,11 +27,11 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javafx.beans.Observable;
|
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Orientation;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
@ -126,7 +126,6 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
this.eventBundle = eventBundle;
|
this.eventBundle = eventBundle;
|
||||||
this.parentNode = parentNode;
|
this.parentNode = parentNode;
|
||||||
this.chart = chart;
|
this.chart = chart;
|
||||||
|
|
||||||
this.descLOD.set(eventBundle.getDescriptionLoD());
|
this.descLOD.set(eventBundle.getDescriptionLoD());
|
||||||
sleuthkitCase = chart.getController().getAutopsyCase().getSleuthkitCase();
|
sleuthkitCase = chart.getController().getAutopsyCase().getSleuthkitCase();
|
||||||
eventsModel = chart.getController().getEventsModel();
|
eventsModel = chart.getController().getEventsModel();
|
||||||
@ -145,22 +144,24 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
setAlignment(Pos.TOP_LEFT);
|
setAlignment(Pos.TOP_LEFT);
|
||||||
|
|
||||||
setPrefHeight(USE_COMPUTED_SIZE);
|
setPrefHeight(USE_COMPUTED_SIZE);
|
||||||
heightProperty().addListener((Observable observable) -> {
|
heightProperty().addListener(heightProp -> {
|
||||||
chart.layoutPlotChildren();
|
chart.requestChartLayout();
|
||||||
});
|
});
|
||||||
setMaxHeight(USE_PREF_SIZE);
|
setMaxHeight(USE_PREF_SIZE);
|
||||||
|
setMinWidth(USE_PREF_SIZE);
|
||||||
setMaxWidth(USE_PREF_SIZE);
|
setMaxWidth(USE_PREF_SIZE);
|
||||||
setLayoutX(chart.getXAxis().getDisplayPosition(new DateTime(eventBundle.getStartMillis())) - getLayoutXCompensation());
|
setLayoutX(chart.getXAxis().getDisplayPosition(new DateTime(eventBundle.getStartMillis())) - getLayoutXCompensation());
|
||||||
|
|
||||||
//initialize info hbox
|
//initialize info hbox
|
||||||
infoHBox.setMinWidth(USE_PREF_SIZE);
|
infoHBox.setMinWidth(USE_PREF_SIZE);
|
||||||
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
||||||
infoHBox.setPadding(new Insets(2, 5, 2, 5));
|
infoHBox.setPadding(new Insets(2, 3, 2, 3));
|
||||||
infoHBox.setAlignment(Pos.TOP_LEFT);
|
infoHBox.setAlignment(Pos.TOP_LEFT);
|
||||||
|
|
||||||
//set up subnode pane sizing contraints
|
//set up subnode pane sizing contraints
|
||||||
subNodePane.setPrefHeight(USE_COMPUTED_SIZE);
|
subNodePane.setPrefHeight(USE_COMPUTED_SIZE);
|
||||||
subNodePane.setMaxHeight(USE_PREF_SIZE);
|
subNodePane.setPrefHeight(USE_COMPUTED_SIZE);
|
||||||
|
subNodePane.setMinHeight(24);
|
||||||
subNodePane.setPrefWidth(USE_COMPUTED_SIZE);
|
subNodePane.setPrefWidth(USE_COMPUTED_SIZE);
|
||||||
subNodePane.setMinWidth(USE_PREF_SIZE);
|
subNodePane.setMinWidth(USE_PREF_SIZE);
|
||||||
subNodePane.setMaxWidth(USE_PREF_SIZE);
|
subNodePane.setMaxWidth(USE_PREF_SIZE);
|
||||||
@ -177,7 +178,6 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
Tooltip.uninstall(chart, AbstractVisualizationPane.getDragTooltip());
|
Tooltip.uninstall(chart, AbstractVisualizationPane.getDragTooltip());
|
||||||
showHoverControls(true);
|
showHoverControls(true);
|
||||||
toFront();
|
toFront();
|
||||||
|
|
||||||
});
|
});
|
||||||
setOnMouseExited((MouseEvent event) -> {
|
setOnMouseExited((MouseEvent event) -> {
|
||||||
showHoverControls(false);
|
showHoverControls(false);
|
||||||
@ -269,7 +269,7 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
new Thread(tooltTipTask).start();
|
||||||
chart.getController().monitorTask(tooltTipTask);
|
chart.getController().monitorTask(tooltTipTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,6 +329,11 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
return getEventBundle().getEventIDs();
|
return getEventBundle().getEventIDs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Orientation getContentBias() {
|
||||||
|
return Orientation.HORIZONTAL;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void layoutChildren() {
|
protected void layoutChildren() {
|
||||||
chart.layoutEventBundleNodes(subNodes, 0);
|
chart.layoutEventBundleNodes(subNodes, 0);
|
||||||
|
@ -114,7 +114,7 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
||||||
final int size = getEventBundle().getEventIDs().size();
|
final int size = getEventBundle().getEventIDs().size();
|
||||||
switch (descrVis) {
|
switch (descrVis) {
|
||||||
case HIDDEN:
|
case HIDDEN:
|
||||||
@ -212,11 +212,12 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error loading subnodes", ex);
|
LOGGER.log(Level.SEVERE, "Error loading subnodes", ex);
|
||||||
}
|
}
|
||||||
chart.layoutPlotChildren();
|
chart.requestChartLayout();
|
||||||
chart.setCursor(null);
|
chart.setCursor(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
new Thread(loggedTask).start();
|
||||||
//start task
|
//start task
|
||||||
chart.getController().monitorTask(loggedTask);
|
chart.getController().monitorTask(loggedTask);
|
||||||
}
|
}
|
||||||
@ -233,8 +234,7 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
protected void layoutChildren() {
|
protected void layoutChildren() {
|
||||||
double chartX = chart.getXAxis().getDisplayPosition(new DateTime(getStartMillis()));
|
double chartX = chart.getXAxis().getDisplayPosition(new DateTime(getStartMillis()));
|
||||||
double w = chart.getXAxis().getDisplayPosition(new DateTime(getEndMillis())) - chartX;
|
double w = chart.getXAxis().getDisplayPosition(new DateTime(getEndMillis())) - chartX;
|
||||||
subNodePane.setPrefWidth(w);
|
subNodePane.setPrefWidth(Math.max(1, w));
|
||||||
subNodePane.setMinWidth(Math.max(1, w));
|
|
||||||
super.layoutChildren();
|
super.layoutChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -103,14 +104,11 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
private static final int PROJECTED_LINE_STROKE_WIDTH = 5;
|
private static final int PROJECTED_LINE_STROKE_WIDTH = 5;
|
||||||
private static final int MINIMUM_EVENT_NODE_GAP = 4;
|
private static final int MINIMUM_EVENT_NODE_GAP = 4;
|
||||||
|
|
||||||
|
|
||||||
private final TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
private final FilteredEventsModel filteredEvents;
|
private final FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
private ContextMenu chartContextMenu;
|
private ContextMenu chartContextMenu;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ContextMenu getChartContextMenu() {
|
public ContextMenu getChartContextMenu() {
|
||||||
return chartContextMenu;
|
return chartContextMenu;
|
||||||
}
|
}
|
||||||
@ -204,7 +202,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
});
|
});
|
||||||
Tooltip.install(this, AbstractVisualizationPane.getDragTooltip());
|
Tooltip.install(this, AbstractVisualizationPane.getDragTooltip());
|
||||||
|
|
||||||
|
|
||||||
dateAxis.setAutoRanging(false);
|
dateAxis.setAutoRanging(false);
|
||||||
|
|
||||||
verticalAxis.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
|
||||||
@ -342,7 +339,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
stripeNodeMap.put(eventStripe, stripeNode);
|
stripeNodeMap.put(eventStripe, stripeNode);
|
||||||
nodeGroup.getChildren().add(stripeNode);
|
nodeGroup.getChildren().add(stripeNode);
|
||||||
data.setNode(stripeNode);
|
data.setNode(stripeNode);
|
||||||
layoutPlotChildren();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -359,7 +355,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
EventStripeNode removedNode = stripeNodeMap.remove(removedStripe);
|
EventStripeNode removedNode = stripeNodeMap.remove(removedStripe);
|
||||||
nodeGroup.getChildren().remove(removedNode);
|
nodeGroup.getChildren().remove(removedNode);
|
||||||
data.setNode(null);
|
data.setNode(null);
|
||||||
layoutPlotChildren();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -463,48 +458,42 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
* @param nodes collection of nodes to layout
|
* @param nodes collection of nodes to layout
|
||||||
* @param minY the minimum y coordinate to position the nodes at.
|
* @param minY the minimum y coordinate to position the nodes at.
|
||||||
*/
|
*/
|
||||||
synchronized double layoutEventBundleNodes(final Collection<? extends EventBundleNodeBase<?, ?, ?>> nodes, final double minY) {
|
double layoutEventBundleNodes(final Collection<? extends EventBundleNodeBase<?, ?, ?>> nodes, final double minY) {
|
||||||
// map from y value (ranges) to right most occupied x value.
|
|
||||||
TreeRangeMap<Double, Double> treeRangeMap = TreeRangeMap.create();
|
TreeRangeMap<Double, Double> treeRangeMap = TreeRangeMap.create();
|
||||||
// maximum y values occupied by any of the given nodes, updated as nodes are layed out.
|
// maximum y values occupied by any of the given nodes, updated as nodes are layed out.
|
||||||
double localMax = minY;
|
double localMax = minY;
|
||||||
|
|
||||||
|
Set<String> activeQuickHidefilters = getController().getQuickHideFilters().stream()
|
||||||
|
.filter(AbstractFilter::isActive)
|
||||||
|
.map(DescriptionFilter::getDescription)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
//for each node do a recursive layout to size it and then position it in first available slot
|
//for each node do a recursive layout to size it and then position it in first available slot
|
||||||
for (final EventBundleNodeBase<?, ?, ?> bundleNode : nodes) {
|
for (EventBundleNodeBase<?, ?, ?> bundleNode : nodes) {
|
||||||
//is the node hiden by a quick hide filter?
|
//is the node hiden by a quick hide filter?
|
||||||
boolean quickHide = getController().getQuickHideFilters().stream()
|
boolean quickHide = activeQuickHidefilters.contains(bundleNode.getDescription());
|
||||||
.filter(AbstractFilter::isActive)
|
|
||||||
.anyMatch(filter -> filter.getDescription().equals(bundleNode.getDescription()));
|
|
||||||
if (quickHide) {
|
if (quickHide) {
|
||||||
//hide it and skip layout
|
//hide it and skip layout
|
||||||
bundleNode.setVisible(false);
|
bundleNode.setVisible(false);
|
||||||
bundleNode.setManaged(false);
|
bundleNode.setManaged(false);
|
||||||
} else {
|
} else {
|
||||||
//make sure it is shown
|
bundleLayoutHelper(bundleNode);
|
||||||
bundleNode.setVisible(true);
|
|
||||||
bundleNode.setManaged(true);
|
|
||||||
//apply advanced layout description visibility options
|
|
||||||
bundleNode.setDescriptionVisibility(descrVisibility.get());
|
|
||||||
bundleNode.setDescriptionWidth(truncateAll.get() ? truncateWidth.get() : USE_PREF_SIZE);
|
|
||||||
|
|
||||||
//do recursive layout
|
|
||||||
bundleNode.layout();
|
|
||||||
//get computed height and width
|
//get computed height and width
|
||||||
double h = bundleNode.getBoundsInLocal().getHeight();
|
double h = bundleNode.getBoundsInLocal().getHeight();
|
||||||
double w = bundleNode.getBoundsInLocal().getWidth();
|
double w = bundleNode.getBoundsInLocal().getWidth();
|
||||||
//get left and right x coords from axis plus computed width
|
//get left and right x coords from axis plus computed width
|
||||||
double xLeft = getXForEpochMillis(bundleNode.getStartMillis()) - bundleNode.getLayoutXCompensation();
|
double xLeft = getXForEpochMillis(bundleNode.getStartMillis()) - bundleNode.getLayoutXCompensation();
|
||||||
double xRight = xLeft + w;
|
double xRight = xLeft + w + MINIMUM_EVENT_NODE_GAP;
|
||||||
|
|
||||||
//initial test position
|
//initial test position
|
||||||
double yTop = minY;
|
double yTop = minY;
|
||||||
double yBottom = yTop + h;
|
|
||||||
|
|
||||||
if (oneEventPerRow.get()) {
|
if (oneEventPerRow.get()) {
|
||||||
// if onePerRow, just put it at end
|
// if onePerRow, just put it at end
|
||||||
yTop = (localMax + MINIMUM_EVENT_NODE_GAP);
|
yTop = (localMax + MINIMUM_EVENT_NODE_GAP);
|
||||||
yBottom = yTop + h;
|
|
||||||
} else {
|
} else {
|
||||||
|
double yBottom = yTop + h;
|
||||||
|
|
||||||
//until the node is not overlapping any others try moving it down.
|
//until the node is not overlapping any others try moving it down.
|
||||||
boolean overlapping = true;
|
boolean overlapping = true;
|
||||||
while (overlapping) {
|
while (overlapping) {
|
||||||
@ -525,21 +514,42 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
treeRangeMap.put(Range.closed(yTop, yBottom), xRight);
|
treeRangeMap.put(Range.closed(yTop, yBottom), xRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
localMax = Math.max(yBottom, localMax);
|
localMax = Math.max(yTop + h, localMax);
|
||||||
|
|
||||||
//animate node to new position
|
if ((xLeft != bundleNode.getLayoutX()) || (yTop != bundleNode.getLayoutY())) {
|
||||||
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(100),
|
|
||||||
new KeyValue(bundleNode.layoutXProperty(), xLeft),
|
//animate node to new position
|
||||||
new KeyValue(bundleNode.layoutYProperty(), yTop)));
|
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(100),
|
||||||
timeline.setOnFinished((ActionEvent event) -> {
|
new KeyValue(bundleNode.layoutXProperty(), xLeft),
|
||||||
requestChartLayout();
|
new KeyValue(bundleNode.layoutYProperty(), yTop))
|
||||||
});
|
);
|
||||||
timeline.play();
|
timeline.setOnFinished((ActionEvent event) -> {
|
||||||
|
requestChartLayout();
|
||||||
|
});
|
||||||
|
timeline.play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return localMax; //return new max
|
return localMax; //return new max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void bundleLayoutHelper(final EventBundleNodeBase<?, ?, ?> bundleNode) {
|
||||||
|
//make sure it is shown
|
||||||
|
bundleNode.setVisible(true);
|
||||||
|
bundleNode.setManaged(true);
|
||||||
|
//apply advanced layout description visibility options
|
||||||
|
bundleNode.setDescriptionVisibility(descrVisibility.get());
|
||||||
|
bundleNode.setDescriptionWidth(truncateAll.get() ? truncateWidth.get() : USE_PREF_SIZE);
|
||||||
|
|
||||||
|
//do recursive layout
|
||||||
|
bundleNode.layoutChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestChartLayout() {
|
||||||
|
super.requestChartLayout(); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
private double getXForEpochMillis(Long millis) {
|
private double getXForEpochMillis(Long millis) {
|
||||||
DateTime dateTime = new DateTime(millis, TimeLineController.getJodaTimeZone());
|
DateTime dateTime = new DateTime(millis, TimeLineController.getJodaTimeZone());
|
||||||
return getXAxis().getDisplayPosition(new DateTime(dateTime));
|
return getXAxis().getDisplayPosition(new DateTime(dateTime));
|
||||||
@ -568,6 +578,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
*/
|
*/
|
||||||
public FilteredEventsModel getFilteredEvents() {
|
public FilteredEventsModel getFilteredEvents() {
|
||||||
return filteredEvents;
|
return filteredEvents;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static private class DetailIntervalSelector extends IntervalSelector<DateTime> {
|
static private class DetailIntervalSelector extends IntervalSelector<DateTime> {
|
||||||
@ -673,7 +684,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
.filter(testFilter::equals)
|
.filter(testFilter::equals)
|
||||||
.findFirst().orElseGet(() -> {
|
.findFirst().orElseGet(() -> {
|
||||||
testFilter.selectedProperty().addListener((Observable observable) -> {
|
testFilter.selectedProperty().addListener((Observable observable) -> {
|
||||||
layoutPlotChildren();
|
requestChartLayout();
|
||||||
});
|
});
|
||||||
getController().getQuickHideFilters().add(testFilter);
|
getController().getQuickHideFilters().add(testFilter);
|
||||||
return testFilter;
|
return testFilter;
|
||||||
|
@ -98,6 +98,8 @@ final public class EventStripeNode extends EventBundleNodeBase<EventStripe, Even
|
|||||||
descrLabel.setMaxWidth(w);
|
descrLabel.setMaxWidth(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apply the 'effect' to visually indicate highlighted nodes
|
* apply the 'effect' to visually indicate highlighted nodes
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Mon, 26 Oct 2015 09:54:05 -0400
|
#Mon, 26 Oct 2015 14:50:57 -0400
|
||||||
LBL_splash_window_title=Starting Autopsy
|
LBL_splash_window_title=Starting Autopsy
|
||||||
SPLASH_HEIGHT=314
|
SPLASH_HEIGHT=314
|
||||||
SPLASH_WIDTH=538
|
SPLASH_WIDTH=538
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Mon, 26 Oct 2015 09:54:05 -0400
|
#Mon, 26 Oct 2015 14:50:57 -0400
|
||||||
CTL_MainWindow_Title=Autopsy 4.0.0
|
CTL_MainWindow_Title=Autopsy 4.0.0
|
||||||
CTL_MainWindow_Title_No_Project=Autopsy 4.0.0
|
CTL_MainWindow_Title_No_Project=Autopsy 4.0.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user