Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 4791-ReviseIntraCaseResults

This commit is contained in:
William Schaefer 2019-03-07 13:02:46 -05:00
commit f4780fc044
17 changed files with 158 additions and 55 deletions

View File

@ -39,7 +39,7 @@ MediaFileViewer.title=Media
MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio) MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio)
MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory. MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory.
MediaViewImagePanel.errorLabel.text=Could not load file into Media View. MediaViewImagePanel.errorLabel.text=Could not load file into Media View.
MediaViewImagePanel.externalViewerButton.text=Open in External Viewer MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E
MediaViewVideoPanel.pauseButton.text=\u25ba MediaViewVideoPanel.pauseButton.text=\u25ba
MediaViewVideoPanel.progressLabel.text=00:00 MediaViewVideoPanel.progressLabel.text=00:00
MediaViewVideoPanel.infoLabel.text=info MediaViewVideoPanel.infoLabel.text=info

View File

@ -60,7 +60,7 @@ import org.sleuthkit.datamodel.AbstractFile;
* Image viewer part of the Media View layered pane. Uses JavaFX to display the * Image viewer part of the Media View layered pane. Uses JavaFX to display the
* image. * image.
*/ */
@NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer", @NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E",
"MediaViewImagePanel.errorLabel.text=Could not load file into Media View.", "MediaViewImagePanel.errorLabel.text=Could not load file into Media View.",
"MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory."}) "MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory."})
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2018 Basis Technology Corp. * Copyright 2011-2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -38,6 +38,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
/** /**
* A DataResultTopComponent object is a NetBeans top component that provides * A DataResultTopComponent object is a NetBeans top component that provides
@ -100,7 +101,7 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
DataResultTopComponent resultViewTopComponent = new DataResultTopComponent(false, title, null, Collections.emptyList(), DataContentTopComponent.findInstance()); DataResultTopComponent resultViewTopComponent = new DataResultTopComponent(false, title, null, Collections.emptyList(), DataContentTopComponent.findInstance());
initInstance(description, node, childNodeCount, resultViewTopComponent); initInstance(description, node, childNodeCount, resultViewTopComponent);
return resultViewTopComponent; return resultViewTopComponent;
} }
/** /**
* Creates a result view top component that provides multiple views of the * Creates a result view top component that provides multiple views of the
@ -147,7 +148,7 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
DataResultTopComponent resultViewTopComponent = new DataResultTopComponent(false, title, null, Collections.emptyList(), DataContentTopComponent.findInstance()); DataResultTopComponent resultViewTopComponent = new DataResultTopComponent(false, title, null, Collections.emptyList(), DataContentTopComponent.findInstance());
return resultViewTopComponent; return resultViewTopComponent;
} }
/** /**
* Initializes a partially initialized result view top component. * Initializes a partially initialized result view top component.
* *
@ -248,6 +249,9 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
setName(title); setName(title);
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(AddBookmarkTagAction.BOOKMARK_SHORTCUT, "addBookmarkTag"); //NON-NLS getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(AddBookmarkTagAction.BOOKMARK_SHORTCUT, "addBookmarkTag"); //NON-NLS
getActionMap().put("addBookmarkTag", new AddBookmarkTagAction()); //NON-NLS getActionMap().put("addBookmarkTag", new AddBookmarkTagAction()); //NON-NLS
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ExternalViewerShortcutAction.EXTERNAL_VIEWER_SHORTCUT, "useExternalViewer"); //NON-NLS
getActionMap().put("useExternalViewer", new ExternalViewerShortcutAction()); //NON-NLS
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, isMain); putClientProperty(TopComponent.PROP_CLOSING_DISABLED, isMain);
putClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED, true); putClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED, true);
putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, true); putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, true);

View File

@ -22,6 +22,8 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -31,7 +33,6 @@ import org.openide.nodes.Node;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.CasePreferences;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
@ -87,6 +88,16 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
List<DataSource> dataSources = tskCase.getDataSources(); List<DataSource> dataSources = tskCase.getDataSources();
Collections.sort(dataSources, new Comparator<DataSource>() {
@Override
public int compare(DataSource dataS1, DataSource dataS2) {
String dataS1Name = dataS1.getName().toLowerCase();
String dataS2Name = dataS2.getName().toLowerCase();
return dataS1Name.compareTo(dataS2Name);
}
});
List<DataSourceGrouping> keys = new ArrayList<>(); List<DataSourceGrouping> keys = new ArrayList<>();
dataSources.forEach((datasource) -> { dataSources.forEach((datasource) -> {
keys.add(new DataSourceGrouping(datasource)); keys.add(new DataSourceGrouping(datasource));
@ -140,4 +151,4 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
public void refreshChildren() { public void refreshChildren() {
refresh(true); refresh(true);
} }
} }

View File

@ -53,7 +53,7 @@ ContentUtils.exception.msg=Cannot extract a {0}
DataModelActionsFactory.srcFileInDir.text=View Source File in Directory DataModelActionsFactory.srcFileInDir.text=View Source File in Directory
DataModelActionsFactory.fileInDir.text=View File in Directory DataModelActionsFactory.fileInDir.text=View File in Directory
DataModelActionsFactory.viewNewWin.text=View in New Window DataModelActionsFactory.viewNewWin.text=View in New Window
DataModelActionsFactory.openExtViewer.text=Open in External Viewer DataModelActionsFactory.openExtViewer.text=Open in External Viewer Ctrl+E
DataSourcesNode.name=Data Sources DataSourcesNode.name=Data Sources
DataSourcesNode.group_by_datasource.name=Data Source Files DataSourcesNode.group_by_datasource.name=Data Source Files
DataSourcesNode.createSheet.name.name=Name DataSourcesNode.createSheet.name.name=Name
@ -120,13 +120,13 @@ LayoutFileNode.createSheet.name.displayName=Name
LayoutFileNode.createSheet.name.desc=no description LayoutFileNode.createSheet.name.desc=no description
LayoutFileNode.createSheet.noDescr.text=no description LayoutFileNode.createSheet.noDescr.text=no description
LayoutFileNode.getActions.viewInNewWin.text=View in New Window LayoutFileNode.getActions.viewInNewWin.text=View in New Window
LayoutFileNode.getActions.openInExtViewer.text=Open in External Viewer LayoutFileNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E
LocalFileNode.createSheet.name.name=Name LocalFileNode.createSheet.name.name=Name
LocalFileNode.createSheet.name.displayName=Name LocalFileNode.createSheet.name.displayName=Name
LocalFileNode.createSheet.name.desc=no description LocalFileNode.createSheet.name.desc=no description
LocalFileNode.createSheet.noDescr.text=no description LocalFileNode.createSheet.noDescr.text=no description
LocalFileNode.getActions.viewInNewWin.text=View in New Window LocalFileNode.getActions.viewInNewWin.text=View in New Window
LocalFileNode.getActions.openInExtViewer.text=Open in External Viewer LocalFileNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E
LocalFileNode.getActions.searchFilesSameMd5.text=Search for files with the same MD5 hash LocalFileNode.getActions.searchFilesSameMd5.text=Search for files with the same MD5 hash
OpenReportAction.actionDisplayName=Open Report OpenReportAction.actionDisplayName=Open Report
OpenReportAction.actionPerformed.MessageBoxTitle=Open Report Failure OpenReportAction.actionPerformed.MessageBoxTitle=Open Report Failure

View File

@ -95,7 +95,7 @@ DeletedContent.fsDelFilter.text=File System
DeleteReportAction.showConfirmDialog.errorMsg=An error occurred while deleting the reports. DeleteReportAction.showConfirmDialog.errorMsg=An error occurred while deleting the reports.
DeleteReportAction.showConfirmDialog.multiple.explanation=The reports will remain on disk. DeleteReportAction.showConfirmDialog.multiple.explanation=The reports will remain on disk.
DeleteReportAction.showConfirmDialog.single.explanation=The report will remain on disk. DeleteReportAction.showConfirmDialog.single.explanation=The report will remain on disk.
FileNode.getActions.openInExtViewer.text=Open in External Viewer FileNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E
FileNode.getActions.searchFilesSameMD5.text=Search for files with the same MD5 hash FileNode.getActions.searchFilesSameMD5.text=Search for files with the same MD5 hash
FileNode.getActions.viewFileInDir.text=View File in Directory FileNode.getActions.viewFileInDir.text=View File in Directory
FileNode.getActions.viewInNewWin.text=View in New Window FileNode.getActions.viewInNewWin.text=View in New Window
@ -210,7 +210,7 @@ ContentUtils.exception.msg=Cannot extract a {0}
DataModelActionsFactory.srcFileInDir.text=View Source File in Directory DataModelActionsFactory.srcFileInDir.text=View Source File in Directory
DataModelActionsFactory.fileInDir.text=View File in Directory DataModelActionsFactory.fileInDir.text=View File in Directory
DataModelActionsFactory.viewNewWin.text=View in New Window DataModelActionsFactory.viewNewWin.text=View in New Window
DataModelActionsFactory.openExtViewer.text=Open in External Viewer DataModelActionsFactory.openExtViewer.text=Open in External Viewer Ctrl+E
DataSourcesNode.name=Data Sources DataSourcesNode.name=Data Sources
DataSourcesNode.group_by_datasource.name=Data Source Files DataSourcesNode.group_by_datasource.name=Data Source Files
DataSourcesNode.createSheet.name.name=Name DataSourcesNode.createSheet.name.name=Name
@ -277,13 +277,13 @@ LayoutFileNode.createSheet.name.displayName=Name
LayoutFileNode.createSheet.name.desc=no description LayoutFileNode.createSheet.name.desc=no description
LayoutFileNode.createSheet.noDescr.text=no description LayoutFileNode.createSheet.noDescr.text=no description
LayoutFileNode.getActions.viewInNewWin.text=View in New Window LayoutFileNode.getActions.viewInNewWin.text=View in New Window
LayoutFileNode.getActions.openInExtViewer.text=Open in External Viewer LayoutFileNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E
LocalFileNode.createSheet.name.name=Name LocalFileNode.createSheet.name.name=Name
LocalFileNode.createSheet.name.displayName=Name LocalFileNode.createSheet.name.displayName=Name
LocalFileNode.createSheet.name.desc=no description LocalFileNode.createSheet.name.desc=no description
LocalFileNode.createSheet.noDescr.text=no description LocalFileNode.createSheet.noDescr.text=no description
LocalFileNode.getActions.viewInNewWin.text=View in New Window LocalFileNode.getActions.viewInNewWin.text=View in New Window
LocalFileNode.getActions.openInExtViewer.text=Open in External Viewer LocalFileNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E
LocalFileNode.getActions.searchFilesSameMd5.text=Search for files with the same MD5 hash LocalFileNode.getActions.searchFilesSameMd5.text=Search for files with the same MD5 hash
OpenReportAction.actionDisplayName=Open Report OpenReportAction.actionDisplayName=Open Report
OpenReportAction.actionPerformed.MessageBoxTitle=Open Report Failure OpenReportAction.actionPerformed.MessageBoxTitle=Open Report Failure

View File

@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
@ -123,6 +124,17 @@ public class DataSourcesNode extends DisplayableItemNode {
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getDataSource(datasourceObjId); Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getDataSource(datasourceObjId);
currentKeys = new ArrayList<>(Arrays.asList(content)); currentKeys = new ArrayList<>(Arrays.asList(content));
} }
Collections.sort(currentKeys, new Comparator<Content>() {
@Override
public int compare(Content content1, Content content2) {
String content1Name = content1.getName().toLowerCase();
String content2Name = content2.getName().toLowerCase();
return content1Name.compareTo(content2Name);
}
});
setKeys(currentKeys); setKeys(currentKeys);
} catch (TskCoreException | NoCurrentCaseException | TskDataException ex) { } catch (TskCoreException | NoCurrentCaseException | TskDataException ex) {
logger.log(Level.SEVERE, "Error getting data sources: {0}", ex.getMessage()); // NON-NLS logger.log(Level.SEVERE, "Error getting data sources: {0}", ex.getMessage()); // NON-NLS
@ -165,4 +177,4 @@ public class DataSourcesNode extends DisplayableItemNode {
NAME)); NAME));
return sheet; return sheet;
} }
} }

View File

@ -148,7 +148,7 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
@NbBundle.Messages({ @NbBundle.Messages({
"FileNode.getActions.viewFileInDir.text=View File in Directory", "FileNode.getActions.viewFileInDir.text=View File in Directory",
"FileNode.getActions.viewInNewWin.text=View in New Window", "FileNode.getActions.viewInNewWin.text=View in New Window",
"FileNode.getActions.openInExtViewer.text=Open in External Viewer", "FileNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E",
"FileNode.getActions.searchFilesSameMD5.text=Search for files with the same MD5 hash"}) "FileNode.getActions.searchFilesSameMD5.text=Search for files with the same MD5 hash"})
public Action[] getActions(boolean context) { public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<>(); List<Action> actionsList = new ArrayList<>();

View File

@ -52,7 +52,7 @@ ChangeViewAction.menuItem.view.string=String
DataResultFilterNode.action.viewFileInDir.text=View File in Directory DataResultFilterNode.action.viewFileInDir.text=View File in Directory
DataResultFilterNode.action.viewSrcFileInDir.text=View Source File in Directory DataResultFilterNode.action.viewSrcFileInDir.text=View Source File in Directory
DataResultFilterNode.action.viewInNewWin.text=View in New Window DataResultFilterNode.action.viewInNewWin.text=View in New Window
DataResultFilterNode.action.openInExtViewer.text=Open in External Viewer DataResultFilterNode.action.openInExtViewer.text=Open in External Viewer Ctrl+E
DataResultFilterNode.action.searchFilesSameMd5.text=Search for files with the same MD5 hash DataResultFilterNode.action.searchFilesSameMd5.text=Search for files with the same MD5 hash
DataResultFilterNode.action.viewInDir.text=View in Directory DataResultFilterNode.action.viewInDir.text=View in Directory
DirectoryTreeFilterNode.action.collapseAll.text=Collapse All DirectoryTreeFilterNode.action.collapseAll.text=Collapse All

View File

@ -11,6 +11,7 @@ ExternalViewerAction.actionPerformed.failure.open.url=Cannot open URL
ExternalViewerAction.actionPerformed.failure.permission.message=Permission to open the file was denied. ExternalViewerAction.actionPerformed.failure.permission.message=Permission to open the file was denied.
ExternalViewerAction.actionPerformed.failure.support.message=This platform (operating system) does not support opening a file in an editor this way. ExternalViewerAction.actionPerformed.failure.support.message=This platform (operating system) does not support opening a file in an editor this way.
ExternalViewerAction.actionPerformed.failure.title=Open File Failure ExternalViewerAction.actionPerformed.failure.title=Open File Failure
ExternalViewerShortcutAction.title.text=Open in External Viewer Ctrl+E
ExtractAction.noOpenCase.errMsg=No open case available. ExtractAction.noOpenCase.errMsg=No open case available.
ExtractUnallocAction.imageError=Error extracting unallocated space from image ExtractUnallocAction.imageError=Error extracting unallocated space from image
ExtractUnallocAction.noFiles=No unallocated files found on volume ExtractUnallocAction.noFiles=No unallocated files found on volume
@ -80,7 +81,7 @@ ChangeViewAction.menuItem.view.string=String
DataResultFilterNode.action.viewFileInDir.text=View File in Directory DataResultFilterNode.action.viewFileInDir.text=View File in Directory
DataResultFilterNode.action.viewSrcFileInDir.text=View Source File in Directory DataResultFilterNode.action.viewSrcFileInDir.text=View Source File in Directory
DataResultFilterNode.action.viewInNewWin.text=View in New Window DataResultFilterNode.action.viewInNewWin.text=View in New Window
DataResultFilterNode.action.openInExtViewer.text=Open in External Viewer DataResultFilterNode.action.openInExtViewer.text=Open in External Viewer Ctrl+E
DataResultFilterNode.action.searchFilesSameMd5.text=Search for files with the same MD5 hash DataResultFilterNode.action.searchFilesSameMd5.text=Search for files with the same MD5 hash
DataResultFilterNode.action.viewInDir.text=View in Directory DataResultFilterNode.action.viewInDir.text=View in Directory
DirectoryTreeFilterNode.action.collapseAll.text=Collapse All DirectoryTreeFilterNode.action.collapseAll.text=Collapse All

View File

@ -1,15 +1,15 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2018 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -35,6 +35,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.datamodel.SlackFileNode; import org.sleuthkit.autopsy.datamodel.SlackFileNode;
import org.sleuthkit.datamodel.AbstractFile;
/** /**
* Extracts a File object to a temporary file in the case directory, and then * Extracts a File object to a temporary file in the case directory, and then
@ -44,18 +45,13 @@ import org.sleuthkit.autopsy.datamodel.SlackFileNode;
public class ExternalViewerAction extends AbstractAction { public class ExternalViewerAction extends AbstractAction {
private final static Logger logger = Logger.getLogger(ExternalViewerAction.class.getName()); private final static Logger logger = Logger.getLogger(ExternalViewerAction.class.getName());
private final org.sleuthkit.datamodel.AbstractFile fileObject; private final AbstractFile fileObject;
private String fileObjectExt; private String fileObjectExt;
final static String[] EXECUTABLE_EXT = {".exe", ".dll", ".com", ".bat", ".msi", ".reg", ".scr", ".cmd"}; //NON-NLS final static String[] EXECUTABLE_EXT = {".exe", ".dll", ".com", ".bat", ".msi", ".reg", ".scr", ".cmd"}; //NON-NLS
/** ExternalViewerAction(String title, AbstractFile file, boolean isSlackFile) {
*
* @param title Name of the action
* @param fileNode File to display
*/
public ExternalViewerAction(String title, Node fileNode) {
super(title); super(title);
this.fileObject = fileNode.getLookup().lookup(org.sleuthkit.datamodel.AbstractFile.class); this.fileObject = file;
long size = fileObject.getSize(); long size = fileObject.getSize();
String fileName = fileObject.getName(); String fileName = fileObject.getName();
@ -79,11 +75,20 @@ public class ExternalViewerAction extends AbstractAction {
// find an application for files without an extension // find an application for files without an extension
// or if file is executable (for security reasons) // or if file is executable (for security reasons)
// Also skip slack files since their extension is the original extension + "-slack" // Also skip slack files since their extension is the original extension + "-slack"
if (!(size > 0) || extPos == -1 || isExecutable || (fileNode instanceof SlackFileNode)) { if (!(size > 0) || extPos == -1 || isExecutable || isSlackFile) {
this.setEnabled(false); this.setEnabled(false);
} }
} }
/**
*
* @param title Name of the action
* @param fileNode File to display
*/
public ExternalViewerAction(String title, Node fileNode) {
this(title, fileNode.getLookup().lookup(org.sleuthkit.datamodel.AbstractFile.class), fileNode instanceof SlackFileNode);
}
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
// Get the temp folder path of the case // Get the temp folder path of the case
@ -152,8 +157,8 @@ public class ExternalViewerAction extends AbstractAction {
try { try {
String localpath = file.getPath(); String localpath = file.getPath();
if (localpath.toLowerCase().contains("http")) { if (localpath.toLowerCase().contains("http")) {
String url_path = file.getPath().replaceAll("\\\\","/"); String url_path = file.getPath().replaceAll("\\\\", "/");
Desktop.getDesktop().browse(new URI(url_path.replaceFirst("/","//"))); Desktop.getDesktop().browse(new URI(url_path.replaceFirst("/", "//")));
} else { } else {
Desktop.getDesktop().open(file); Desktop.getDesktop().open(file);
} }
@ -183,24 +188,24 @@ public class ExternalViewerAction extends AbstractAction {
Bundle.ExternalViewerAction_actionPerformed_failure_title(), Bundle.ExternalViewerAction_actionPerformed_failure_title(),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} catch (URISyntaxException ex) { } catch (URISyntaxException ex) {
logger.log(Level.WARNING, "Could not open URL provided: " + file.getPath(), ex); logger.log(Level.WARNING, "Could not open URL provided: " + file.getPath(), ex);
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
Bundle.ExternalViewerAction_actionPerformed_failure_open_url(), Bundle.ExternalViewerAction_actionPerformed_failure_open_url(),
Bundle.ExternalViewerAction_actionPerformed_failure_title(), Bundle.ExternalViewerAction_actionPerformed_failure_title(),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} }
} }
} }
/** /**
* Opens a URL using the default desktop browser * Opens a URL using the default desktop browser
* *
* @param path URL to open * @param path URL to open
*/ */
public static void openURL(String path) { public static void openURL(String path) {
String url_path = path.replaceAll("\\\\","/"); String url_path = path.replaceAll("\\\\", "/");
try { try {
Desktop.getDesktop().browse(new URI(url_path.replaceFirst("/","//"))); Desktop.getDesktop().browse(new URI(url_path.replaceFirst("/", "//")));
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.WARNING, "Could not find a viewer for the given URL: " + url_path, ex); //NON-NLS logger.log(Level.WARNING, "Could not find a viewer for the given URL: " + url_path, ex); //NON-NLS
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
@ -226,11 +231,11 @@ public class ExternalViewerAction extends AbstractAction {
Bundle.ExternalViewerAction_actionPerformed_failure_title(), Bundle.ExternalViewerAction_actionPerformed_failure_title(),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} catch (URISyntaxException ex) { } catch (URISyntaxException ex) {
logger.log(Level.WARNING, "Could not open URL provided: " + url_path, ex); logger.log(Level.WARNING, "Could not open URL provided: " + url_path, ex);
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
Bundle.ExternalViewerAction_actionPerformed_failure_open_url(), Bundle.ExternalViewerAction_actionPerformed_failure_open_url(),
Bundle.ExternalViewerAction_actionPerformed_failure_title(), Bundle.ExternalViewerAction_actionPerformed_failure_title(),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} }
} }
} }

View File

@ -0,0 +1,57 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.HashSet;
import javax.swing.AbstractAction;
import javax.swing.KeyStroke;
import org.openide.util.NbBundle.Messages;
import org.openide.util.Utilities;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Extracts a File object to a temporary file in the case directory, and then
* tries to open it in the user's system with the default or user specified
* associated application.
*/
@Messages({"ExternalViewerShortcutAction.title.text=Open in External Viewer Ctrl+E"})
public class ExternalViewerShortcutAction extends AbstractAction {
public static final KeyStroke EXTERNAL_VIEWER_SHORTCUT = KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK);
public ExternalViewerShortcutAction() {
super(Bundle.ExternalViewerShortcutAction_title_text());
}
@Override
public void actionPerformed(ActionEvent e) {
final Collection<AbstractFile> selectedFiles = new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class));
if (!selectedFiles.isEmpty()) {
for (AbstractFile file : selectedFiles){
ExternalViewerAction action = new ExternalViewerAction(Bundle.ExternalViewerShortcutAction_title_text(), file, false);
if(action.isEnabled()){
action.actionPerformed(e);
}
}
}
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2018 Basis Technology Corp. * Copyright 2011-2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -65,6 +65,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
import org.sleuthkit.autopsy.timeline.actions.Back; import org.sleuthkit.autopsy.timeline.actions.Back;
import org.sleuthkit.autopsy.timeline.actions.Forward; import org.sleuthkit.autopsy.timeline.actions.Forward;
import org.sleuthkit.autopsy.timeline.explorernodes.EventNode; import org.sleuthkit.autopsy.timeline.explorernodes.EventNode;
@ -261,7 +262,8 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(AddBookmarkTagAction.BOOKMARK_SHORTCUT, "addBookmarkTag"); //NON-NLS getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(AddBookmarkTagAction.BOOKMARK_SHORTCUT, "addBookmarkTag"); //NON-NLS
getActionMap().put("addBookmarkTag", new AddBookmarkTagAction()); //NON-NLS getActionMap().put("addBookmarkTag", new AddBookmarkTagAction()); //NON-NLS
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ExternalViewerShortcutAction.EXTERNAL_VIEWER_SHORTCUT, "useExternalViewer"); //NON-NLS
getActionMap().put("useExternalViewer", new ExternalViewerShortcutAction()); //NON-NLS
this.controller = controller; this.controller = controller;
//create linked result and content views //create linked result and content views

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-2018 Basis Technology Corp. * Copyright 2013-2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -50,6 +50,7 @@ import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.stage.Modality; import javafx.stage.Modality;
import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.GuardedBy;
import javax.swing.JComponent;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.ObjectUtils.notEqual; import static org.apache.commons.lang3.ObjectUtils.notEqual;
@ -64,6 +65,7 @@ import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute; import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupManager; import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupManager;
import org.sleuthkit.autopsy.imagegallery.gui.DataSourceCell; import org.sleuthkit.autopsy.imagegallery.gui.DataSourceCell;
@ -238,6 +240,8 @@ public final class ImageGalleryTopComponent extends TopComponent implements Expl
public ImageGalleryTopComponent() { public ImageGalleryTopComponent() {
setName(Bundle.CTL_ImageGalleryTopComponent()); setName(Bundle.CTL_ImageGalleryTopComponent());
initComponents(); initComponents();
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ExternalViewerShortcutAction.EXTERNAL_VIEWER_SHORTCUT, "useExternalViewer"); //NON-NLS
getActionMap().put("useExternalViewer", new ExternalViewerShortcutAction()); //NON-NLS
} }
/** /**

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2015 Basis Technology Corp. * Copyright 2015-2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -21,6 +21,9 @@ package org.sleuthkit.autopsy.imagegallery.actions;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
@ -33,10 +36,11 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
* appropriate text and graphic * appropriate text and graphic
*/ */
@NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer", @NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer",
"OpenExternalViewerAction.displayName=External Viewer"}) "OpenExternalViewerAction.displayName=External Viewer"})
public class OpenExternalViewerAction extends Action { public class OpenExternalViewerAction extends Action {
private static final Image EXTERNAL = new Image(OpenExternalViewerAction.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/external.png").toExternalForm()); //NON-NLS private static final Image EXTERNAL = new Image(OpenExternalViewerAction.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/external.png").toExternalForm()); //NON-NLS
private static final KeyCombination EXTERNAL_VIEWER_SHORTCUT = new KeyCodeCombination(KeyCode.E, KeyCombination.CONTROL_DOWN);
private static final ActionEvent ACTION_EVENT = new ActionEvent(OpenExternalViewerAction.class, ActionEvent.ACTION_PERFORMED, ""); //Swing ActionEvent //NOI18N private static final ActionEvent ACTION_EVENT = new ActionEvent(OpenExternalViewerAction.class, ActionEvent.ACTION_PERFORMED, ""); //Swing ActionEvent //NOI18N
public OpenExternalViewerAction(DrawableFile file) { public OpenExternalViewerAction(DrawableFile file) {
@ -49,9 +53,12 @@ public class OpenExternalViewerAction extends Action {
ExternalViewerAction externalViewerAction = new ExternalViewerAction(Bundle.MediaViewImagePanel_externalViewerButton_text(), new FileNode(file.getAbstractFile())); ExternalViewerAction externalViewerAction = new ExternalViewerAction(Bundle.MediaViewImagePanel_externalViewerButton_text(), new FileNode(file.getAbstractFile()));
setLongText(Bundle.MediaViewImagePanel_externalViewerButton_text()); setLongText(Bundle.MediaViewImagePanel_externalViewerButton_text());
setEventHandler(actionEvent -> //fx ActionEvent setEventHandler(actionEvent
-> //fx ActionEvent
SwingUtilities.invokeLater(() -> externalViewerAction.actionPerformed(ACTION_EVENT)) SwingUtilities.invokeLater(() -> externalViewerAction.actionPerformed(ACTION_EVENT))
); );
setGraphic(new ImageView(EXTERNAL)); setGraphic(new ImageView(EXTERNAL));
setAccelerator(EXTERNAL_VIEWER_SHORTCUT);
} }
} }

View File

@ -87,7 +87,7 @@ KeywordSearchEditListPanel.exportButtonActionPerformed.kwListExportedMsg=Keyword
KeywordSearchEditListPanel.kwColName=Keyword KeywordSearchEditListPanel.kwColName=Keyword
KeywordSearchEditListPanel.addKeyword.message=Add a new word to the keyword search list: KeywordSearchEditListPanel.addKeyword.message=Add a new word to the keyword search list:
KeywordSearchEditListPanel.addKeyword.title=New Keyword KeywordSearchEditListPanel.addKeyword.title=New Keyword
KeywordSearchFilterNode.getFileActions.openExternViewActLbl=Open in External Viewer KeywordSearchFilterNode.getFileActions.openExternViewActLbl=Open in External Viewer Ctrl+E
KeywordSearchFilterNode.getFileActions.searchSameMd5=Search for files with the same MD5 hash KeywordSearchFilterNode.getFileActions.searchSameMd5=Search for files with the same MD5 hash
KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=View in New Window KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=View in New Window
KeywordSearchIngestModule.init.noKwInLstMsg=No keywords in keyword list. KeywordSearchIngestModule.init.noKwInLstMsg=No keywords in keyword list.

View File

@ -122,7 +122,7 @@ KeywordSearchEditListPanel.exportButtonActionPerformed.kwListExportedMsg=Keyword
KeywordSearchEditListPanel.kwColName=Keyword KeywordSearchEditListPanel.kwColName=Keyword
KeywordSearchEditListPanel.addKeyword.message=Add a new word to the keyword search list: KeywordSearchEditListPanel.addKeyword.message=Add a new word to the keyword search list:
KeywordSearchEditListPanel.addKeyword.title=New Keyword KeywordSearchEditListPanel.addKeyword.title=New Keyword
KeywordSearchFilterNode.getFileActions.openExternViewActLbl=Open in External Viewer KeywordSearchFilterNode.getFileActions.openExternViewActLbl=Open in External Viewer Ctrl+E
KeywordSearchFilterNode.getFileActions.searchSameMd5=Search for files with the same MD5 hash KeywordSearchFilterNode.getFileActions.searchSameMd5=Search for files with the same MD5 hash
KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=View in New Window KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=View in New Window
KeywordSearchIngestModule.init.noKwInLstMsg=No keywords in keyword list. KeywordSearchIngestModule.init.noKwInLstMsg=No keywords in keyword list.