add right click menu option to add event with datetime prepopulated;

other small cleanup and refactoring
This commit is contained in:
millmanorama 2019-03-05 16:30:52 +01:00
parent 397f9694ee
commit aecc229345
10 changed files with 36 additions and 18 deletions

View File

@ -23,6 +23,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeEvent;
import java.time.ZoneId;
import java.util.Collection;
@ -32,6 +33,7 @@ import java.util.Optional;
import java.util.TimeZone;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import javafx.application.Platform;
import javafx.beans.Observable;
@ -116,7 +118,8 @@ public class TimeLineController {
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 ReadOnlyDoubleWrapper taskProgress = new ReadOnlyDoubleWrapper(-1);
private final ReadOnlyStringWrapper taskMessage = new ReadOnlyStringWrapper();
@ -134,13 +137,17 @@ public class TimeLineController {
}
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();
}
public static TimeZone getTimeZone() {
return timeZone.get();
}
/**
* Status is a string that will be displayed in the status bar as a kind of
* user hint/information when it is not empty

View File

@ -281,7 +281,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
Platform.runLater(this::initFXComponents);
//set up listeners
TimeLineController.getTimeZone().addListener(timeZone -> dataResultPanel.setPath(getResultViewerSummaryString()));
TimeLineController.timeZoneProperty().addListener(timeZone -> dataResultPanel.setPath(getResultViewerSummaryString()));
controller.getSelectedEventIDs().addListener(selectedEventsListener);
//Listen to ViewMode and adjust GUI componenets as needed.

View File

@ -18,8 +18,10 @@
*/
package org.sleuthkit.autopsy.timeline.actions;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@ -88,6 +90,10 @@ public class AddManualEvent extends Action {
"CreateManualEvent.text=Add Event",
"CreateManualEvent.longText=Manually add an event to the timeline."})
public AddManualEvent(TimeLineController controller) {
this(controller, System.currentTimeMillis());
}
public AddManualEvent(TimeLineController controller, long epochMillis) {
super(Bundle.CreateManualEvent_text());
this.controller = controller;
setGraphic(new ImageView(ADD_EVENT_IMAGE));
@ -95,7 +101,7 @@ public class AddManualEvent extends Action {
setEventHandler(actionEvent -> {
//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;
EventCreationDialog(TimeLineController controller) {
this.eventCreationDialogPane = new EventCreationDialogPane(controller);
EventCreationDialog(TimeLineController controller, long epochMillis) {
this.eventCreationDialogPane = new EventCreationDialogPane(controller, epochMillis);
setTitle("Add Event");
setDialogPane(eventCreationDialogPane);
@ -187,9 +193,10 @@ public class AddManualEvent extends Action {
private final ValidationSupport validationSupport = new ValidationSupport();
private final TimeLineController controller;
EventCreationDialogPane(TimeLineController controller) {
EventCreationDialogPane(TimeLineController controller, long epochMillis) {
this.controller = controller;
FXMLConstructor.construct(this, "EventCreationDialog.fxml");
timePicker.setLocalDateTime( LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMillis) , TimeLineController.getTimeZoneID()));
}
@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'.";
timeZoneChooser.getItems().setAll(timeZoneList);
timeZoneChooser.getSelectionModel().select(TimeZoneUtils.createTimeZoneString(TimeZone.getDefault()));
timeZoneChooser.getSelectionModel().select(TimeZoneUtils.createTimeZoneString(TimeLineController.getTimeZone()));
TextFields.bindAutoCompletion(timeZoneChooser.getEditor(), timeZoneList);
timePicker.setLocalDateTime(LocalDateTime.now());
try {
dataSourceChooser.getItems().setAll(controller.getAutopsyCase().getSleuthkitCase().getDataSources());
dataSourceChooser.getSelectionModel().select(0);

View File

@ -184,7 +184,7 @@ public class EventNode extends DisplayableItemNode {
super(name, String.class, displayName, shortDescription);
setValue("suppressCustomEditor", Boolean.TRUE); // remove the "..." (editing) button NON-NLS
this.value = value;
TimeLineController.getTimeZone().addListener(timeZone -> {
TimeLineController.timeZoneProperty().addListener(timeZone -> {
try {
setValue(getDateTimeString());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {

View File

@ -87,7 +87,7 @@ public abstract class AbstractTimeLineView extends BorderPane {
this.filteredEvents = controller.getEventsModel();
this.filteredEvents.registerForEvents(this);
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
this.filteredEvents.zoomStateProperty().removeListener(updateListener);
TimeLineController.getTimeZone().removeListener(updateListener);
TimeLineController.timeZoneProperty().removeListener(updateListener);
updateListener = null;
filteredEvents.unRegisterForEvents(this);
controller.unRegisterForEvents(this);

View File

@ -293,8 +293,8 @@ public abstract class IntervalSelector<X> extends BorderPane {
return getValueForDisplay(getBoundsInParent().getMinX());
}
private X getValueForDisplay(final double display) {
return chart.getXAxis().getValueForDisplay(chart.getXAxis().parentToLocal(display, 0).getX());
private X getValueForDisplay(final double displayX) {
return chart.getXAxis().getValueForDisplay(chart.getXAxis().parentToLocal(displayX, 0).getX());
}
/**

View File

@ -68,6 +68,7 @@ public interface TimeLineChart<X> extends ContextMenuProvider, IntervalSelectorP
@Override
public TimeLineController getController();
/**
* Drag handler class used by TimeLineCharts to create IntervalSelectors
*

View File

@ -424,7 +424,7 @@ final public class ViewFrame extends BorderPane {
filteredEvents.registerForEvents(this);
//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.zoomStateProperty().addListener(zoomListener);
refreshTimeUI(); //populate the view

View File

@ -395,7 +395,7 @@ final public class DetailViewPane extends AbstractTimelineChart<DateTime, EventS
ZoomState newZoom = eventsModel.getZoomState();
//if the ZoomState haven't actually changed, just bail
if (Objects.equals(currentZoom, newZoom)) {
if (needsRefresh() == false && Objects.equals(currentZoom, newZoom)) {
return true;
}

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.timeline.ui.detailview;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.MissingResourceException;
import java.util.function.Predicate;
@ -45,6 +46,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.timeline.FilteredEventsModel;
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.TimeLineChart;
import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent;
@ -276,9 +278,12 @@ final class DetailsChart extends Control implements TimeLineChart<DateTime> {
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
setContextMenu(ActionUtils.createContextMenu(Arrays.asList(
new PlaceMarkerAction(this, mouseEvent),
new AddManualEvent(controller, selectedTimeMillis),
ActionUtils.ACTION_SEPARATOR,
TimeLineChart.newZoomHistoyActionGroup(getController())
)));