19 package org.sleuthkit.autopsy.timeline.actions;
21 import java.awt.Desktop;
22 import java.awt.image.BufferedImage;
23 import java.io.IOException;
24 import java.nio.file.InvalidPathException;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.text.SimpleDateFormat;
28 import java.util.Date;
29 import java.util.function.Supplier;
30 import java.util.logging.Level;
31 import javafx.embed.swing.SwingFXUtils;
32 import javafx.scene.Node;
33 import javafx.scene.control.Alert;
34 import javafx.scene.control.ButtonBar;
35 import javafx.scene.control.ButtonType;
36 import javafx.scene.image.Image;
37 import javafx.scene.image.ImageView;
38 import javax.swing.JOptionPane;
39 import javax.swing.SwingUtilities;
40 import org.apache.commons.lang3.StringUtils;
41 import org.controlsfx.control.action.Action;
42 import org.openide.util.NbBundle;
43 import org.openide.windows.WindowManager;
60 private static final Image
SNAP_SHOT =
new Image(
"org/sleuthkit/autopsy/timeline/images/image.png", 16, 16,
true,
true);
61 private static final ButtonType
OK =
new ButtonType(ButtonType.OK.getText(), ButtonBar.ButtonData.CANCEL_CLOSE);
72 "Timeline.ModuleName=Timeline",
73 "SaveSnapShotAsReport.action.dialogs.title=Timeline",
74 "SaveSnapShotAsReport.action.name.text=Snapshot Report",
75 "SaveSnapShotAsReport.action.longText=Save a screen capture of the current view of the timeline as a report.",
76 "# {0} - report file path",
77 "SaveSnapShotAsReport.ReportSavedAt=Report saved at [{0}]",
78 "SaveSnapShotAsReport.Success=Success",
79 "SaveSnapShotAsReport.FailedToAddReport=Failed to add snaphot to case as a report.",
80 "# {0} - report path",
81 "SaveSnapShotAsReport.ErrorWritingReport=Error writing report to disk at {0}.",
82 "# {0} - generated default report name",
83 "SaveSnapShotAsReport.reportName.prompt=Leave empty for default report name:\n{0}.",
84 "SaveSnapShotAsReport.reportName.header=Enter a report name for the Timeline Snapshot Report.",
85 "SaveSnapShotAsReport.duplicateReportNameError.text=A report with that name already exists.",
86 "SaveSnapShotAsReport_Report_Failed=Report failed",
87 "# {0} - supplied report name",
88 "SaveSnapShotAsReport_Path_Failure_Report=Failed to create report. Supplied report name has invalid characters: {0}",
89 "# {0} - report location",
90 "SaveSnapShotAsReport_success_message=Snapshot report successfully created at location: \n\n {0}",
91 "SaveSnapShotAsReport_Open_Button=Open Report",
92 "SaveSnapShotAsReport_OK_Button=OK"
95 super(Bundle.SaveSnapShotAsReport_action_name_text());
96 setLongText(Bundle.SaveSnapShotAsReport_action_longText());
97 setGraphic(
new ImageView(SNAP_SHOT));
101 setEventHandler(actionEvent -> {
103 Date generationDate =
new Date();
105 BufferedImage snapshot = SwingFXUtils.fromFXImage(nodeSupplier.get().snapshot(null, null), null);
107 SwingUtilities.invokeLater(() ->{
108 String message = String.format(
"%s\n\n%s", Bundle.SaveSnapShotAsReport_reportName_header(), Bundle.SaveSnapShotAsReport_reportName_prompt(defaultReportName));
110 String reportName = JOptionPane.showInputDialog(SwingUtilities.windowForComponent(controller.
getTopComponent()), message,
111 Bundle.SaveSnapShotAsReport_action_dialogs_title(), JOptionPane.QUESTION_MESSAGE);
113 if (reportName != null) {
114 reportName = StringUtils.defaultIfBlank(reportName, defaultReportName);
116 createReport(controller, reportName, generationDate, snapshot);
124 Path reportFolderPath;
126 reportFolderPath = Paths.get(currentCase.
getReportDirectory(), reportName,
"Timeline Snapshot");
127 }
catch (InvalidPathException ex) {
129 final Alert alert =
new Alert(Alert.AlertType.ERROR, null, OK);
130 alert.setTitle(Bundle.SaveSnapShotAsReport_Report_Failed());
131 alert.setHeaderText(Bundle.SaveSnapShotAsReport_Path_Failure_Report(reportName));
135 Path reportMainFilePath;
143 generationDate, snapshot).writeReport();
144 }
catch (IOException ex) {
145 LOGGER.log(Level.SEVERE,
"Error writing report to disk at " + reportFolderPath, ex);
154 LOGGER.log(Level.WARNING,
"Failed to add " + reportMainFilePath.toString() +
" to case as a report", ex);
159 Object[] options = { Bundle.SaveSnapShotAsReport_Open_Button(),
160 Bundle.SaveSnapShotAsReport_OK_Button()};
162 int result = JOptionPane.showOptionDialog(SwingUtilities.windowForComponent(controller.
getTopComponent()),
163 Bundle.SaveSnapShotAsReport_success_message(reportMainFilePath),
164 Bundle.SaveSnapShotAsReport_action_dialogs_title(),
165 JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
166 options, options[0]);
170 openReportAction.handle(null);
178 "OpenReportAction.DisplayName=Open Report",
179 "OpenReportAction.NoAssociatedEditorMessage=There is no associated editor for reports of this type or the associated application failed to launch.",
180 "OpenReportAction.MessageBoxTitle=Open Report Failure",
181 "OpenReportAction.NoOpenInEditorSupportMessage=This platform (operating system) does not support opening a file in an editor this way.",
182 "OpenReportAction.MissingReportFileMessage=The report file no longer exists.",
183 "OpenReportAction.ReportFileOpenPermissionDeniedMessage=Permission to open the report file was denied."})
187 super(Bundle.OpenReportAction_DisplayName());
188 setEventHandler(actionEvent -> {
190 Desktop.getDesktop().open(reportHTMLFIle.toFile());
191 }
catch (IOException ex) {
192 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
193 Bundle.OpenReportAction_NoAssociatedEditorMessage(),
194 Bundle.OpenReportAction_MessageBoxTitle(),
195 JOptionPane.ERROR_MESSAGE);
196 }
catch (UnsupportedOperationException ex) {
197 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
198 Bundle.OpenReportAction_NoOpenInEditorSupportMessage(),
199 Bundle.OpenReportAction_MessageBoxTitle(),
200 JOptionPane.ERROR_MESSAGE);
201 }
catch (IllegalArgumentException ex) {
202 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
203 Bundle.OpenReportAction_MissingReportFileMessage(),
204 Bundle.OpenReportAction_MessageBoxTitle(),
205 JOptionPane.ERROR_MESSAGE);
206 }
catch (SecurityException ex) {
207 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
208 Bundle.OpenReportAction_ReportFileOpenPermissionDeniedMessage(),
209 Bundle.OpenReportAction_MessageBoxTitle(),
210 JOptionPane.ERROR_MESSAGE);
static final Logger LOGGER
static final Image SNAP_SHOT
void createReport(TimeLineController controller, String reportName, Date generationDate, BufferedImage snapshot)
String getReportDirectory()
synchronized EventsModelParams getModelParams()
void addReport(String localPath, String srcModuleName, String reportName)
SaveSnapshotAsReport(TimeLineController controller, Supplier< Node > nodeSupplier)
synchronized TimeLineTopComponent getTopComponent()
EventsModel getEventsModel()
static String escapeFileName(String fileName)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static final ButtonType OK
static void error(String message)