mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
flesh out pinning multievents, and small ui changes to streamline bundles with only one sub-bundle.
move eventTypeImageView into EventNodeBase
This commit is contained in:
parent
64d3f09118
commit
a6bfbf467a
@ -47,7 +47,7 @@ public interface MultiEvent<ParentType extends MultiEvent<?>> extends TimeLineEv
|
|||||||
|
|
||||||
Optional<ParentType> getParentBundle();
|
Optional<ParentType> getParentBundle();
|
||||||
|
|
||||||
default int getCount() {
|
default int getSize() {
|
||||||
return getEventIDs().size();
|
return getEventIDs().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public interface TimeLineEvent {
|
|||||||
|
|
||||||
long getStartMillis();
|
long getStartMillis();
|
||||||
|
|
||||||
default int getCount() {
|
default int getSize() {
|
||||||
return getEventIDs().size();
|
return getEventIDs().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
|||||||
import org.sleuthkit.autopsy.timeline.filters.RootFilter;
|
import org.sleuthkit.autopsy.timeline.filters.RootFilter;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.TypeFilter;
|
import org.sleuthkit.autopsy.timeline.filters.TypeFilter;
|
||||||
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.configureActionButton;
|
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.configureActionButton;
|
||||||
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.show;
|
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
|
import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
|
||||||
@ -72,8 +71,8 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
|
|
||||||
private final Border clusterBorder = new Border(new BorderStroke(evtColor.deriveColor(0, 1, 1, .4), BorderStrokeStyle.SOLID, CORNER_RADII_1, CLUSTER_BORDER_WIDTHS));
|
private final Border clusterBorder = new Border(new BorderStroke(evtColor.deriveColor(0, 1, 1, .4), BorderStrokeStyle.SOLID, CORNER_RADII_1, CLUSTER_BORDER_WIDTHS));
|
||||||
|
|
||||||
private Button plusButton;
|
Button plusButton;
|
||||||
private Button minusButton;
|
Button minusButton;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void installActionButtons() {
|
void installActionButtons() {
|
||||||
@ -81,15 +80,14 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
if (plusButton == null) {
|
if (plusButton == null) {
|
||||||
plusButton = ActionUtils.createButton(new ExpandClusterAction(), ActionUtils.ActionTextBehavior.HIDE);
|
plusButton = ActionUtils.createButton(new ExpandClusterAction(), ActionUtils.ActionTextBehavior.HIDE);
|
||||||
minusButton = ActionUtils.createButton(new CollapseClusterAction(), ActionUtils.ActionTextBehavior.HIDE);
|
minusButton = ActionUtils.createButton(new CollapseClusterAction(), ActionUtils.ActionTextBehavior.HIDE);
|
||||||
infoHBox.getChildren().addAll(minusButton, plusButton);
|
controlsHBox.getChildren().addAll(minusButton, plusButton);
|
||||||
|
|
||||||
configureActionButton(plusButton);
|
configureActionButton(plusButton);
|
||||||
configureActionButton(minusButton);
|
configureActionButton(minusButton);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventClusterNode(DetailsChart chart, EventCluster eventCluster, EventStripeNode parentNode) {
|
EventClusterNode(DetailsChart chart, EventCluster eventCluster, EventStripeNode parentNode) {
|
||||||
super(chart, eventCluster, parentNode);
|
super(chart, eventCluster, parentNode);
|
||||||
|
|
||||||
subNodePane.setBorder(clusterBorder);
|
subNodePane.setBorder(clusterBorder);
|
||||||
@ -102,17 +100,10 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
setCursor(Cursor.HAND);
|
setCursor(Cursor.HAND);
|
||||||
getChildren().addAll(subNodePane, infoHBox);
|
getChildren().addAll(subNodePane, infoHBox);
|
||||||
|
|
||||||
}
|
if (parentNode == null) {
|
||||||
|
|
||||||
@Override
|
setDescriptionVisibiltiyImpl(DescriptionVisibility.SHOWN);
|
||||||
void showHoverControls(final boolean showControls) {
|
}
|
||||||
super.showHoverControls(showControls);
|
|
||||||
installActionButtons();
|
|
||||||
show(plusButton, showControls);
|
|
||||||
show(minusButton, showControls);
|
|
||||||
// if (getEventCluster().getEventIDs().size() == 1) {
|
|
||||||
// show(pinButton, showControls);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -120,14 +111,9 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
// 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
|
|
||||||
void setMaxDescriptionWidth(double max) {
|
|
||||||
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
||||||
final int size = getEventCluster().getCount();
|
final int size = getEventCluster().getSize();
|
||||||
switch (descrVis) {
|
switch (descrVis) {
|
||||||
case HIDDEN:
|
case HIDDEN:
|
||||||
countLabel.setText("");
|
countLabel.setText("");
|
||||||
@ -137,9 +123,20 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
descrLabel.setText("");
|
descrLabel.setText("");
|
||||||
countLabel.setText(String.valueOf(size));
|
countLabel.setText(String.valueOf(size));
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
case SHOWN:
|
case SHOWN:
|
||||||
countLabel.setText(String.valueOf(size));
|
default:
|
||||||
|
String count;
|
||||||
|
String description;
|
||||||
|
if (parentNode == null) {
|
||||||
|
description = tlEvent.getDescription();
|
||||||
|
count = "(" + size + ")";
|
||||||
|
} else {
|
||||||
|
description = "";
|
||||||
|
count = String.valueOf(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
descrLabel.setText(description);
|
||||||
|
countLabel.setText(count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,8 +222,6 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
EventNodeBase<?> createChildNode(EventStripe stripe) {
|
EventNodeBase<?> createChildNode(EventStripe stripe) {
|
||||||
// return new EventStripeNode(getChart(), stripe, this);
|
|
||||||
|
|
||||||
if (stripe.getEventIDs().size() == 1) {
|
if (stripe.getEventIDs().size() == 1) {
|
||||||
return new SingleEventNode(getChart(), getChart().getController().getEventsModel().getEventById(Iterables.getOnlyElement(stripe.getEventIDs())), this);
|
return new SingleEventNode(getChart(), getChart().getController().getEventsModel().getEventById(Iterables.getOnlyElement(stripe.getEventIDs())), this);
|
||||||
} else {
|
} else {
|
||||||
@ -270,7 +265,7 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
return mouseEvent -> new ExpandClusterAction().handle(null);
|
return mouseEvent -> new ExpandClusterAction().handle(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ExpandClusterAction extends Action {
|
class ExpandClusterAction extends Action {
|
||||||
|
|
||||||
@NbBundle.Messages({"ExpandClusterAction.text=Expand"})
|
@NbBundle.Messages({"ExpandClusterAction.text=Expand"})
|
||||||
ExpandClusterAction() {
|
ExpandClusterAction() {
|
||||||
@ -286,7 +281,7 @@ final public class EventClusterNode extends MultiEventNodeBase<EventCluster, Eve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CollapseClusterAction extends Action {
|
class CollapseClusterAction extends Action {
|
||||||
|
|
||||||
@NbBundle.Messages({"CollapseClusterAction.text=Collapse"})
|
@NbBundle.Messages({"CollapseClusterAction.text=Collapse"})
|
||||||
CollapseClusterAction() {
|
CollapseClusterAction() {
|
||||||
|
@ -29,6 +29,7 @@ import javafx.animation.Timeline;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ButtonBase;
|
import javafx.scene.control.ButtonBase;
|
||||||
@ -42,8 +43,15 @@ import javafx.scene.image.Image;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
|
import javafx.scene.layout.Background;
|
||||||
|
import javafx.scene.layout.BackgroundFill;
|
||||||
|
import javafx.scene.layout.Border;
|
||||||
|
import javafx.scene.layout.BorderStroke;
|
||||||
|
import javafx.scene.layout.BorderStrokeStyle;
|
||||||
|
import javafx.scene.layout.BorderWidths;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
import org.controlsfx.control.action.ActionUtils;
|
import org.controlsfx.control.action.ActionUtils;
|
||||||
@ -55,7 +63,9 @@ import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
|||||||
import org.sleuthkit.autopsy.timeline.ui.AbstractVisualizationPane;
|
import org.sleuthkit.autopsy.timeline.ui.AbstractVisualizationPane;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||||
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.show;
|
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.show;
|
||||||
|
import static org.sleuthkit.autopsy.timeline.ui.detailview.MultiEventNodeBase.CORNER_RADII_3;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
||||||
|
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -71,40 +81,68 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
|
|
||||||
static final Map<EventType, Effect> dropShadowMap = new ConcurrentHashMap<>();
|
static final Map<EventType, Effect> dropShadowMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final Tooltip tooltip = new Tooltip(Bundle.EventBundleNodeBase_toolTip_loading());
|
|
||||||
|
|
||||||
final Type tlEvent;
|
|
||||||
|
|
||||||
final EventNodeBase<?> parentNode;
|
|
||||||
final Label descrLabel = new Label();
|
|
||||||
final SimpleObjectProperty<DescriptionLoD> descLOD = new SimpleObjectProperty<>();
|
|
||||||
final SimpleObjectProperty<DescriptionVisibility> descVisibility = new SimpleObjectProperty<>();
|
|
||||||
|
|
||||||
static void configureActionButton(ButtonBase b) {
|
static void configureActionButton(ButtonBase b) {
|
||||||
b.setMinSize(16, 16);
|
b.setMinSize(16, 16);
|
||||||
b.setMaxSize(16, 16);
|
b.setMaxSize(16, 16);
|
||||||
b.setPrefSize(16, 16);
|
b.setPrefSize(16, 16);
|
||||||
show(b, false);
|
// show(b, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show(Node b, boolean show) {
|
static void show(Node b, boolean show) {
|
||||||
b.setVisible(show);
|
b.setVisible(show);
|
||||||
b.setManaged(show);
|
b.setManaged(show);
|
||||||
}
|
}
|
||||||
private Timeline timeline;
|
|
||||||
final DetailsChart chart;
|
|
||||||
|
|
||||||
public EventNodeBase(Type ievent, EventNodeBase<?> parent, DetailsChart chart) {
|
final Type tlEvent;
|
||||||
|
|
||||||
|
final EventNodeBase<?> parentNode;
|
||||||
|
|
||||||
|
final SimpleObjectProperty<DescriptionLoD> descLOD = new SimpleObjectProperty<>();
|
||||||
|
final SimpleObjectProperty<DescriptionVisibility> descVisibility = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
|
final DetailsChart chart;
|
||||||
|
final Background highlightedBackground;
|
||||||
|
final Background defaultBackground;
|
||||||
|
final Color evtColor;
|
||||||
|
|
||||||
|
final Label countLabel = new Label();
|
||||||
|
final Label descrLabel = new Label();
|
||||||
|
final ImageView hashIV = new ImageView(HASH_PIN);
|
||||||
|
final ImageView tagIV = new ImageView(TAG);
|
||||||
|
|
||||||
|
final HBox controlsHBox = new HBox(5);
|
||||||
|
final HBox infoHBox = new HBox(5, descrLabel, countLabel, hashIV, tagIV, controlsHBox);
|
||||||
|
|
||||||
|
private final Tooltip tooltip = new Tooltip(Bundle.EventBundleNodeBase_toolTip_loading());
|
||||||
|
|
||||||
|
private Timeline timeline;
|
||||||
|
private Button pinButton;
|
||||||
|
private final Border SELECTION_BORDER;
|
||||||
|
final ImageView eventTypeImageView = new ImageView();
|
||||||
|
|
||||||
|
EventNodeBase(Type ievent, EventNodeBase<?> parent, DetailsChart chart) {
|
||||||
this.chart = chart;
|
this.chart = chart;
|
||||||
this.tlEvent = ievent;
|
this.tlEvent = ievent;
|
||||||
this.parentNode = parent;
|
this.parentNode = parent;
|
||||||
|
eventTypeImageView.setImage(getEventType().getFXImage());
|
||||||
|
|
||||||
|
descrLabel.setGraphic(eventTypeImageView);
|
||||||
|
|
||||||
|
if (chart.getController().getEventsModel().getEventTypeZoom() == EventTypeZoomLevel.SUB_TYPE) {
|
||||||
|
evtColor = getEventType().getColor();
|
||||||
|
} else {
|
||||||
|
evtColor = getEventType().getBaseType().getColor();
|
||||||
|
}
|
||||||
|
SELECTION_BORDER = new Border(new BorderStroke(evtColor.darker().desaturate(), BorderStrokeStyle.SOLID, CORNER_RADII_3, new BorderWidths(2)));
|
||||||
|
|
||||||
|
defaultBackground = new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII_3, Insets.EMPTY));
|
||||||
|
highlightedBackground = new Background(new BackgroundFill(evtColor.deriveColor(0, 1.1, 1.1, .3), CORNER_RADII_3, Insets.EMPTY));
|
||||||
descVisibility.addListener(observable -> setDescriptionVisibiltiyImpl(descVisibility.get()));
|
descVisibility.addListener(observable -> setDescriptionVisibiltiyImpl(descVisibility.get()));
|
||||||
// descVisibility.set(DescriptionVisibility.SHOWN); //trigger listener for initial value
|
// descVisibility.set(DescriptionVisibility.SHOWN); //trigger listener for initial value
|
||||||
|
setBackground(defaultBackground);
|
||||||
|
|
||||||
//set up mouse hover effect and tooltip
|
//set up mouse hover effect and tooltip
|
||||||
setOnMouseEntered(mouseEntered -> {
|
setOnMouseEntered(mouseEntered -> {
|
||||||
|
|
||||||
Tooltip.uninstall(chart.asNode(), AbstractVisualizationPane.getDefaultTooltip());
|
Tooltip.uninstall(chart.asNode(), AbstractVisualizationPane.getDefaultTooltip());
|
||||||
showHoverControls(true);
|
showHoverControls(true);
|
||||||
toFront();
|
toFront();
|
||||||
@ -118,50 +156,50 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
setOnMouseClicked(new ClickHandler());
|
setOnMouseClicked(new ClickHandler());
|
||||||
|
show(controlsHBox, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getEvent() {
|
public Type getEvent() {
|
||||||
return tlEvent;
|
return tlEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract TimeLineChart<DateTime> getChart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param w the maximum width the description label should have
|
||||||
|
*/
|
||||||
|
public void setMaxDescriptionWidth(double w) {
|
||||||
|
descrLabel.setMaxWidth(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract List<EventNodeBase<?>> getSubNodes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply the 'effect' to visually indicate selection
|
||||||
|
*
|
||||||
|
* @param applied true to apply the selection 'effect', false to remove it
|
||||||
|
*/
|
||||||
|
public void applySelectionEffect(boolean applied) {
|
||||||
|
setBorder(applied ? SELECTION_BORDER : null);
|
||||||
|
}
|
||||||
|
|
||||||
protected void layoutChildren() {
|
protected void layoutChildren() {
|
||||||
super.layoutChildren();
|
super.layoutChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* install whatever buttons are visible on hover for this node. likes
|
* Install whatever buttons are visible on hover for this node. likes
|
||||||
* tooltips, this had a surprisingly large impact on speed of loading the
|
* tooltips, this had a surprisingly large impact on speed of loading the
|
||||||
* chart
|
* chart
|
||||||
*/
|
*/
|
||||||
void installActionButtons() {
|
void installActionButtons() {
|
||||||
if (pinButton == null) {
|
if (pinButton == null) {
|
||||||
pinButton = new Button("", new ImageView(PIN));
|
pinButton = new Button();
|
||||||
infoHBox.getChildren().add(pinButton);
|
controlsHBox.getChildren().add(pinButton);
|
||||||
configureActionButton(pinButton);
|
configureActionButton(pinButton);
|
||||||
|
|
||||||
pinButton.setOnAction(actionEvent -> {
|
|
||||||
TimeLineController controller = getChart().getController();
|
|
||||||
if (controller.getPinnedEvents().contains(tlEvent)) {
|
|
||||||
new UnPinEventAction(controller, tlEvent).handle(actionEvent);
|
|
||||||
pinButton.setGraphic(new ImageView(PIN));
|
|
||||||
} else {
|
|
||||||
new PinEventAction(controller, tlEvent).handle(actionEvent);
|
|
||||||
pinButton.setGraphic(new ImageView(UNPIN));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Label countLabel = new Label();
|
|
||||||
|
|
||||||
final ImageView hashIV = new ImageView(HASH_PIN);
|
|
||||||
final ImageView tagIV = new ImageView(TAG);
|
|
||||||
final HBox infoHBox = new HBox(5, descrLabel, countLabel, hashIV, tagIV);
|
|
||||||
private Button pinButton;
|
|
||||||
|
|
||||||
abstract public TimeLineChart<DateTime> getChart();
|
|
||||||
|
|
||||||
void showHoverControls(final boolean showControls) {
|
void showHoverControls(final boolean showControls) {
|
||||||
Effect dropShadow = dropShadowMap.computeIfAbsent(getEventType(),
|
Effect dropShadow = dropShadowMap.computeIfAbsent(getEventType(),
|
||||||
eventType -> new DropShadow(-10, eventType.getColor()));
|
eventType -> new DropShadow(-10, eventType.getColor()));
|
||||||
@ -169,7 +207,24 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
installTooltip();
|
installTooltip();
|
||||||
enableTooltip(showControls);
|
enableTooltip(showControls);
|
||||||
installActionButtons();
|
installActionButtons();
|
||||||
show(pinButton, showControls);
|
|
||||||
|
TimeLineController controller = getChart().getController();
|
||||||
|
|
||||||
|
if (controller.getPinnedEvents().contains(tlEvent)) {
|
||||||
|
pinButton.setOnAction(actionEvent -> {
|
||||||
|
new UnPinEventAction(controller, tlEvent).handle(actionEvent);
|
||||||
|
showHoverControls(true);
|
||||||
|
});
|
||||||
|
pinButton.setGraphic(new ImageView(UNPIN));
|
||||||
|
} else {
|
||||||
|
pinButton.setOnAction(actionEvent -> {
|
||||||
|
new PinEventAction(controller, tlEvent).handle(actionEvent);
|
||||||
|
showHoverControls(true);
|
||||||
|
});
|
||||||
|
pinButton.setGraphic(new ImageView(PIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
show(controlsHBox, showControls);
|
||||||
if (parentNode != null) {
|
if (parentNode != null) {
|
||||||
parentNode.showHoverControls(false);
|
parentNode.showHoverControls(false);
|
||||||
}
|
}
|
||||||
@ -185,7 +240,7 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EventType getEventType() {
|
final EventType getEventType() {
|
||||||
return tlEvent.getEventType();
|
return tlEvent.getEventType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,10 +277,6 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
|
|
||||||
abstract void setDescriptionVisibiltiyImpl(DescriptionVisibility get);
|
abstract void setDescriptionVisibiltiyImpl(DescriptionVisibility get);
|
||||||
|
|
||||||
abstract void setMaxDescriptionWidth(double descriptionWidth);
|
|
||||||
|
|
||||||
abstract public List<EventNodeBase<?>> getSubNodes();
|
|
||||||
|
|
||||||
abstract void applyHighlightEffect(boolean b);
|
abstract void applyHighlightEffect(boolean b);
|
||||||
|
|
||||||
void applyHighlightEffect() {
|
void applyHighlightEffect() {
|
||||||
@ -238,9 +289,9 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
|
|
||||||
abstract Collection<Long> getEventIDs();
|
abstract Collection<Long> getEventIDs();
|
||||||
|
|
||||||
void applySelectionEffect(Boolean selected) {
|
abstract EventHandler<MouseEvent> getDoubleClickHandler();
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
}
|
abstract Collection<? extends Action> getActions();
|
||||||
|
|
||||||
static class PinEventAction extends Action {
|
static class PinEventAction extends Action {
|
||||||
|
|
||||||
@ -300,8 +351,4 @@ public abstract class EventNodeBase<Type extends TimeLineEvent> extends StackPan
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract EventHandler<MouseEvent> getDoubleClickHandler();
|
|
||||||
|
|
||||||
abstract Collection<? extends Action> getActions();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import javafx.event.EventHandler;
|
|||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.OverrunStyle;
|
import javafx.scene.control.OverrunStyle;
|
||||||
import javafx.scene.image.ImageView;
|
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -44,73 +43,47 @@ final public class EventStripeNode extends MultiEventNodeBase<EventStripe, Event
|
|||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(EventStripeNode.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(EventStripeNode.class.getName());
|
||||||
private Button hideButton;
|
private Button hideButton;
|
||||||
/**
|
|
||||||
* Pane that contains EventStripeNodes for any 'subevents' if they are
|
|
||||||
* displayed
|
|
||||||
*
|
|
||||||
* //TODO: move more of the control of subnodes/events here and out of
|
|
||||||
* EventDetail Chart
|
|
||||||
*/
|
|
||||||
// private final HBox clustersHBox = new HBox();
|
|
||||||
private final ImageView eventTypeImageView = new ImageView();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void installActionButtons() {
|
|
||||||
super.installActionButtons();
|
|
||||||
if (hideButton == null) {
|
|
||||||
hideButton = ActionUtils.createButton(new HideDescriptionAction(getDescription(), tlEvent.getDescriptionLoD(), chart),
|
|
||||||
ActionUtils.ActionTextBehavior.HIDE);
|
|
||||||
configureActionButton(hideButton);
|
|
||||||
|
|
||||||
infoHBox.getChildren().add(hideButton);
|
EventStripeNode(DetailsChart chart, EventStripe eventStripe, EventClusterNode parentNode) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventStripeNode(DetailsChart chart, EventStripe eventStripe, EventClusterNode parentNode) {
|
|
||||||
super(chart, eventStripe, parentNode);
|
super(chart, eventStripe, parentNode);
|
||||||
setMinHeight(48);
|
setMinHeight(24);
|
||||||
//setup description label
|
//setup description label
|
||||||
eventTypeImageView.setImage(getEventType().getFXImage());
|
|
||||||
descrLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
|
descrLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
|
||||||
descrLabel.setGraphic(eventTypeImageView);
|
|
||||||
descrLabel.setPrefWidth(USE_COMPUTED_SIZE);
|
descrLabel.setPrefWidth(USE_COMPUTED_SIZE);
|
||||||
setAlignment(subNodePane, Pos.BOTTOM_LEFT);
|
setAlignment(subNodePane, Pos.BOTTOM_LEFT);
|
||||||
|
|
||||||
for (EventCluster cluster : eventStripe.getClusters()) {
|
if (eventStripe.getClusters().size() > 1) {
|
||||||
subNodes.add(createChildNode(cluster));
|
for (EventCluster cluster : eventStripe.getClusters()) {
|
||||||
}
|
subNodes.add(createChildNode(cluster));
|
||||||
|
}
|
||||||
getChildren().addAll(new VBox(infoHBox, subNodePane));
|
getChildren().addAll(new VBox(infoHBox, subNodePane));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
EventNodeBase<?> createChildNode(EventCluster cluster) {
|
|
||||||
if (cluster.getEventIDs().size() == 1) {
|
|
||||||
return new SingleEventNode(getChart(), getChart().getController().getEventsModel().getEventById(Iterables.getOnlyElement(cluster.getEventIDs())), this);
|
|
||||||
} else {
|
} else {
|
||||||
return new EventClusterNode(getChart(), cluster, this);
|
EventNodeBase<?> childNode;
|
||||||
}
|
EventCluster cluster = Iterables.getOnlyElement(eventStripe.getClusters());
|
||||||
}
|
if (cluster.getEventIDs().size() == 1) {
|
||||||
|
SingleEventNode singleEventNode = new SingleEventNode(getChart(), getChart().getController().getEventsModel().getEventById(Iterables.getOnlyElement(cluster.getEventIDs())), this);
|
||||||
|
childNode = singleEventNode;
|
||||||
|
} else {
|
||||||
|
EventClusterNode eventClusterNode = new EventClusterNode(getChart(), cluster, this);
|
||||||
|
eventClusterNode.installActionButtons();
|
||||||
|
eventClusterNode.infoHBox.getChildren().remove(eventClusterNode.countLabel);
|
||||||
|
controlsHBox.getChildren().addAll(eventClusterNode.minusButton, eventClusterNode.plusButton);
|
||||||
|
childNode = eventClusterNode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
childNode.setDescriptionVisibiltiyImpl(DescriptionVisibility.HIDDEN);
|
||||||
void showHoverControls(final boolean showControls) {
|
subNodes.add(childNode);
|
||||||
super.showHoverControls(showControls);
|
getChildren().addAll(infoHBox, subNodePane);
|
||||||
installActionButtons();
|
}
|
||||||
show(hideButton, showControls);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventStripe getEventStripe() {
|
public EventStripe getEventStripe() {
|
||||||
return getEventBundle();
|
return getEventBundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param w the maximum width the description label should have
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setMaxDescriptionWidth(double w) {
|
|
||||||
descrLabel.setMaxWidth(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apply the 'effect' to visually indicate highlighted nodes
|
* apply the 'effect' to visually indicate highlighted nodes
|
||||||
*
|
*
|
||||||
@ -127,9 +100,32 @@ final public class EventStripeNode extends MultiEventNodeBase<EventStripe, Event
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void installActionButtons() {
|
||||||
|
super.installActionButtons();
|
||||||
|
if (hideButton == null) {
|
||||||
|
hideButton = ActionUtils.createButton(new HideDescriptionAction(getDescription(), tlEvent.getDescriptionLoD(), chart),
|
||||||
|
ActionUtils.ActionTextBehavior.HIDE);
|
||||||
|
configureActionButton(hideButton);
|
||||||
|
|
||||||
|
controlsHBox.getChildren().add(hideButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
EventNodeBase<?> createChildNode(EventCluster cluster) {
|
||||||
|
if (cluster.getEventIDs().size() == 1) {
|
||||||
|
return new SingleEventNode(getChart(), getChart().getController().getEventsModel().getEventById(Iterables.getOnlyElement(cluster.getEventIDs())), this);
|
||||||
|
} else {
|
||||||
|
return new EventClusterNode(getChart(), cluster, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
||||||
final int size = getEventStripe().getCount();
|
final int size = getEventStripe().getSize();
|
||||||
|
|
||||||
switch (descrVis) {
|
switch (descrVis) {
|
||||||
case HIDDEN:
|
case HIDDEN:
|
||||||
|
@ -40,15 +40,8 @@ import javafx.geometry.Orientation;
|
|||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.Background;
|
|
||||||
import javafx.scene.layout.BackgroundFill;
|
|
||||||
import javafx.scene.layout.Border;
|
|
||||||
import javafx.scene.layout.BorderStroke;
|
|
||||||
import javafx.scene.layout.BorderStrokeStyle;
|
|
||||||
import javafx.scene.layout.BorderWidths;
|
|
||||||
import javafx.scene.layout.CornerRadii;
|
import javafx.scene.layout.CornerRadii;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.paint.Color;
|
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
@ -59,7 +52,6 @@ import org.sleuthkit.autopsy.timeline.TimeLineController;
|
|||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.MultiEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.MultiEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
|
||||||
import org.sleuthkit.autopsy.timeline.ui.AbstractVisualizationPane;
|
import org.sleuthkit.autopsy.timeline.ui.AbstractVisualizationPane;
|
||||||
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.show;
|
import static org.sleuthkit.autopsy.timeline.ui.detailview.EventNodeBase.show;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
||||||
@ -80,32 +72,21 @@ public abstract class MultiEventNodeBase< BundleType extends MultiEvent<ParentTy
|
|||||||
static final CornerRadii CORNER_RADII_3 = new CornerRadii(3);
|
static final CornerRadii CORNER_RADII_3 = new CornerRadii(3);
|
||||||
static final CornerRadii CORNER_RADII_1 = new CornerRadii(1);
|
static final CornerRadii CORNER_RADII_1 = new CornerRadii(1);
|
||||||
|
|
||||||
private final Border SELECTION_BORDER;
|
|
||||||
|
|
||||||
final SleuthkitCase sleuthkitCase;
|
final SleuthkitCase sleuthkitCase;
|
||||||
final FilteredEventsModel eventsModel;
|
final FilteredEventsModel eventsModel;
|
||||||
|
|
||||||
final Background highlightedBackground;
|
|
||||||
final Background defaultBackground;
|
|
||||||
final Color evtColor;
|
|
||||||
|
|
||||||
final ObservableList<EventNodeBase<?>> subNodes = FXCollections.observableArrayList();
|
final ObservableList<EventNodeBase<?>> subNodes = FXCollections.observableArrayList();
|
||||||
final Pane subNodePane = new Pane();
|
final Pane subNodePane = new Pane();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final Tooltip tooltip = new Tooltip(Bundle.EventBundleNodeBase_toolTip_loading());
|
private final Tooltip tooltip = new Tooltip(Bundle.EventBundleNodeBase_toolTip_loading());
|
||||||
private Timeline timeline;
|
private Timeline timeline;
|
||||||
|
|
||||||
public MultiEventNodeBase(DetailsChart chart, BundleType eventBundle, ParentNodeType parentNode) {
|
MultiEventNodeBase(DetailsChart chart, BundleType eventBundle, ParentNodeType parentNode) {
|
||||||
super(eventBundle, parentNode, chart);
|
super(eventBundle, parentNode, 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();
|
||||||
evtColor = getEventType().getColor();
|
|
||||||
defaultBackground = new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII_3, Insets.EMPTY));
|
|
||||||
highlightedBackground = new Background(new BackgroundFill(evtColor.deriveColor(0, 1.1, 1.1, .3), CORNER_RADII_3, Insets.EMPTY));
|
|
||||||
SELECTION_BORDER = new Border(new BorderStroke(evtColor.darker().desaturate(), BorderStrokeStyle.SOLID, CORNER_RADII_3, new BorderWidths(2)));
|
|
||||||
if (eventBundle.getEventIDsWithHashHits().isEmpty()) {
|
if (eventBundle.getEventIDsWithHashHits().isEmpty()) {
|
||||||
show(hashIV, false);
|
show(hashIV, false);
|
||||||
}
|
}
|
||||||
@ -113,7 +94,6 @@ public abstract class MultiEventNodeBase< BundleType extends MultiEvent<ParentTy
|
|||||||
show(tagIV, false);
|
show(tagIV, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBackground(defaultBackground);
|
|
||||||
setAlignment(Pos.TOP_LEFT);
|
setAlignment(Pos.TOP_LEFT);
|
||||||
setMaxWidth(USE_PREF_SIZE);
|
setMaxWidth(USE_PREF_SIZE);
|
||||||
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
||||||
@ -171,7 +151,6 @@ public abstract class MultiEventNodeBase< BundleType extends MultiEvent<ParentTy
|
|||||||
return tlEvent;
|
return tlEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* defer tooltip content creation till needed, this had a surprisingly large
|
* defer tooltip content creation till needed, this had a surprisingly large
|
||||||
* impact on speed of loading the chart
|
* impact on speed of loading the chart
|
||||||
@ -246,15 +225,6 @@ public abstract class MultiEventNodeBase< BundleType extends MultiEvent<ParentTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* apply the 'effect' to visually indicate selection
|
|
||||||
*
|
|
||||||
* @param applied true to apply the selection 'effect', false to remove it
|
|
||||||
*/
|
|
||||||
public void applySelectionEffect(boolean applied) {
|
|
||||||
setBorder(applied ? SELECTION_BORDER : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apply the 'effect' to visually indicate highlighted nodes
|
* apply the 'effect' to visually indicate highlighted nodes
|
||||||
*
|
*
|
||||||
@ -267,10 +237,6 @@ public abstract class MultiEventNodeBase< BundleType extends MultiEvent<ParentTy
|
|||||||
return subNodes;
|
return subNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
final EventType getEventType() {
|
|
||||||
return getEventBundle().getEventType();
|
|
||||||
}
|
|
||||||
|
|
||||||
final String getDescription() {
|
final String getDescription() {
|
||||||
return getEventBundle().getDescription();
|
return getEventBundle().getDescription();
|
||||||
}
|
}
|
||||||
@ -300,11 +266,6 @@ public abstract class MultiEventNodeBase< BundleType extends MultiEvent<ParentTy
|
|||||||
|
|
||||||
abstract EventNodeBase<?> createChildNode(ParentType rawChild);
|
abstract EventNodeBase<?> createChildNode(ParentType rawChild);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param w the maximum width the description label should have
|
|
||||||
*/
|
|
||||||
abstract void setMaxDescriptionWidth(double w);
|
|
||||||
|
|
||||||
void animateTo(double xLeft, double yTop) {
|
void animateTo(double xLeft, double yTop) {
|
||||||
if (timeline != null) {
|
if (timeline != null) {
|
||||||
timeline.stop();
|
timeline.stop();
|
||||||
|
@ -346,8 +346,8 @@ public final class PinnedEventsChart extends XYChart<DateTime, TimeLineEvent> im
|
|||||||
eventNode.setVisible(true);
|
eventNode.setVisible(true);
|
||||||
eventNode.setManaged(true);
|
eventNode.setManaged(true);
|
||||||
//apply advanced layout description visibility options
|
//apply advanced layout description visibility options
|
||||||
// eventNode.setDescriptionVisibility(descrVisibility.get());
|
eventNode.setDescriptionVisibility(DescriptionVisibility.SHOWN);
|
||||||
// eventNode.setMaxDescriptionWidth(descriptionWidth);
|
eventNode.setMaxDescriptionWidth(USE_PREF_SIZE);
|
||||||
|
|
||||||
//do recursive layout
|
//do recursive layout
|
||||||
eventNode.layoutChildren();
|
eventNode.layoutChildren();
|
||||||
|
@ -23,29 +23,23 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.OverrunStyle;
|
import javafx.scene.control.OverrunStyle;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.Background;
|
|
||||||
import javafx.scene.layout.BackgroundFill;
|
|
||||||
import javafx.scene.layout.Border;
|
import javafx.scene.layout.Border;
|
||||||
import javafx.scene.layout.BorderStroke;
|
import javafx.scene.layout.BorderStroke;
|
||||||
import javafx.scene.layout.BorderStrokeStyle;
|
import javafx.scene.layout.BorderStrokeStyle;
|
||||||
import javafx.scene.layout.BorderWidths;
|
import javafx.scene.layout.BorderWidths;
|
||||||
import javafx.scene.layout.CornerRadii;
|
import javafx.scene.layout.CornerRadii;
|
||||||
import static javafx.scene.layout.Region.USE_PREF_SIZE;
|
import static javafx.scene.layout.Region.USE_PREF_SIZE;
|
||||||
import javafx.scene.paint.Color;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||||
import static org.sleuthkit.autopsy.timeline.ui.detailview.MultiEventNodeBase.CORNER_RADII_3;
|
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -53,10 +47,6 @@ import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
|||||||
final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
||||||
|
|
||||||
private final DetailsChart chart;
|
private final DetailsChart chart;
|
||||||
final Background defaultBackground;
|
|
||||||
private final Color evtColor;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void show(Node b, boolean show) {
|
static void show(Node b, boolean show) {
|
||||||
b.setVisible(show);
|
b.setVisible(show);
|
||||||
@ -65,7 +55,6 @@ final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
|||||||
static final CornerRadii CORNER_RADII_1 = new CornerRadii(1);
|
static final CornerRadii CORNER_RADII_1 = new CornerRadii(1);
|
||||||
private static final BorderWidths CLUSTER_BORDER_WIDTHS = new BorderWidths(0, 0, 0, 2);
|
private static final BorderWidths CLUSTER_BORDER_WIDTHS = new BorderWidths(0, 0, 0, 2);
|
||||||
private final ImageView eventTypeImageView = new ImageView();
|
private final ImageView eventTypeImageView = new ImageView();
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
EventHandler<MouseEvent> getDoubleClickHandler() {
|
EventHandler<MouseEvent> getDoubleClickHandler() {
|
||||||
@ -100,19 +89,12 @@ final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
|||||||
show(tagIV, false);
|
show(tagIV, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chart.getController().getEventsModel().getEventTypeZoom() == EventTypeZoomLevel.SUB_TYPE) {
|
|
||||||
evtColor = getEventType().getColor();
|
|
||||||
} else {
|
|
||||||
evtColor = getEventType().getBaseType().getColor();
|
|
||||||
}
|
|
||||||
final Border clusterBorder = new Border(new BorderStroke(evtColor.deriveColor(0, 1, 1, .4), BorderStrokeStyle.SOLID, CORNER_RADII_1, CLUSTER_BORDER_WIDTHS));
|
final Border clusterBorder = new Border(new BorderStroke(evtColor.deriveColor(0, 1, 1, .4), BorderStrokeStyle.SOLID, CORNER_RADII_1, CLUSTER_BORDER_WIDTHS));
|
||||||
setBorder(clusterBorder);
|
setBorder(clusterBorder);
|
||||||
defaultBackground = new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII_3, Insets.EMPTY));
|
|
||||||
setBackground(defaultBackground);
|
|
||||||
setMaxWidth(USE_PREF_SIZE);
|
setMaxWidth(USE_PREF_SIZE);
|
||||||
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
||||||
getChildren().add(infoHBox);
|
getChildren().add(infoHBox);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -125,14 +107,6 @@ final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void showHoverControls(final boolean showControls) {
|
|
||||||
super.showHoverControls(showControls);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void layoutChildren() {
|
protected void layoutChildren() {
|
||||||
super.layoutChildren(); //To change body of generated methods, choose Tools | Templates.
|
super.layoutChildren(); //To change body of generated methods, choose Tools | Templates.
|
||||||
@ -153,14 +127,28 @@ final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
|||||||
chart.requestTimelineChartLayout();
|
chart.requestTimelineChartLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply the 'effect' to visually indicate highlighted nodes
|
||||||
|
*
|
||||||
|
* @param applied true to apply the highlight 'effect', false to remove it
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
void applyHighlightEffect(boolean b) {
|
public synchronized void applyHighlightEffect(boolean applied) {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
if (applied) {
|
||||||
|
descrLabel.setStyle("-fx-font-weight: bold;"); // NON-NLS
|
||||||
|
setBackground(highlightedBackground);
|
||||||
|
} else {
|
||||||
|
descrLabel.setStyle("-fx-font-weight: normal;"); // NON-NLS
|
||||||
|
setBackground(defaultBackground);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param w the maximum width the description label should have
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
void setMaxDescriptionWidth(double descriptionWidth) {
|
public void setMaxDescriptionWidth(double w) {
|
||||||
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
descrLabel.setMaxWidth(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -168,13 +156,16 @@ final class SingleEventNode extends EventNodeBase<SingleEvent> {
|
|||||||
|
|
||||||
switch (descrVis) {
|
switch (descrVis) {
|
||||||
case HIDDEN:
|
case HIDDEN:
|
||||||
|
countLabel.setText(null);
|
||||||
descrLabel.setText("");
|
descrLabel.setText("");
|
||||||
break;
|
break;
|
||||||
case COUNT_ONLY:
|
case COUNT_ONLY:
|
||||||
|
countLabel.setText(null);
|
||||||
descrLabel.setText("");
|
descrLabel.setText("");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case SHOWN:
|
case SHOWN:
|
||||||
|
countLabel.setText(null);
|
||||||
String description = tlEvent.getFullDescription();
|
String description = tlEvent.getFullDescription();
|
||||||
description = parentNode != null
|
description = parentNode != null
|
||||||
? " ..." + StringUtils.substringAfter(description, parentNode.getDescription())
|
? " ..." + StringUtils.substringAfter(description, parentNode.getDescription())
|
||||||
|
@ -52,7 +52,7 @@ class EventDescriptionTreeItem extends NavTreeItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getCount() {
|
public long getCount() {
|
||||||
return getValue().getCount();
|
return getValue().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
@ -44,7 +44,7 @@ class EventTypeTreeItem extends NavTreeItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getCount() {
|
public long getCount() {
|
||||||
return getValue().getCount();
|
return getValue().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
@ -185,7 +185,7 @@ final public class EventsTree extends BorderPane {
|
|||||||
setDisable(true);
|
setDisable(true);
|
||||||
} else {
|
} else {
|
||||||
setDisable(false);
|
setDisable(false);
|
||||||
text = item.getDescription() + " (" + item.getCount() + ")"; // NON-NLS
|
text = item.getDescription() + " (" + item.getSize() + ")"; // NON-NLS
|
||||||
TreeItem<TimeLineEvent> parent = getTreeItem().getParent();
|
TreeItem<TimeLineEvent> parent = getTreeItem().getParent();
|
||||||
if (parent != null && parent.getValue() != null && (parent instanceof EventDescriptionTreeItem)) {
|
if (parent != null && parent.getValue() != null && (parent instanceof EventDescriptionTreeItem)) {
|
||||||
text = StringUtils.substringAfter(text, parent.getValue().getDescription());
|
text = StringUtils.substringAfter(text, parent.getValue().getDescription());
|
||||||
|
@ -51,7 +51,7 @@ class RootItem extends NavTreeItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getCount() {
|
public long getCount() {
|
||||||
return getValue().getCount();
|
return getValue().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,7 @@ enum TreeComparator implements Comparator<TreeItem<TimeLineEvent>> {
|
|||||||
Count(Bundle.TreeComparator_Count_displayName()) {
|
Count(Bundle.TreeComparator_Count_displayName()) {
|
||||||
@Override
|
@Override
|
||||||
public int compare(TreeItem<TimeLineEvent> o1, TreeItem<TimeLineEvent> o2) {
|
public int compare(TreeItem<TimeLineEvent> o1, TreeItem<TimeLineEvent> o2) {
|
||||||
return Long.compare(o2.getValue().getCount(), o1.getValue().getCount());
|
return Long.compare(o2.getValue().getSize(), o1.getValue().getSize());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Type(Bundle.TreeComparator_Type_displayName()) {
|
Type(Bundle.TreeComparator_Type_displayName()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user