rename ShowFileInTimelineAction an ShowArtifactInTimelineAction to View... ; split file and artifact constructors for ShowInTimelineDialog

This commit is contained in:
jmillman 2016-06-10 12:30:17 -04:00
parent e6c9274cfe
commit ac3d88e808
6 changed files with 93 additions and 70 deletions

View File

@ -35,8 +35,8 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import static org.sleuthkit.autopsy.datamodel.Bundle.*;
import org.sleuthkit.autopsy.timeline.actions.ShowArtifactInTimelineAction;
import org.sleuthkit.autopsy.timeline.actions.ShowFileInTimelineAction;
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -131,14 +131,14 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
}
if (hasTimeStamp) {
//if this artifact has a time stamp add the action to view it in the timeline
actionsList.add(new ShowArtifactInTimelineAction(artifact));
actionsList.add(new ViewArtifactInTimelineAction(artifact));
}
AbstractFile file = getLookup().lookup(AbstractFile.class);
if (null != file) {
//if this artifact has associated content, add the action to view the content in the timeline
actionsList.add(new ShowFileInTimelineAction(file));
actionsList.add(new ViewFileInTimelineAction(file, true));
}
return actionsList.toArray(new Action[actionsList.size()]);

View File

@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.autopsy.timeline.actions.ShowFileInTimelineAction;
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
@ -86,7 +86,7 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
}
actionsList.add(new NewWindowViewAction(Bundle.FileNode_getActions_viewInNewWin_text(), this));
actionsList.add(new ExternalViewerAction(Bundle.FileNode_getActions_openInExtViewer_text(), this));
actionsList.add(new ShowFileInTimelineAction(getContent()));
actionsList.add(new ViewFileInTimelineAction(getContent(), false));
actionsList.add(null); // creates a menu separator
actionsList.add(ExtractAction.getInstance());

View File

@ -49,6 +49,7 @@ import javafx.scene.layout.VBox;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;
import org.joda.time.Interval;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
@ -57,14 +58,17 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
*
* A Dialog that, given a AbstractFile OR BlackBoardArtifact, allows the user to
* choose a specific event and a time range around it to show in the Timeline
* List View.
*/
public class ShowInTimelineDialog extends Dialog<ShowInTimelineDialog.EventInTimeRange> {
private static final ButtonType SHOW = new ButtonType("Show Timeline", ButtonBar.ButtonData.OK_DONE);
final class ShowInTimelineDialog extends Dialog<ShowInTimelineDialog.EventInTimeRange> {
private static final Logger LOGGER = Logger.getLogger(ShowInTimelineDialog.class.getName());
@NbBundle.Messages({"ShowInTimelineDialog.showTimelineButtonType.text=Show Timeline"})
private static final ButtonType SHOW = new ButtonType(Bundle.ShowInTimelineDialog_showTimelineButtonType_text(), ButtonBar.ButtonData.OK_DONE);
@FXML
private TableView<SingleEvent> eventTable;
@ -79,12 +83,18 @@ public class ShowInTimelineDialog extends Dialog<ShowInTimelineDialog.EventInTim
@FXML
private ComboBox<ChronoUnit> unitComboBox;
@FXML
private Label chooseEventLabel;
private final VBox contentRoot;
private final VBox contentRoot = new VBox();
private final TimeLineController controller;
/**
* List of ChronoUnits the user can select from when choosing a time range
* to show.
*/
private static final List<ChronoUnit> SCROLL_BY_UNITS = Arrays.asList(
ChronoUnit.YEARS,
ChronoUnit.MONTHS,
@ -93,24 +103,9 @@ public class ShowInTimelineDialog extends Dialog<ShowInTimelineDialog.EventInTim
ChronoUnit.MINUTES,
ChronoUnit.SECONDS);
static private class ChronoUnitListCell extends ListCell<ChronoUnit> {
@Override
protected void updateItem(ChronoUnit item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(WordUtils.capitalizeFully(item.toString()));
}
}
}
public ShowInTimelineDialog(TimeLineController controller, AbstractFile file, BlackboardArtifact artifact) {
super();
private ShowInTimelineDialog(TimeLineController controller, List<Long> eventIDS) {
this.controller = controller;
contentRoot = new VBox();
final String name = "nbres:/" + StringUtils.replace(ShowInTimelineDialog.class.getPackage().getName(), ".", "/") + "/ShowInTimelineDialog.fxml"; // NON-NLS
try {
@ -132,22 +127,6 @@ public class ShowInTimelineDialog extends Dialog<ShowInTimelineDialog.EventInTim
dialogPane.setContent(contentRoot);
dialogPane.getButtonTypes().setAll(SHOW, ButtonType.CANCEL);
setResultConverter(buttonType -> {
if (buttonType == SHOW) {
SingleEvent selectedEvent = eventTable.getSelectionModel().getSelectedItem();
if (file == null) {
selectedEvent = eventTable.getItems().get(0);
}
Duration selectedDuration = Duration.of(amountSpinner.getValue(), unitComboBox.getSelectionModel().getSelectedItem());
Interval range = IntervalUtils.getIntervalAround(Instant.ofEpochMilli(selectedEvent.getStartMillis()), selectedDuration);
return new EventInTimeRange(Collections.singleton(selectedEvent.getEventID()), range);
} else {
return null;
}
});
amountSpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 1000));
unitComboBox.setButtonCell(new ChronoUnitListCell());
@ -161,26 +140,64 @@ public class ShowInTimelineDialog extends Dialog<ShowInTimelineDialog.EventInTim
dateTimeColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue().getStartMillis()));
dateTimeColumn.setCellFactory(param -> new DateTimeTableCell<>());
List<Long> eventIDS;
if (file != null) {
eventIDS = controller.getEventsModel().getEventIDsForFile(file, false);
dialogPane.lookupButton(SHOW).disableProperty().bind(eventTable.getSelectionModel().selectedItemProperty().isNull());
} else if (artifact != null) {
eventIDS = controller.getEventsModel().getEventIDsForArtifact(artifact);
} else {
throw new IllegalArgumentException();
}
setResizable(true);
eventTable.getItems().setAll(eventIDS.stream().map(controller.getEventsModel()::getEventById).collect(Collectors.toSet()));
if (eventIDS.size() == 1) {
chooseEventLabel.setVisible(false);
chooseEventLabel.setManaged(false);
eventTable.getSelectionModel().select(0);
}
eventTable.setPrefHeight(Math.min(200, 24 * eventTable.getItems().size() + 28));
}
ShowInTimelineDialog(TimeLineController controller, BlackboardArtifact artifact) {
this(controller,
controller.getEventsModel().getEventIDsForArtifact(artifact));
chooseEventLabel.setVisible(false);
chooseEventLabel.setManaged(false);
eventTable.getSelectionModel().select(0);
setResultConverter(buttonType -> {
if (buttonType == SHOW) {
SingleEvent selectedEvent = eventTable.getSelectionModel().getSelectedItem();
if (selectedEvent == null) {
selectedEvent = eventTable.getItems().get(0);
}
return makeEventInTimeRange(selectedEvent);
} else {
return null;
}
});
}
ShowInTimelineDialog(TimeLineController controller, AbstractFile file) {
this(controller,
controller.getEventsModel().getEventIDsForFile(file, false));
getDialogPane().lookupButton(SHOW).disableProperty().bind(eventTable.getSelectionModel().selectedItemProperty().isNull());
setResultConverter(buttonType -> {
if (buttonType == SHOW) {
return makeEventInTimeRange(eventTable.getSelectionModel().getSelectedItem());
} else {
return null;
}
});
}
private EventInTimeRange makeEventInTimeRange(SingleEvent selectedEvent) {
Duration selectedDuration = Duration.of(amountSpinner.getValue(), unitComboBox.getSelectionModel().getSelectedItem());
Interval range = IntervalUtils.getIntervalAround(Instant.ofEpochMilli(selectedEvent.getStartMillis()), selectedDuration);
return new EventInTimeRange(Collections.singleton(selectedEvent.getEventID()), range);
}
static private class ChronoUnitListCell extends ListCell<ChronoUnit> {
@Override
protected void updateItem(ChronoUnit item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(WordUtils.capitalizeFully(item.toString()));
}
}
}
static private class DateTimeTableCell<X> extends TableCell<X, Long> {
@Override

View File

@ -418,7 +418,8 @@ public class TimeLineController {
}
//get a task that rebuilds the repo with the bellow state listener attached
final CancellationProgressTask<?> rebuildRepositoryTask = repoBuilder.apply(newSate -> {
final CancellationProgressTask<?> rebuildRepositoryTask;
rebuildRepositoryTask = repoBuilder.apply(newSate -> {
//this will be on JFX thread
switch (newSate) {
case SUCCEEDED:
@ -443,7 +444,9 @@ public class TimeLineController {
SwingUtilities.invokeLater(this::showWindow);
TimeLineController.this.showFullRange();
} else {
ShowInTimelineDialog d = new ShowInTimelineDialog(this, file, artifact);
ShowInTimelineDialog d = (file == null)
? new ShowInTimelineDialog(this, artifact)
: new ShowInTimelineDialog(this, file);
Optional<ShowInTimelineDialog.EventInTimeRange> result = d.showAndWait();
result.ifPresent(eventInTimeRange -> {

View File

@ -28,14 +28,14 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
/**
* An action that shows the given artifact in the Timeline List View.
*/
public final class ShowArtifactInTimelineAction extends AbstractAction {
public final class ViewArtifactInTimelineAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final BlackboardArtifact artifact;
@NbBundle.Messages({"ShowArtifactInTimelineAction.displayName=Show Result in Timeline... "})
public ShowArtifactInTimelineAction(BlackboardArtifact artifact) {
super(Bundle.ShowArtifactInTimelineAction_displayName());
@NbBundle.Messages({"ViewArtifactInTimelineAction.displayName=View Result in Timeline... "})
public ViewArtifactInTimelineAction(BlackboardArtifact artifact) {
super(Bundle.ViewArtifactInTimelineAction_displayName());
this.artifact = artifact;
}

View File

@ -29,14 +29,17 @@ import org.sleuthkit.datamodel.AbstractFile;
* An action to prompt the user to pick an timestamp/event associated with the
* given file and show it in the Timeline List View
*/
public final class ShowFileInTimelineAction extends AbstractAction {
public final class ViewFileInTimelineAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final AbstractFile file;
@NbBundle.Messages({"ShowFileInTimelineAction.displayName=Show File in Timeline... "})
public ShowFileInTimelineAction(AbstractFile file) {
super(Bundle.ShowFileInTimelineAction_displayName());
@NbBundle.Messages({"ViewFileInTimelineAction.fileSource.displayName=View File in Timeline... ",
"ViewFileInTimelineAction.artifactSource.displayName=View Source File in Timeline... "})
public ViewFileInTimelineAction(AbstractFile file, boolean isArtifactSource) {
super(isArtifactSource
? Bundle.ViewFileInTimelineAction_artifactSource_displayName()
: Bundle.ViewFileInTimelineAction_fileSource_displayName());
this.file = file;
}