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 reportName = StringUtils.defaultIfBlank(reportName, defaultReportName);
115 createReport(controller, reportName, generationDate, snapshot);
122 Path reportFolderPath;
124 reportFolderPath = Paths.get(currentCase.
getReportDirectory(), reportName,
"Timeline Snapshot");
125 }
catch (InvalidPathException ex) {
127 final Alert alert =
new Alert(Alert.AlertType.ERROR, null, OK);
128 alert.setTitle(Bundle.SaveSnapShotAsReport_Report_Failed());
129 alert.setHeaderText(Bundle.SaveSnapShotAsReport_Path_Failure_Report(reportName));
133 Path reportMainFilePath;
141 generationDate, snapshot).writeReport();
142 }
catch (IOException ex) {
143 LOGGER.log(Level.SEVERE,
"Error writing report to disk at " + reportFolderPath, ex);
152 LOGGER.log(Level.WARNING,
"Failed to add " + reportMainFilePath.toString() +
" to case as a report", ex);
157 Object[] options = { Bundle.SaveSnapShotAsReport_Open_Button(),
158 Bundle.SaveSnapShotAsReport_OK_Button()};
160 int result = JOptionPane.showOptionDialog(SwingUtilities.windowForComponent(controller.
getTopComponent()),
161 Bundle.SaveSnapShotAsReport_success_message(reportMainFilePath),
162 Bundle.SaveSnapShotAsReport_action_dialogs_title(),
163 JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
164 options, options[0]);
168 openReportAction.handle(null);
176 "OpenReportAction.DisplayName=Open Report",
177 "OpenReportAction.NoAssociatedEditorMessage=There is no associated editor for reports of this type or the associated application failed to launch.",
178 "OpenReportAction.MessageBoxTitle=Open Report Failure",
179 "OpenReportAction.NoOpenInEditorSupportMessage=This platform (operating system) does not support opening a file in an editor this way.",
180 "OpenReportAction.MissingReportFileMessage=The report file no longer exists.",
181 "OpenReportAction.ReportFileOpenPermissionDeniedMessage=Permission to open the report file was denied."})
185 super(Bundle.OpenReportAction_DisplayName());
186 setEventHandler(actionEvent -> {
188 Desktop.getDesktop().open(reportHTMLFIle.toFile());
189 }
catch (IOException ex) {
190 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
191 Bundle.OpenReportAction_NoAssociatedEditorMessage(),
192 Bundle.OpenReportAction_MessageBoxTitle(),
193 JOptionPane.ERROR_MESSAGE);
194 }
catch (UnsupportedOperationException ex) {
195 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
196 Bundle.OpenReportAction_NoOpenInEditorSupportMessage(),
197 Bundle.OpenReportAction_MessageBoxTitle(),
198 JOptionPane.ERROR_MESSAGE);
199 }
catch (IllegalArgumentException ex) {
200 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
201 Bundle.OpenReportAction_MissingReportFileMessage(),
202 Bundle.OpenReportAction_MessageBoxTitle(),
203 JOptionPane.ERROR_MESSAGE);
204 }
catch (SecurityException ex) {
205 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
206 Bundle.OpenReportAction_ReportFileOpenPermissionDeniedMessage(),
207 Bundle.OpenReportAction_MessageBoxTitle(),
208 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)