timeline time range fix

This commit is contained in:
Greg DiCristofaro 2020-11-23 13:32:49 -05:00
parent 27c6283959
commit e015b93eb5
3 changed files with 86 additions and 53 deletions

View File

@ -31,6 +31,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Interval; import org.joda.time.Interval;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TimelineDataSourceUtils; import org.sleuthkit.autopsy.datasourcesummary.datamodel.TimelineDataSourceUtils;
@ -86,7 +87,6 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
private final LoadableLabel earliestLabel = new LoadableLabel(Bundle.TimelinePanel_earliestLabel_title()); private final LoadableLabel earliestLabel = new LoadableLabel(Bundle.TimelinePanel_earliestLabel_title());
private final LoadableLabel latestLabel = new LoadableLabel(Bundle.TimelinePanel_latestLabel_title()); private final LoadableLabel latestLabel = new LoadableLabel(Bundle.TimelinePanel_latestLabel_title());
private final BarChartPanel last30DaysChart = new BarChartPanel(Bundle.TimlinePanel_last30DaysChart_title(), "", ""); private final BarChartPanel last30DaysChart = new BarChartPanel(Bundle.TimlinePanel_last30DaysChart_title(), "", "");
private final OpenTimelineAction openTimelineAction = new OpenTimelineAction();
private final TimelineDataSourceUtils timelineUtils = TimelineDataSourceUtils.getInstance(); private final TimelineDataSourceUtils timelineUtils = TimelineDataSourceUtils.getInstance();
// all loadable components on this tab // all loadable components on this tab
@ -220,24 +220,45 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
} }
} }
openFilteredChart(dataSource, minDate, maxDate);
}
/**
* Action that occurs when 'View in Timeline' button is pressed.
*
* @param dataSource The data source to filter to.
* @param minDate The min date for the zoom of the window.
* @param maxDate The max date for the zoom of the window.
*/
private void openFilteredChart(DataSource dataSource, Date minDate, Date maxDate) {
OpenTimelineAction openTimelineAction = CallableSystemAction.get(OpenTimelineAction.class);
if (openTimelineAction == null) {
logger.log(Level.WARNING, "No OpenTimelineAction provided by CallableSystemAction; taking no redirect action.");
}
// notify dialog (if in dialog) should close. // notify dialog (if in dialog) should close.
TimelinePanel.this.notifyParentClose(); TimelinePanel.this.notifyParentClose();
// open the timeline filtered to data source and zoomed in on interval Interval timeSpan = null;
openTimelineAction.performAction();
try { try {
TimeLineController controller = TimeLineModule.getController(); final TimeLineController controller = TimeLineModule.getController();
if (dataSource != null) { if (dataSource != null) {
controller.pushFilters(timelineUtils.getDataSourceFilterState(dataSource)); controller.pushFilters(timelineUtils.getDataSourceFilterState(dataSource));
} }
if (minDate != null && maxDate != null) { if (minDate != null && maxDate != null) {
Interval timeSpan = new Interval(new DateTime(minDate), new DateTime(maxDate)); timeSpan = new Interval(new DateTime(minDate), new DateTime(maxDate));
controller.pushTimeRange(timeSpan); }
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.WARNING, "Unable to view time range in Timeline view", ex);
} }
} catch (NoCurrentCaseException | TskCoreException ex) { try {
logger.log(Level.WARNING, "Unable to open Timeline view", ex); openTimelineAction.showTimeline(timeSpan);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "An unexpected exception occurred while opening the timeline.", ex);
} }
} }

View File

@ -24,6 +24,7 @@ import javafx.application.Platform;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import org.joda.time.Interval;
import org.openide.awt.ActionID; import org.openide.awt.ActionID;
import org.openide.awt.ActionReference; import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences; import org.openide.awt.ActionReferences;
@ -46,13 +47,10 @@ import org.sleuthkit.datamodel.TskCoreException;
* An Action that opens the Timeline window. Has methods to open the window in * An Action that opens the Timeline window. Has methods to open the window in
* various specific states (e.g., showing a specific artifact in the List View) * various specific states (e.g., showing a specific artifact in the List View)
*/ */
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline") @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy = false) @ActionRegistration(displayName = "#CTL_MakeTimeline", lazy = false)
@ActionReferences(value = { @ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 104) @ActionReference(path = "Menu/Tools", position = 104),
,
@ActionReference(path = "Toolbars/Case", position = 104)}) @ActionReference(path = "Toolbars/Case", position = 104)})
public final class OpenTimelineAction extends CallableSystemAction { public final class OpenTimelineAction extends CallableSystemAction {
@ -64,7 +62,6 @@ public final class OpenTimelineAction extends CallableSystemAction {
private final JButton toolbarButton = new JButton(getName(), private final JButton toolbarButton = new JButton(getName(),
new ImageIcon(getClass().getResource("images/btn_icon_timeline_colorized_26.png"))); //NON-NLS new ImageIcon(getClass().getResource("images/btn_icon_timeline_colorized_26.png"))); //NON-NLS
public OpenTimelineAction() { public OpenTimelineAction() {
toolbarButton.addActionListener(actionEvent -> performAction()); toolbarButton.addActionListener(actionEvent -> performAction());
menuItem = super.getMenuPresenter(); menuItem = super.getMenuPresenter();
@ -74,9 +71,10 @@ public final class OpenTimelineAction extends CallableSystemAction {
@Override @Override
public boolean isEnabled() { public boolean isEnabled() {
/** /**
* We used to also check if Case.getCurrentOpenCase().hasData() was true. We * We used to also check if Case.getCurrentOpenCase().hasData() was
* disabled that check because if it is executed while a data source is * true. We disabled that check because if it is executed while a data
* being added, it blocks the edt. We still do that in ImageGallery. * source is being added, it blocks the edt. We still do that in
* ImageGallery.
*/ */
return super.isEnabled() && Case.isCaseOpen() && Installer.isJavaFxInited(); return super.isEnabled() && Case.isCaseOpen() && Installer.isJavaFxInited();
} }
@ -103,7 +101,7 @@ public final class OpenTimelineAction extends CallableSystemAction {
@NbBundle.Messages({ @NbBundle.Messages({
"OpenTimelineAction.settingsErrorMessage=Failed to initialize timeline settings.", "OpenTimelineAction.settingsErrorMessage=Failed to initialize timeline settings.",
"OpenTimeLineAction.msgdlg.text=Could not create timeline, there are no data sources."}) "OpenTimeLineAction.msgdlg.text=Could not create timeline, there are no data sources."})
synchronized private void showTimeline(AbstractFile file, BlackboardArtifact artifact) throws TskCoreException { synchronized private void showTimeline(AbstractFile file, BlackboardArtifact artifact, Interval timeSpan) throws TskCoreException {
try { try {
Case currentCase = Case.getCurrentCaseThrows(); Case currentCase = Case.getCurrentCaseThrows();
if (currentCase.hasData() == false) { if (currentCase.hasData() == false) {
@ -112,6 +110,15 @@ public final class OpenTimelineAction extends CallableSystemAction {
return; return;
} }
TimeLineController controller = TimeLineModule.getController(); TimeLineController controller = TimeLineModule.getController();
// if file or artifact not specified, specify the time range as either
// a) full range if timeSpan is null or b) the timeSpan
if (file == null && artifact == null) {
if (timeSpan == null) {
controller.showFullRange();
} else {
controller.pushTimeRange(timeSpan);
}
}
controller.showTimeLine(file, artifact); controller.showTimeLine(file, artifact);
} catch (NoCurrentCaseException e) { } catch (NoCurrentCaseException e) {
//there is no case... Do nothing. //there is no case... Do nothing.
@ -123,7 +130,18 @@ public final class OpenTimelineAction extends CallableSystemAction {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public void showTimeline() throws TskCoreException { public void showTimeline() throws TskCoreException {
showTimeline(null, null); showTimeline(null, null, null);
}
/**
* Open timeline with the given timeSpan time range.
*
* @param timeSpan The time range to display.
* @throws TskCoreException
*/
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public void showTimeline(Interval timeSpan) throws TskCoreException {
showTimeline(null, null, timeSpan);
} }
/** /**
@ -135,7 +153,7 @@ public final class OpenTimelineAction extends CallableSystemAction {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public void showFileInTimeline(AbstractFile file) throws TskCoreException { public void showFileInTimeline(AbstractFile file) throws TskCoreException {
showTimeline(file, null); showTimeline(file, null, null);
} }
/** /**
@ -146,7 +164,7 @@ public final class OpenTimelineAction extends CallableSystemAction {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public void showArtifactInTimeline(BlackboardArtifact artifact) throws TskCoreException { public void showArtifactInTimeline(BlackboardArtifact artifact) throws TskCoreException {
showTimeline(null, artifact); showTimeline(null, artifact, null);
} }
@Override @Override

View File

@ -62,7 +62,6 @@ import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatter;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE;
import static org.sleuthkit.autopsy.casemodule.Case.Events.DATA_SOURCE_ADDED; import static org.sleuthkit.autopsy.casemodule.Case.Events.DATA_SOURCE_ADDED;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent; import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
@ -348,7 +347,7 @@ public class TimeLineController {
/** /**
* Show the entire range of the timeline. * Show the entire range of the timeline.
*/ */
private boolean showFullRange() throws TskCoreException { boolean showFullRange() throws TskCoreException {
synchronized (filteredEvents) { synchronized (filteredEvents) {
return pushTimeRange(filteredEvents.getSpanningInterval()); return pushTimeRange(filteredEvents.getSpanningInterval());
} }
@ -376,7 +375,6 @@ public class TimeLineController {
} }
} }
/** /**
* Shuts down the task executor in charge of handling case events. * Shuts down the task executor in charge of handling case events.
*/ */
@ -395,14 +393,12 @@ public class TimeLineController {
} }
} }
/** /**
* Add the case and ingest listeners, prompt for rebuilding the database if * Add the case and ingest listeners, prompt for rebuilding the database if
* necessary, and show the timeline window. * necessary, and show the timeline window.
* *
* @param file The AbstractFile from which to choose an event to show in * @param file The AbstractFile from which to choose an event to show in the
* the List View. * List View.
* @param artifact The BlackboardArtifact to show in the List View. * @param artifact The BlackboardArtifact to show in the List View.
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@ -421,9 +417,7 @@ public class TimeLineController {
try { try {
if (file == null && artifact == null) { if (file == null && artifact == null) {
SwingUtilities.invokeLater(TimeLineController.this::showWindow); SwingUtilities.invokeLater(TimeLineController.this::showWindow);
this.showFullRange();
} else { } else {
//prompt user to pick specific event and time range //prompt user to pick specific event and time range
ShowInTimelineDialog showInTimelineDilaog = (file == null) ShowInTimelineDialog showInTimelineDilaog = (file == null)
? new ShowInTimelineDialog(this, artifact) ? new ShowInTimelineDialog(this, artifact)
@ -497,7 +491,7 @@ public class TimeLineController {
topComponent.requestActive(); topComponent.requestActive();
} }
synchronized public TimeLineTopComponent getTopComponent(){ synchronized public TimeLineTopComponent getTopComponent() {
return topComponent; return topComponent;
} }