mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-18 02:27:42 +00:00
add right click menu option to add event with datetime prepopulated;
other small cleanup and refactoring
This commit is contained in:
parent
397f9694ee
commit
aecc229345
@ -23,6 +23,7 @@ import com.google.common.util.concurrent.Futures;
|
|||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -32,6 +33,7 @@ import java.util.Optional;
|
|||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
@ -116,7 +118,8 @@ public class TimeLineController {
|
|||||||
|
|
||||||
private static final ReadOnlyObjectWrapper<TimeZone> timeZone = new ReadOnlyObjectWrapper<>(TimeZone.getDefault());
|
private static final ReadOnlyObjectWrapper<TimeZone> timeZone = new ReadOnlyObjectWrapper<>(TimeZone.getDefault());
|
||||||
|
|
||||||
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
|
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(
|
||||||
|
new ThreadFactoryBuilder().setNameFormat("Timeline Controller BG thread").build()));
|
||||||
private final ReadOnlyListWrapper<Task<?>> tasks = new ReadOnlyListWrapper<>(FXCollections.observableArrayList());
|
private final ReadOnlyListWrapper<Task<?>> tasks = new ReadOnlyListWrapper<>(FXCollections.observableArrayList());
|
||||||
private final ReadOnlyDoubleWrapper taskProgress = new ReadOnlyDoubleWrapper(-1);
|
private final ReadOnlyDoubleWrapper taskProgress = new ReadOnlyDoubleWrapper(-1);
|
||||||
private final ReadOnlyStringWrapper taskMessage = new ReadOnlyStringWrapper();
|
private final ReadOnlyStringWrapper taskMessage = new ReadOnlyStringWrapper();
|
||||||
@ -134,13 +137,17 @@ public class TimeLineController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static DateTimeZone getJodaTimeZone() {
|
public static DateTimeZone getJodaTimeZone() {
|
||||||
return DateTimeZone.forTimeZone(getTimeZone().get());
|
return DateTimeZone.forTimeZone(timeZoneProperty().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReadOnlyObjectProperty<TimeZone> getTimeZone() {
|
public static ReadOnlyObjectProperty<TimeZone> timeZoneProperty() {
|
||||||
return timeZone.getReadOnlyProperty();
|
return timeZone.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TimeZone getTimeZone() {
|
||||||
|
return timeZone.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status is a string that will be displayed in the status bar as a kind of
|
* Status is a string that will be displayed in the status bar as a kind of
|
||||||
* user hint/information when it is not empty
|
* user hint/information when it is not empty
|
||||||
|
@ -281,7 +281,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
|||||||
Platform.runLater(this::initFXComponents);
|
Platform.runLater(this::initFXComponents);
|
||||||
|
|
||||||
//set up listeners
|
//set up listeners
|
||||||
TimeLineController.getTimeZone().addListener(timeZone -> dataResultPanel.setPath(getResultViewerSummaryString()));
|
TimeLineController.timeZoneProperty().addListener(timeZone -> dataResultPanel.setPath(getResultViewerSummaryString()));
|
||||||
controller.getSelectedEventIDs().addListener(selectedEventsListener);
|
controller.getSelectedEventIDs().addListener(selectedEventsListener);
|
||||||
|
|
||||||
//Listen to ViewMode and adjust GUI componenets as needed.
|
//Listen to ViewMode and adjust GUI componenets as needed.
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.actions;
|
package org.sleuthkit.autopsy.timeline.actions;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -88,6 +90,10 @@ public class AddManualEvent extends Action {
|
|||||||
"CreateManualEvent.text=Add Event",
|
"CreateManualEvent.text=Add Event",
|
||||||
"CreateManualEvent.longText=Manually add an event to the timeline."})
|
"CreateManualEvent.longText=Manually add an event to the timeline."})
|
||||||
public AddManualEvent(TimeLineController controller) {
|
public AddManualEvent(TimeLineController controller) {
|
||||||
|
this(controller, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddManualEvent(TimeLineController controller, long epochMillis) {
|
||||||
super(Bundle.CreateManualEvent_text());
|
super(Bundle.CreateManualEvent_text());
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
setGraphic(new ImageView(ADD_EVENT_IMAGE));
|
setGraphic(new ImageView(ADD_EVENT_IMAGE));
|
||||||
@ -95,7 +101,7 @@ public class AddManualEvent extends Action {
|
|||||||
|
|
||||||
setEventHandler(actionEvent -> {
|
setEventHandler(actionEvent -> {
|
||||||
//shoe the dialog and if it completed normally add the event.
|
//shoe the dialog and if it completed normally add the event.
|
||||||
new EventCreationDialog(controller).showAndWait().ifPresent(this::addEvent);
|
new EventCreationDialog(controller, epochMillis).showAndWait().ifPresent(this::addEvent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,8 +153,8 @@ public class AddManualEvent extends Action {
|
|||||||
*/
|
*/
|
||||||
private final EventCreationDialogPane eventCreationDialogPane;
|
private final EventCreationDialogPane eventCreationDialogPane;
|
||||||
|
|
||||||
EventCreationDialog(TimeLineController controller) {
|
EventCreationDialog(TimeLineController controller, long epochMillis) {
|
||||||
this.eventCreationDialogPane = new EventCreationDialogPane(controller);
|
this.eventCreationDialogPane = new EventCreationDialogPane(controller, epochMillis);
|
||||||
setTitle("Add Event");
|
setTitle("Add Event");
|
||||||
setDialogPane(eventCreationDialogPane);
|
setDialogPane(eventCreationDialogPane);
|
||||||
|
|
||||||
@ -187,9 +193,10 @@ public class AddManualEvent extends Action {
|
|||||||
private final ValidationSupport validationSupport = new ValidationSupport();
|
private final ValidationSupport validationSupport = new ValidationSupport();
|
||||||
private final TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
|
|
||||||
EventCreationDialogPane(TimeLineController controller) {
|
EventCreationDialogPane(TimeLineController controller, long epochMillis) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
FXMLConstructor.construct(this, "EventCreationDialog.fxml");
|
FXMLConstructor.construct(this, "EventCreationDialog.fxml");
|
||||||
|
timePicker.setLocalDateTime( LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMillis) , TimeLineController.getTimeZoneID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -198,11 +205,9 @@ public class AddManualEvent extends Action {
|
|||||||
assert descriptionTextField != null : "fx:id=\"descriptionTextField\" was not injected: check your FXML file 'EventCreationDialog.fxml'.";
|
assert descriptionTextField != null : "fx:id=\"descriptionTextField\" was not injected: check your FXML file 'EventCreationDialog.fxml'.";
|
||||||
|
|
||||||
timeZoneChooser.getItems().setAll(timeZoneList);
|
timeZoneChooser.getItems().setAll(timeZoneList);
|
||||||
timeZoneChooser.getSelectionModel().select(TimeZoneUtils.createTimeZoneString(TimeZone.getDefault()));
|
timeZoneChooser.getSelectionModel().select(TimeZoneUtils.createTimeZoneString(TimeLineController.getTimeZone()));
|
||||||
TextFields.bindAutoCompletion(timeZoneChooser.getEditor(), timeZoneList);
|
TextFields.bindAutoCompletion(timeZoneChooser.getEditor(), timeZoneList);
|
||||||
|
|
||||||
timePicker.setLocalDateTime(LocalDateTime.now());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dataSourceChooser.getItems().setAll(controller.getAutopsyCase().getSleuthkitCase().getDataSources());
|
dataSourceChooser.getItems().setAll(controller.getAutopsyCase().getSleuthkitCase().getDataSources());
|
||||||
dataSourceChooser.getSelectionModel().select(0);
|
dataSourceChooser.getSelectionModel().select(0);
|
||||||
|
@ -184,7 +184,7 @@ public class EventNode extends DisplayableItemNode {
|
|||||||
super(name, String.class, displayName, shortDescription);
|
super(name, String.class, displayName, shortDescription);
|
||||||
setValue("suppressCustomEditor", Boolean.TRUE); // remove the "..." (editing) button NON-NLS
|
setValue("suppressCustomEditor", Boolean.TRUE); // remove the "..." (editing) button NON-NLS
|
||||||
this.value = value;
|
this.value = value;
|
||||||
TimeLineController.getTimeZone().addListener(timeZone -> {
|
TimeLineController.timeZoneProperty().addListener(timeZone -> {
|
||||||
try {
|
try {
|
||||||
setValue(getDateTimeString());
|
setValue(getDateTimeString());
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
|
||||||
|
@ -87,7 +87,7 @@ public abstract class AbstractTimeLineView extends BorderPane {
|
|||||||
this.filteredEvents = controller.getEventsModel();
|
this.filteredEvents = controller.getEventsModel();
|
||||||
this.filteredEvents.registerForEvents(this);
|
this.filteredEvents.registerForEvents(this);
|
||||||
this.filteredEvents.zoomStateProperty().addListener(updateListener);
|
this.filteredEvents.zoomStateProperty().addListener(updateListener);
|
||||||
TimeLineController.getTimeZone().addListener(updateListener);
|
TimeLineController.timeZoneProperty().addListener(updateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,7 +225,7 @@ public abstract class AbstractTimeLineView extends BorderPane {
|
|||||||
}
|
}
|
||||||
//remvoe and gc updateListener
|
//remvoe and gc updateListener
|
||||||
this.filteredEvents.zoomStateProperty().removeListener(updateListener);
|
this.filteredEvents.zoomStateProperty().removeListener(updateListener);
|
||||||
TimeLineController.getTimeZone().removeListener(updateListener);
|
TimeLineController.timeZoneProperty().removeListener(updateListener);
|
||||||
updateListener = null;
|
updateListener = null;
|
||||||
filteredEvents.unRegisterForEvents(this);
|
filteredEvents.unRegisterForEvents(this);
|
||||||
controller.unRegisterForEvents(this);
|
controller.unRegisterForEvents(this);
|
||||||
|
@ -293,8 +293,8 @@ public abstract class IntervalSelector<X> extends BorderPane {
|
|||||||
return getValueForDisplay(getBoundsInParent().getMinX());
|
return getValueForDisplay(getBoundsInParent().getMinX());
|
||||||
}
|
}
|
||||||
|
|
||||||
private X getValueForDisplay(final double display) {
|
private X getValueForDisplay(final double displayX) {
|
||||||
return chart.getXAxis().getValueForDisplay(chart.getXAxis().parentToLocal(display, 0).getX());
|
return chart.getXAxis().getValueForDisplay(chart.getXAxis().parentToLocal(displayX, 0).getX());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +68,7 @@ public interface TimeLineChart<X> extends ContextMenuProvider, IntervalSelectorP
|
|||||||
@Override
|
@Override
|
||||||
public TimeLineController getController();
|
public TimeLineController getController();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drag handler class used by TimeLineCharts to create IntervalSelectors
|
* Drag handler class used by TimeLineCharts to create IntervalSelectors
|
||||||
*
|
*
|
||||||
|
@ -424,7 +424,7 @@ final public class ViewFrame extends BorderPane {
|
|||||||
filteredEvents.registerForEvents(this);
|
filteredEvents.registerForEvents(this);
|
||||||
|
|
||||||
//listen for changes in the time range / zoom params
|
//listen for changes in the time range / zoom params
|
||||||
TimeLineController.getTimeZone().addListener(timeZoneProp -> refreshTimeUI());
|
TimeLineController.timeZoneProperty().addListener(timeZoneProp -> refreshTimeUI());
|
||||||
filteredEvents.timeRangeProperty().addListener(timeRangeProp -> refreshTimeUI());
|
filteredEvents.timeRangeProperty().addListener(timeRangeProp -> refreshTimeUI());
|
||||||
filteredEvents.zoomStateProperty().addListener(zoomListener);
|
filteredEvents.zoomStateProperty().addListener(zoomListener);
|
||||||
refreshTimeUI(); //populate the view
|
refreshTimeUI(); //populate the view
|
||||||
|
@ -395,7 +395,7 @@ final public class DetailViewPane extends AbstractTimelineChart<DateTime, EventS
|
|||||||
ZoomState newZoom = eventsModel.getZoomState();
|
ZoomState newZoom = eventsModel.getZoomState();
|
||||||
|
|
||||||
//if the ZoomState haven't actually changed, just bail
|
//if the ZoomState haven't actually changed, just bail
|
||||||
if (Objects.equals(currentZoom, newZoom)) {
|
if (needsRefresh() == false && Objects.equals(currentZoom, newZoom)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.ui.detailview;
|
package org.sleuthkit.autopsy.timeline.ui.detailview;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@ -45,6 +46,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.timeline.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.FilteredEventsModel;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
|
import org.sleuthkit.autopsy.timeline.actions.AddManualEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.IntervalSelector;
|
import org.sleuthkit.autopsy.timeline.ui.IntervalSelector;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent;
|
import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent;
|
||||||
@ -276,9 +278,12 @@ final class DetailsChart extends Control implements TimeLineChart<DateTime> {
|
|||||||
contextMenu.hide();
|
contextMenu.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long selectedTimeMillis = getXAxis().getValueForDisplay(getXAxis().parentToLocal(mouseEvent.getX(), 0).getX()).getMillis();
|
||||||
|
|
||||||
//make and assign a new context menu based on the given mouseEvent
|
//make and assign a new context menu based on the given mouseEvent
|
||||||
setContextMenu(ActionUtils.createContextMenu(Arrays.asList(
|
setContextMenu(ActionUtils.createContextMenu(Arrays.asList(
|
||||||
new PlaceMarkerAction(this, mouseEvent),
|
new PlaceMarkerAction(this, mouseEvent),
|
||||||
|
new AddManualEvent(controller, selectedTimeMillis),
|
||||||
ActionUtils.ACTION_SEPARATOR,
|
ActionUtils.ACTION_SEPARATOR,
|
||||||
TimeLineChart.newZoomHistoyActionGroup(getController())
|
TimeLineChart.newZoomHistoyActionGroup(getController())
|
||||||
)));
|
)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user