mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Merge remote-tracking branch 'upstream/TL-list-view' into 792-truncate-descriptions-in-list-view
Conflicts: Core/src/org/sleuthkit/autopsy/timeline/datamodel/CombinedEvent.java Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/ListTimeline.java
This commit is contained in:
commit
37f2bee2de
@ -24,6 +24,7 @@ import java.io.IOException;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -344,6 +345,9 @@ public class TimeLineController {
|
|||||||
filteredEvents.filterProperty().get(),
|
filteredEvents.filterProperty().get(),
|
||||||
DescriptionLoD.SHORT);
|
DescriptionLoD.SHORT);
|
||||||
historyManager.advance(InitialZoomState);
|
historyManager.advance(InitialZoomState);
|
||||||
|
|
||||||
|
//clear the selected events when the view mode changes
|
||||||
|
viewMode.addListener(observable -> selectEventIDs(Collections.emptySet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +35,10 @@ public class CombinedEvent {
|
|||||||
private final long fileID;
|
private final long fileID;
|
||||||
private final long epochMillis;
|
private final long epochMillis;
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map from EventType to event ID.
|
||||||
|
*/
|
||||||
private final Map<EventType, Long> eventTypeMap = new HashMap<>();
|
private final Map<EventType, Long> eventTypeMap = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +47,7 @@ public class CombinedEvent {
|
|||||||
* @param epochMillis The timestamp for this event, in millis from the Unix
|
* @param epochMillis The timestamp for this event, in millis from the Unix
|
||||||
* epoch.
|
* epoch.
|
||||||
* @param description The full description shared by all the combined events
|
* @param description The full description shared by all the combined events
|
||||||
* @param fileID The ID of the file all the combined events are for.
|
* @param fileID The ID of the file shared by all the combined events.
|
||||||
* @param eventMap A map from EventType to event ID.
|
* @param eventMap A map from EventType to event ID.
|
||||||
*/
|
*/
|
||||||
public CombinedEvent(long epochMillis, String description, long fileID, Map<EventType, Long> eventMap) {
|
public CombinedEvent(long epochMillis, String description, long fileID, Map<EventType, Long> eventMap) {
|
||||||
@ -145,5 +149,4 @@ public class CombinedEvent {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,8 @@ public abstract class AbstractTimelineChart<X, Y, NodeType extends Node, ChartTy
|
|||||||
private static final Border ONLY_LEFT_BORDER = new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(0, 0, 0, 1)));
|
private static final Border ONLY_LEFT_BORDER = new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(0, 0, 0, 1)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tool tip to use for this view when no more specific
|
* Get the tool tip to use for this view when no more specific Tooltip is
|
||||||
* Tooltip is needed.
|
* needed.
|
||||||
*
|
*
|
||||||
* @return The default Tooltip.
|
* @return The default Tooltip.
|
||||||
*/
|
*/
|
||||||
@ -176,8 +176,8 @@ public abstract class AbstractTimelineChart<X, Y, NodeType extends Node, ChartTy
|
|||||||
abstract protected Boolean isTickBold(X value);
|
abstract protected Boolean isTickBold(X value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply this view's 'selection effect' to the given node, if
|
* Apply this view's 'selection effect' to the given node, if applied is
|
||||||
* applied is true. If applied is false, remove the affect
|
* true. If applied is false, remove the affect
|
||||||
*
|
*
|
||||||
* @param node The node to apply the 'effect' to
|
* @param node The node to apply the 'effect' to
|
||||||
* @param applied True if the effect should be applied, false if the effect
|
* @param applied True if the effect should be applied, false if the effect
|
||||||
|
@ -75,7 +75,7 @@ class ListTimeline extends BorderPane {
|
|||||||
private static final Logger LOGGER = Logger.getLogger(ListTimeline.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ListTimeline.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* call-back used to wrap CombinedEvent in a ObservableValue
|
* call-back used to wrap the CombinedEvent in a ObservableValue
|
||||||
*/
|
*/
|
||||||
private static final Callback<TableColumn.CellDataFeatures<CombinedEvent, CombinedEvent>, ObservableValue<CombinedEvent>> CELL_VALUE_FACTORY = param -> new SimpleObjectProperty<>(param.getValue());
|
private static final Callback<TableColumn.CellDataFeatures<CombinedEvent, CombinedEvent>, ObservableValue<CombinedEvent>> CELL_VALUE_FACTORY = param -> new SimpleObjectProperty<>(param.getValue());
|
||||||
|
|
||||||
@ -351,48 +351,55 @@ class ListTimeline extends BorderPane {
|
|||||||
event = null;
|
event = null;
|
||||||
} else {
|
} else {
|
||||||
event = controller.getEventsModel().getEventById(item.getRepresentativeEventID());
|
event = controller.getEventsModel().getEventById(item.getRepresentativeEventID());
|
||||||
//make context menu
|
|
||||||
try {
|
|
||||||
EventNode node = EventNode.createEventNode(event.getEventID(), controller.getEventsModel());
|
|
||||||
List<MenuItem> menuItems = new ArrayList<>();
|
|
||||||
|
|
||||||
//for each actions avaialable on node, make a menu item.
|
setOnContextMenuRequested(contextMenuEvent -> {
|
||||||
for (Action action : node.getActions(false)) {
|
//make a new context menu on each request in order to include uptodate tag names and hash sets
|
||||||
if (action == null) {
|
try {
|
||||||
// swing/netbeans uses null action to represent separator in menu
|
EventNode node = EventNode.createEventNode(item.getRepresentativeEventID(), controller.getEventsModel());
|
||||||
menuItems.add(new SeparatorMenuItem());
|
List<MenuItem> menuItems = new ArrayList<>();
|
||||||
} else {
|
|
||||||
String actionName = Objects.toString(action.getValue(Action.NAME));
|
//for each actions avaialable on node, make a menu item.
|
||||||
//for now, suppress properties and tools actions, by ignoring them
|
for (Action action : node.getActions(false)) {
|
||||||
if (Arrays.asList("&Properties", "Tools").contains(actionName) == false) {
|
if (action == null) {
|
||||||
if (action instanceof Presenter.Popup) {
|
// swing/netbeans uses null action to represent separator in menu
|
||||||
/*
|
menuItems.add(new SeparatorMenuItem());
|
||||||
* If the action is really the root of a set
|
} else {
|
||||||
* of actions (eg, tagging). Make a menu
|
String actionName = Objects.toString(action.getValue(Action.NAME));
|
||||||
* that parallels the action's menu.
|
//for now, suppress properties and tools actions, by ignoring them
|
||||||
*/
|
if (Arrays.asList("&Properties", "Tools").contains(actionName) == false) {
|
||||||
JMenuItem submenu = ((Presenter.Popup) action).getPopupPresenter();
|
if (action instanceof Presenter.Popup) {
|
||||||
menuItems.add(SwingFXMenuUtils.createFXMenu(submenu));
|
/*
|
||||||
} else {
|
* If the action is really the root of a
|
||||||
menuItems.add(SwingFXMenuUtils.createFXMenu(new Actions.MenuItem(action, false)));
|
* set of actions (eg, tagging). Make a
|
||||||
|
* menu that parallels the action's
|
||||||
|
* menu.
|
||||||
|
*/
|
||||||
|
JMenuItem submenu = ((Presenter.Popup) action).getPopupPresenter();
|
||||||
|
menuItems.add(SwingFXMenuUtils.createFXMenu(submenu));
|
||||||
|
} else {
|
||||||
|
menuItems.add(SwingFXMenuUtils.createFXMenu(new Actions.MenuItem(action, false)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
//show new context menu.
|
||||||
|
new ContextMenu(menuItems.toArray(new MenuItem[menuItems.size()]))
|
||||||
|
.show(this, contextMenuEvent.getScreenX(), contextMenuEvent.getScreenY());
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
//Since the case is closed, the user probably doesn't care about this, just log it as a precaution.
|
||||||
|
LOGGER.log(Level.SEVERE, "There was no case open to lookup the Sleuthkit object backing a SingleEvent.", ex); // NON-NLS
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Failed to lookup Sleuthkit object backing a SingleEvent.", ex); // NON-NLS
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
Notifications.create()
|
||||||
|
.owner(getScene().getWindow())
|
||||||
|
.text(Bundle.ListChart_errorMsg())
|
||||||
|
.showError();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setContextMenu(new ContextMenu(menuItems.toArray(new MenuItem[menuItems.size()])));
|
|
||||||
} catch (IllegalStateException ex) {
|
|
||||||
//Since the case is closed, the user probably doesn't care about this, just log it as a precaution.
|
|
||||||
LOGGER.log(Level.SEVERE, "There was no case open to lookup the Sleuthkit object backing a SingleEvent.", ex); // NON-NLS
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "Failed to lookup Sleuthkit object backing a SingleEvent.", ex); // NON-NLS
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
Notifications.create()
|
|
||||||
.owner(getScene().getWindow())
|
|
||||||
.text(Bundle.ListChart_errorMsg())
|
|
||||||
.showError();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user