Merge remote-tracking branch 'upstream/develop' into data_result_viewer_video_thumbnails

Conflicts:
	Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java
	Core/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewNode.java
	Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java
	ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ThumbnailCache.java
	ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/ImageFile.java
	ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/VideoFile.java
This commit is contained in:
jmillman 2015-07-24 16:07:34 -04:00
commit f15ee9426a
36 changed files with 1900 additions and 691 deletions

View File

@ -220,4 +220,6 @@ XMLCaseManagement.open.msgDlg.notAutCase.msg=Error\: This is not an Autopsy conf
Detail\: \n\
Cannot open a non-Autopsy config file (at {1}).
XMLCaseManagement.open.msgDlg.notAutCase.title=Error
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}

View File

@ -30,6 +30,7 @@ import java.nio.file.InvalidPathException;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
@ -40,6 +41,7 @@ import java.util.TimeZone;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.commons.io.FileUtils;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
@ -141,17 +143,31 @@ public class Case implements SleuthkitCase.ErrorObserver {
* value is a reference to a Report object representing the new report.
*/
REPORT_ADDED,
/** Property name for the event when a new BlackBoardArtifactTag is
* added. The new value is tag added, the old value is empty */
/**
* Name for the property change event when a report is deleted
* from the case. Both the old value and the new value supplied by the
* event object are null.
*/
REPORT_DELETED,
/**
* Property name for the event when a new BlackBoardArtifactTag is
* added. The new value is tag added, the old value is empty
*/
BLACKBOARD_ARTIFACT_TAG_ADDED,
/** Property name for the event when a new BlackBoardArtifactTag is
* deleted. The new value is empty, the old value is the deleted tag */
/**
* Property name for the event when a new BlackBoardArtifactTag is
* deleted. The new value is empty, the old value is the deleted tag
*/
BLACKBOARD_ARTIFACT_TAG_DELETED,
/** Property name for the event when a new ContentTag is
* added. The new value is tag added, the old value is empty */
/**
* Property name for the event when a new ContentTag is added. The new
* value is tag added, the old value is empty
*/
CONTENT_TAG_ADDED,
/** Property name for the event when a new ContentTag is
* deleted. The new value is empty, the old value is the deleted tag */
/**
* Property name for the event when a new ContentTag is deleted. The new
* value is empty, the old value is the deleted tag
*/
CONTENT_TAG_DELETED;
};
@ -1257,6 +1273,49 @@ public class Case implements SleuthkitCase.ErrorObserver {
return this.db.getAllReports();
}
/**
* Deletes reports from the case - deletes it from the disk as well as the
* database.
*
* @param reports Collection of Report to be deleted from the case.
* @param deleteFromDisk Set true to perform reports file deletion from
* disk.
* @throws TskCoreException
*/
public void deleteReports(Collection<? extends Report> reports, boolean deleteFromDisk) throws TskCoreException {
String pathToReportsFolder = Paths.get(this.db.getDbDirPath(), "Reports").normalize().toString(); // NON-NLS
for (Report report : reports) {
// delete from the database.
this.db.deleteReport(report);
if (deleteFromDisk) {
// traverse to the root directory of Report report.
String reportPath = report.getPath();
while (!Paths.get(reportPath, "..").normalize().toString().equals(pathToReportsFolder)) { // NON-NLS
reportPath = Paths.get(reportPath, "..").normalize().toString(); // NON-NLS
}
// delete from the disk.
try {
FileUtils.deleteDirectory(new File(reportPath));
} catch (IOException | SecurityException ex) {
logger.log(Level.WARNING, NbBundle.getMessage(Case.class, "Case.deleteReports.deleteFromDiskException.log.msg"), ex);
JOptionPane.showMessageDialog(null, NbBundle.getMessage(Case.class, "Case.deleteReports.deleteFromDiskException.msg", report.getReportName(), reportPath));
}
}
// fire property change event.
try {
Case.pcs.firePropertyChange(Events.REPORT_DELETED.toString(), null, null);
} catch (Exception ex) {
String errorMessage = String.format("A Case %s listener threw an exception", Events.REPORT_DELETED.toString()); //NON-NLS
logger.log(Level.SEVERE, errorMessage, ex);
}
}
}
/**
* Returns if the case has data in it yet.
*

View File

@ -23,24 +23,9 @@ import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@ -87,6 +72,10 @@ import org.openide.util.actions.Presenter;
return;
Case result = Case.getCurrentCase();
if(!MessageNotifyUtil.Message.confirm("Are you sure you want to close current case?"))
return;
try {
result.closeCase();
EventQueue.invokeLater(new Runnable() {

View File

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2014 Basis Technology Corp.
* Copyright 2011-2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*s
* Licensed under the Apache License, Version 2.0 (the "License");
@ -54,12 +54,10 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
//UI
private final MediaViewVideoPanel videoPanel;
private final SortedSet<String> videoExtensions; // get them from the panel
private final SortedSet<String> imageExtensions;
private final SortedSet<String> videoMimes;
private final SortedSet<String> imageMimes;
private final MediaViewImagePanel imagePanel;
private boolean videoPanelInited;
private boolean imagePanelInited;
private final boolean videoPanelInited;
private final boolean imagePanelInited;
private static final String IMAGE_VIEWER_LAYER = "IMAGE"; //NON-NLS
private static final String VIDEO_VIEWER_LAYER = "VIDEO"; //NON-NLS
@ -78,8 +76,6 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
imagePanel = new MediaViewImagePanel();
imagePanelInited = imagePanel.isInited();
imageMimes = new TreeSet<>(imagePanel.getMimeTypes());
imageExtensions = new TreeSet<>(imagePanel.getExtensions());
customizeComponents();
logger.log(Level.INFO, "Created MediaView instance: " + this); //NON-NLS
@ -195,9 +191,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
//TODO: is this what we want, to require both extension and mimetype support?
if (AUDIO_EXTENSIONS.contains("." + extension) || videoExtensions.contains("." + extension)) {
try {
String mimeType = new FileTypeDetector().detect(file);
if (nonNull(mimeType) && videoMimes.contains(mimeType)) {
return true;
String mimeType = new FileTypeDetector().getFileType(file);
if (nonNull(mimeType)) {
return videoMimes.contains(mimeType);
}
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
logger.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex);
@ -206,6 +202,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
}
}
}
return false;
}
@ -217,36 +214,8 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
* @return True if an image file that can be displayed
*/
private boolean isImageSupported(AbstractFile file) {
String extension = file.getNameExtension();
// blackboard
try {
String mimeType = new FileTypeDetector().detect(file);
if (nonNull(mimeType) && imageMimes.contains(mimeType)) {
return true;
}
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
logger.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex);
if (!imageMimes.isEmpty()) {
MimeMatchEnum mimeMatch = file.isMimeType(imageMimes);
if (mimeMatch == MimeMatchEnum.TRUE) {
return true;
} else if (mimeMatch == MimeMatchEnum.FALSE) {
return false;
}
}
}
// extension
if (imageExtensions.contains("." + extension)) {
return true;
}
// our own signature checks for important types
if (ImageUtils.isJpegFileHeader(file)) {
return true;
}
return ImageUtils.isPngFileHeader(file);
return ImageUtils.thumbnailSupported(file);
}
@Override
@ -264,19 +233,11 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
return false;
}
if (imagePanelInited) {
if (isImageSupported(file)) {
return true;
}
if (imagePanelInited && isImageSupported(file)) {
return true;
}
if (videoPanelInited && videoPanel.isInited()) {
if (isVideoSupported(file)) {
return true;
}
}
return false;
return videoPanelInited && isVideoSupported(file);
}
@Override

View File

@ -65,7 +65,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
private DataContent customContentViewer;
private boolean isMain;
private String title;
private final DummyNodeListener dummyNodeListener = new DummyNodeListener();
private final RootNodeListener rootNodeListener = new RootNodeListener();
private static final Logger logger = Logger.getLogger(DataResultPanel.class.getName() );
private boolean listeningToTabbedPane = false;
@ -369,7 +369,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
@Override
public void setNode(Node selectedNode) {
if (this.rootNode != null) {
this.rootNode.removeNodeListener(dummyNodeListener);
this.rootNode.removeNodeListener(rootNodeListener);
}
// Deferring becoming a listener to the tabbed pane until this point
// eliminates handling a superfluous stateChanged event during construction.
@ -380,8 +380,8 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
this.rootNode = selectedNode;
if (this.rootNode != null) {
dummyNodeListener.reset();
this.rootNode.addNodeListener(dummyNodeListener);
rootNodeListener.reset();
this.rootNode.addNodeListener(rootNodeListener);
}
resetTabs(selectedNode);
@ -620,28 +620,33 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
}
private class DummyNodeListener implements NodeListener {
private class RootNodeListener implements NodeListener {
private volatile boolean waitingForData = true;
private volatile boolean load = true;
public void reset() {
load = true;
waitingForData = true;
}
@Override
public void childrenAdded(final NodeMemberEvent nme) {
Node[] delta = nme.getDelta();
if (load && containsReal(delta)) {
load = false;
updateMatches();
/* There is a known issue in this code whereby we will only
call setupTabs() once even though childrenAdded could be
called multiple times. That means that each panel may not
have access to all of the children when they decide if they
support the content */
if (waitingForData && containsReal(delta)) {
waitingForData = false;
if (SwingUtilities.isEventDispatchThread()) {
setupTabs(nme.getNode());
updateMatches();
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setupTabs(nme.getNode());
updateMatches();
}
});
}

View File

@ -0,0 +1,28 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 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.
*/
.label {
-fx-wrap-text:true;
-fx-text-fill: red;
-fx-font-size: 2em;
}
.bg {
-fx-background-color:black;
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -21,41 +21,65 @@ package org.sleuthkit.autopsy.corecomponents;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.logging.Level;
import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.openide.util.NbBundle;
import org.python.google.common.collect.Lists;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corelibs.ScalrWrapper;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.ReadContentInputStream;
/**
* Container for the image viewer part of media view, on a layered pane. To be
* used with JavaFx image viewer only.
* Image viewer part of the Media View layered pane. Uses JavaFX to display the
* image.
*/
public class MediaViewImagePanel extends javax.swing.JPanel {
public class MediaViewImagePanel extends JPanel {
private static final Logger LOGGER = Logger.getLogger(MediaViewImagePanel.class.getName());
private final boolean fxInited;
private JFXPanel fxPanel;
private ImageView fxImageView;
private static final Logger logger = Logger.getLogger(MediaViewImagePanel.class.getName());
private boolean fxInited = false;
private final List<String> supportedExtensions;
static private final List<String> supportedMimes = Arrays.asList("image/jpeg", "image/png", "image/gif", "image/bmp", "image/x-ms-bmp"); //NON-NLS
private BorderPane borderpane;
private final Label errorLabel = new Label("Could not load image file into media view.");
private final Label tooLargeLabel = new Label("Could not load image file into media view (too large).");
private final Label noReaderLabel = new Label("Image reader not found for file.");
/**
* mime types we should be able to display. if the mimetype is unknown we
* will fall back on extension and jpg/png header
*/
static private final SortedSet<String> supportedMimes = ImageUtils.getSupportedMimeTypes();
/**
* extensions we should be able to display
*/
static private final List<String> supportedExtensions = ImageUtils.getSupportedExtensions().stream()
.map("."::concat)
.collect(Collectors.toList());
/**
* Creates new form MediaViewImagePanel
@ -64,74 +88,59 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
initComponents();
fxInited = org.sleuthkit.autopsy.core.Installer.isJavaFxInited();
if (fxInited) {
setupFx();
}
supportedExtensions = new ArrayList<>();
//logger.log(Level.INFO, "Supported image formats by javafx image viewer: ");
for (String suffix : ImageIO.getReaderFileSuffixes()) {
//logger.log(Level.INFO, "suffix: " + suffix);
supportedExtensions.add("." + suffix);
Platform.runLater(() -> {
// build jfx ui (we could do this in FXML?)
fxImageView = new ImageView(); // will hold image
borderpane = new BorderPane(fxImageView); // centers and sizes imageview
borderpane.getStyleClass().add("bg");
fxPanel = new JFXPanel(); // bridge jfx-swing
Scene scene = new Scene(borderpane); //root of jfx tree
scene.getStylesheets().add(MediaViewImagePanel.class.getResource("MediaViewImagePanel.css").toExternalForm());
fxPanel.setScene(scene);
//bind size of image to that of scene, while keeping proportions
fxImageView.fitWidthProperty().bind(scene.widthProperty());
fxImageView.fitHeightProperty().bind(scene.heightProperty());
fxImageView.setPreserveRatio(true);
fxImageView.setSmooth(true);
fxImageView.setCache(true);
EventQueue.invokeLater(() -> {
add(fxPanel);//add jfx ui to JPanel
});
});
}
}
public boolean isInited() {
return fxInited;
}
/**
* Setup FX components
* clear the displayed image
*/
private void setupFx() {
// load the image
Platform.runLater(new Runnable() {
@Override
public void run() {
fxPanel = new JFXPanel();
fxImageView = new ImageView();
// resizes the image to have width of 100 while preserving the ratio and using
// higher quality filtering method; this ImageView is also cached to
// improve performance
fxImageView.setPreserveRatio(true);
fxImageView.setSmooth(true);
fxImageView.setCache(true);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
add(fxPanel);
//TODO
// setVisible(true);
}
});
}
});
}
public void reset() {
Platform.runLater(new Runnable() {
@Override
public void run() {
fxImageView.setImage(null);
}
Platform.runLater(() -> {
fxImageView.setImage(null);
borderpane.setCenter(null);
});
}
/**
* Show image
* Show the contents of the given AbstractFile as a visual image.
*
* @param file image file to show
* @param dims dimension of the parent window
* @param dims dimension of the parent window (ignored)
*/
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
void showImageFx(final AbstractFile file, final Dimension dims) {
if (!fxInited) {
return;
}
final String fileName = file.getName();
//hide the panel during loading/transformations
//TODO: repalce this with a progress indicator
fxPanel.setVisible(false);
// load the image
@ -139,90 +148,60 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
@Override
public void run() {
if (!Case.isCaseOpen()) {
//handle in-between condition when case is being closed
//and an image was previously selected
/* handle in-between condition when case is being closed
* and an image was previously selected */
return;
}
try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) {
final InputStream inputStream = new ReadContentInputStream(file);
final Image fxImage;
try {
//original input stream
BufferedImage bi = ImageIO.read(inputStream);
if (bi == null) {
logger.log(Level.WARNING, "Could image reader not found for file: " + fileName); //NON-NLS
return;
BufferedImage bufferedImage = ImageIO.read(inputStream);
if (bufferedImage == null) {
LOGGER.log(Level.WARNING, "Image reader not found for file: {0}", file.getName()); //NON-NLS
borderpane.setCenter(noReaderLabel);
} else {
Image fxImage = SwingFXUtils.toFXImage(bufferedImage, null);
if (fxImage.isError()) {
LOGGER.log(Level.WARNING, "Could not load image file into media view: " + file.getName(), fxImage.getException()); //NON-NLS
borderpane.setCenter(errorLabel);
return;
} else {
fxImageView.setImage(fxImage);
borderpane.setCenter(fxImageView);
}
}
//scale image using Scalr
BufferedImage biScaled = ScalrWrapper.resizeHighQuality(bi, (int) dims.getWidth(), (int) dims.getHeight());
//convert from awt imageto fx image
fxImage = SwingFXUtils.toFXImage(biScaled, null);
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not load image file into media view: " + fileName, ex); //NON-NLS
return;
} catch (OutOfMemoryError ex) {
logger.log(Level.WARNING, "Could not load image file into media view (too large): " + fileName, ex); //NON-NLS
} catch (IllegalArgumentException | IOException ex) {
LOGGER.log(Level.WARNING, "Could not load image file into media view: " + file.getName(), ex); //NON-NLS
borderpane.setCenter(errorLabel);
} catch (OutOfMemoryError ex) { // this might be redundant since we are not attempting to rescale the image anymore
LOGGER.log(Level.WARNING, "Could not load image file into media view (too large): " + file.getName(), ex); //NON-NLS
MessageNotifyUtil.Notify.warn(
NbBundle.getMessage(this.getClass(), "MediaViewImagePanel.imgFileTooLarge.msg", file.getName()),
ex.getMessage());
return;
} finally {
try {
inputStream.close();
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not close input stream after loading image in media view: " + fileName, ex); //NON-NLS
}
borderpane.setCenter(tooLargeLabel);
}
if (fxImage == null || fxImage.isError()) {
logger.log(Level.WARNING, "Could not load image file into media view: " + fileName); //NON-NLS
return;
}
//use border pane to center the image in the scene
BorderPane borderpane = new BorderPane();
borderpane.setCenter(fxImageView);
fxImageView.setImage(fxImage);
fxImageView.setFitWidth(dims.getWidth());
fxImageView.setFitHeight(dims.getHeight());
//Group fxRoot = new Group();
//Scene fxScene = new Scene(fxRoot, dims.getWidth(), dims.getHeight(), javafx.scene.paint.Color.BLACK);
Scene fxScene = new Scene(borderpane, javafx.scene.paint.Color.BLACK);
// borderpane.getChildren().add(fxImageView);
fxPanel.setScene(fxScene);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//show the panel after fully loaded
fxPanel.setVisible(true);
}
SwingUtilities.invokeLater(() -> {
//show the panel after fully loaded
fxPanel.setVisible(true);
});
}
});
}
/**
* returns supported mime types
* @return
* @return supported mime types
*/
public List<String> getMimeTypes() {
return supportedMimes;
return Collections.unmodifiableList(Lists.newArrayList(supportedMimes));
}
/**
* returns supported extensions (each starting with .)
* @return
*
* @return
*/
public List<String> getExtensions() {
return supportedExtensions;
return Collections.unmodifiableList(supportedExtensions);
}
/**
@ -239,4 +218,4 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}
}

View File

@ -43,7 +43,7 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
static final int IMAGES_PER_PAGE = 200;
private Node parent;
private final HashMap<Integer, List<Node>> pages = new HashMap<Integer, List<Node>>();
private final HashMap<Integer, List<Node>> pages = new HashMap<>();
private int totalImages = 0;
private int totalPages = 0;
private int iconSize = ImageUtils.ICON_SIZE_MEDIUM;
@ -85,7 +85,7 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
//TODO when lazy loading of original nodes is fixed
//we should be asking the datamodel for the children instead
//and not counting the children nodes (which might not be preloaded at this point)
final List<Node> suppContent = new ArrayList<Node>();
final List<Node> suppContent = new ArrayList<>();
for (Node child : parent.getChildren().getNodes()) {
if (isSupported(child)) {
++totalImages;

View File

@ -77,7 +77,7 @@ class ThumbnailViewNode extends FilterNode {
} else {
final Content content = this.getLookup().lookup(Content.class);
if (content == null) {
return ImageUtils.getDefaultIcon();
return ImageUtils.getDefaultThumbnail();
}
if (swingWorker == null || swingWorker.isDone()) {
swingWorker = new SwingWorker<Image, Object>() {
@ -86,7 +86,7 @@ class ThumbnailViewNode extends FilterNode {
@Override
protected Image doInBackground() throws Exception {
progressHandle.start();
return ImageUtils.getIcon(content, iconSize);
return ImageUtils.getThumbnail(content, iconSize);
}
@Override

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
* Copyright 2012-15 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
@ -25,42 +25,59 @@ package org.sleuthkit.autopsy.coreutils;
import com.google.common.io.Files;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static java.util.Objects.isNull;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.opencv.core.Core;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corelibs.ScalrWrapper;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector.FileTypeDetectorInitException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Utilities for creating and manipulating thumbnail and icon images.
*
* Utilities for working with Images and creating thumbnails. Reuses thumbnails
* by storing them in the case's cache directory.
*/
public class ImageUtils {
private static final Logger LOGGER = Logger.getLogger(ImageUtils.class.getName());
/** save thumbnails to disk as this format */
private static final String FORMAT = "png"; //NON-NLS
public static final int ICON_SIZE_SMALL = 50;
public static final int ICON_SIZE_MEDIUM = 100;
public static final int ICON_SIZE_LARGE = 200;
private static final Logger logger = LOGGER;
private static final BufferedImage DEFAULT_ICON;
private static final Image DEFAULT_THUMBNAIL;
private static final List<String> SUPP_IMAGE_EXTENSIONS = new ArrayList<>(Arrays.asList(ImageIO.getReaderFileSuffixes())); //final
private static final List<String> SUPP_IMAGE_MIME_TYPES = new ArrayList<>(Arrays.asList(ImageIO.getReaderMIMETypes())); // final
private static final List<String> SUPP_VIDEO_EXTENSIONS
@ -118,9 +135,77 @@ public class ImageUtils {
* Get the default Icon, which is the icon for a file.
*
* @return
*
*
*
* /** initialized lazily */
private static FileTypeDetector fileTypeDetector;
private static final List<String> SUPPORTED_EXTENSIONS;
private static final TreeSet<String> SUPPORTED_MIME_TYPES;
/** thread that saves generated thumbnails to disk in the background */
private static final Executor imageSaver
= Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
.namingPattern("icon saver-%d").build());
static {
ImageIO.scanForPlugins();
BufferedImage defaultIcon = null;
try {
defaultIcon = ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/file-icon.png"));//NON-NLS
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Failed to read default thumbnail.");
}
DEFAULT_THUMBNAIL = defaultIcon;
SUPPORTED_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes());
SUPPORTED_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
/* special cases and variants that we support, but don't get registered
* with ImageIO automatically */
SUPPORTED_MIME_TYPES.addAll(Arrays.asList(
"image/x-rgb",
"image/x-ms-bmp",
"application/x-123"));
//this is rarely usefull
SUPPORTED_MIME_TYPES.removeIf("application/octet-stream"::equals);
}
private ImageUtils() {
}
public static List<String> getSupportedExtensions() {
return Collections.unmodifiableList(SUPPORTED_EXTENSIONS);
}
public static SortedSet<String> getSupportedMimeTypes() {
return Collections.unmodifiableSortedSet(SUPPORTED_MIME_TYPES);
}
/**
* Get the default thumbnail, which is the icon for a file. Used when we can
* not
* generate content based thumbnail.
*
* @return
*
* @deprecated use {@link #getDefaultThumbnail() } instead.
*/
@Deprecated
public static Image getDefaultIcon() {
return DEFAULT_ICON;
return getDefaultThumbnail();
}
/**
* Get the default thumbnail, which is the icon for a file. Used when we can
* not generate content based thumbnail.
*
* @return the default thumbnail
*/
public static Image getDefaultThumbnail() {
return DEFAULT_THUMBNAIL;
}
/**
@ -129,45 +214,61 @@ public class ImageUtils {
* @param content
*
* @return
*
*/
public static boolean thumbnailSupported(Content content) {
if (content instanceof AbstractFile == false) {
return false;
}
AbstractFile f = (AbstractFile) content;
if (f.getSize() == 0) {
return false;
}
// check the blackboard for a file type attribute
if (content.getSize() == 0) {
return false;
}
if (!(content instanceof AbstractFile)) {
return false;
}
AbstractFile file = (AbstractFile) content;
try {
//TODO: Use FileTypeDetector here?
ArrayList<BlackboardAttribute> attributes = f.getGenInfoAttributes(ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG);
for (BlackboardAttribute attribute : attributes) {
if (SUPP_IMAGE_MIME_TYPES.contains(attribute.getValueString()) || SUPP_VIDEO_MIME_TYPES.contains(attribute.getValueString())) {
String mimeType = getFileTypeDetector().getFileType(file);
if (Objects.nonNull(mimeType)) {
return SUPPORTED_MIME_TYPES.contains(mimeType)
|| (mimeType.equalsIgnoreCase("audio/x-aiff") && "iff".equalsIgnoreCase(file.getNameExtension()));
}
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
LOGGER.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex);
if (!SUPPORTED_MIME_TYPES.isEmpty()) {
AbstractFile.MimeMatchEnum mimeMatch = file.isMimeType(SUPPORTED_MIME_TYPES);
if (mimeMatch == AbstractFile.MimeMatchEnum.TRUE) {
return true;
} else if (mimeMatch == AbstractFile.MimeMatchEnum.FALSE) {
return false;
}
}
// if the file type is known and we don't support it, bail
if (attributes.size() > 0) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error while getting file signature from blackboard.", ex); //NON-NLS
}
// if we have an extension, check it
final String extension = f.getNameExtension();
if (extension.isEmpty() == false) {
// Note: thumbnail generator only supports JPG, GIF, and PNG for now
if (SUPP_IMAGE_EXTENSIONS.contains(extension) || SUPP_VIDEO_EXTENSIONS.contains(extension)) {
return true;
}
final String extension = file.getNameExtension();
if (StringUtils.isNotBlank(extension) && SUPPORTED_EXTENSIONS.contains(extension)) {
return true;
}
// if no extension or one that is not for an image, then read the content
return isJpegFileHeader(f) || isPngFileHeader(f);
return isJpegFileHeader(file) || isPngFileHeader(file);
}
/**
* returns a lazily instatiated FileTypeDetector
*
* @return a FileTypeDetector
*
* @throws FileTypeDetectorInitException if a initializing the
* FileTypeDetector failed.
*/
synchronized private static FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
if (fileTypeDetector == null) {
fileTypeDetector = new FileTypeDetector();
}
return fileTypeDetector;
}
/**
@ -177,42 +278,48 @@ public class ImageUtils {
* @param content
* @param iconSize
*
* @return
*
* @return a thumbnail for the given image or a default one if there was a
* problem making a thumbnail.
*
* @deprecated use {@link #getThumbnail(org.sleuthkit.datamodel.Content, int)
* } instead.
*
*/
@Nonnull
@Deprecated
public static Image getIcon(Content content, int iconSize) {
//TODO: why do we allow Content here if we only handle AbstractFiles?
return getThumbnail(content, iconSize);
}
Image icon = null;
/**
* Get a thumbnail of a specified size. Generates the image if it is
* not already cached.
*
* @param content
* @param iconSize
*
* @return a thumbnail for the given image or a default one if there was a
* problem making a thumbnail.
*/
public static Image getThumbnail(Content content, int iconSize) {
// If a thumbnail file is already saved locally
// @@@ Bug here in that we do not refer to size in the cache.
File iconFile = getCachedThumbnailLocation(content.getId());
// If a thumbnail file is already saved locally
if (iconFile.exists()) {
File cacheFile = getCachedThumbnailLocation(content.getId());
if (cacheFile.exists()) {
try {
BufferedImage bicon = ImageIO.read(iconFile);
if (bicon == null) {
icon = DEFAULT_ICON;
} else if (bicon.getWidth() != iconSize) {
icon = generateAndSaveIcon(content, iconSize, iconFile);
BufferedImage thumbnail = ImageIO.read(cacheFile);
if (isNull(thumbnail) || thumbnail.getWidth() != iconSize) {
return generateAndSaveThumbnail(content, iconSize, cacheFile);
} else {
icon = bicon;
return thumbnail;
}
} catch (Exception ex) {
logger.log(Level.WARNING, "Error while reading image.", ex); //NON-NLS
icon = DEFAULT_ICON;
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Error while reading image.", ex); //NON-NLS
return generateAndSaveThumbnail(content, iconSize, cacheFile);
}
} else {
final String extension = ((AbstractFile) content).getNameExtension();
if (SUPP_VIDEO_EXTENSIONS.contains(extension) || SUPP_IMAGE_EXTENSIONS.contains(extension)) {
icon = generateAndSaveIcon(content, iconSize, iconFile);
}
return generateAndSaveThumbnail(content, iconSize, cacheFile);
}
if (icon == null) {
return DEFAULT_ICON;
}
return icon;
}
/**
@ -222,13 +329,35 @@ public class ImageUtils {
* @param content
* @param iconSize
*
* @return File object for cached image. Is guaranteed to exist.
* @return File object for cached image. Is guaranteed to exist, as long as
* there was not an error generating or saving the thumbnail.
*
* @deprecated use {@link #getCachedThumbnailFile(org.sleuthkit.datamodel.Content, int)
* } instead.
*
*/
@Nullable
@Deprecated
public static File getIconFile(Content content, int iconSize) {
if (getIcon(content, iconSize) != null) {
return getFile(content.getId());
}
return null;
return getCachedThumbnailFile(content, iconSize);
}
/**
*
* Get a thumbnail of a specified size. Generates the image if it is
* not already cached.
*
* @param content
* @param iconSize
*
* @return File object for cached image. Is guaranteed to exist, as long as
* there was not an error generating or saving the thumbnail.
*/
@Nullable
public static File getCachedThumbnailFile(Content content, int iconSize) {
getThumbnail(content, iconSize);
return getCachedThumbnailLocation(content.getId());
}
/**
@ -239,7 +368,11 @@ public class ImageUtils {
*
* @return
*
*
* @deprecated this should never have been public.
*/
@Deprecated
public static File getFile(long id) {
return getCachedThumbnailLocation(id);
}
@ -258,7 +391,7 @@ public class ImageUtils {
}
/**
* Check if is jpeg file based on header
* Check if the given file is a jpeg based on header.
*
* @param file
*
@ -269,125 +402,137 @@ public class ImageUtils {
return false;
}
byte[] fileHeaderBuffer = new byte[2];
int bytesRead;
try {
bytesRead = file.read(fileHeaderBuffer, 0, 2);
byte[] fileHeaderBuffer = readHeader(file, 2);
/* Check for the JPEG header. Since Java bytes are signed, we cast
* them to an int first. */
return (((fileHeaderBuffer[0] & 0xff) == 0xff) && ((fileHeaderBuffer[1] & 0xff) == 0xd8));
} catch (TskCoreException ex) {
//ignore if can't read the first few bytes, not a JPEG
return false;
}
if (bytesRead != 2) {
return false;
}
/*
* Check for the JPEG header. Since Java bytes are signed, we cast them
* to an int first.
*/
return (((fileHeaderBuffer[0] & 0xff) == 0xff) && ((fileHeaderBuffer[1] & 0xff) == 0xd8));
}
/**
* Check if the given file is a png based on header.
*
* @param file
*
* @return true if png file, false otherwise
*/
public static boolean isPngFileHeader(AbstractFile file) {
if (file.getSize() < 10) {
return false;
}
byte[] fileHeaderBuffer = new byte[8];
int bytesRead;
try {
bytesRead = file.read(fileHeaderBuffer, 0, 8);
byte[] fileHeaderBuffer = readHeader(file, 8);
/* Check for the png header. Since Java bytes are signed, we cast
* them to an int first. */
return (((fileHeaderBuffer[1] & 0xff) == 0x50) && ((fileHeaderBuffer[2] & 0xff) == 0x4E)
&& ((fileHeaderBuffer[3] & 0xff) == 0x47) && ((fileHeaderBuffer[4] & 0xff) == 0x0D)
&& ((fileHeaderBuffer[5] & 0xff) == 0x0A) && ((fileHeaderBuffer[6] & 0xff) == 0x1A)
&& ((fileHeaderBuffer[7] & 0xff) == 0x0A));
} catch (TskCoreException ex) {
//ignore if can't read the first few bytes, not an png
return false;
}
}
private static byte[] readHeader(AbstractFile file, int buffLength) throws TskCoreException {
byte[] fileHeaderBuffer = new byte[buffLength];
int bytesRead = file.read(fileHeaderBuffer, 0, buffLength);
if (bytesRead != buffLength) {
//ignore if can't read the first few bytes, not an image
return false;
throw new TskCoreException("Could not read " + buffLength + " bytes from " + file.getName());
}
if (bytesRead != 8) {
return false;
}
/*
* Check for the header. Since Java bytes are signed, we cast them
* to an int first.
*/
return (((fileHeaderBuffer[1] & 0xff) == 0x50) && ((fileHeaderBuffer[2] & 0xff) == 0x4E)
&& ((fileHeaderBuffer[3] & 0xff) == 0x47) && ((fileHeaderBuffer[4] & 0xff) == 0x0D)
&& ((fileHeaderBuffer[5] & 0xff) == 0x0A) && ((fileHeaderBuffer[6] & 0xff) == 0x1A)
&& ((fileHeaderBuffer[7] & 0xff) == 0x0A));
return fileHeaderBuffer;
}
/**
* Generate an icon and save it to specified location.
*
* @param content File to generate icon for
* @param content File to generate icon for
* @param iconSize
* @param saveFile Location to save thumbnail to
* @param cacheFile Location to save thumbnail to
*
* @return Generated icon or null on error
*/
private static Image generateAndSaveIcon(Content content, int iconSize, File saveFile) {
private static Image generateAndSaveThumbnail(Content content, int iconSize, File cacheFile) {
AbstractFile f = (AbstractFile) content;
final String extension = f.getNameExtension();
BufferedImage icon = null;
BufferedImage thumbnail = null;
try {
if (SUPP_VIDEO_EXTENSIONS.contains(extension)) {
if (openCVLoaded) {
icon = VideoUtils.generateVideoThumbnail((AbstractFile) content, iconSize);
thumbnail = VideoUtils.generateVideoThumbnail((AbstractFile) content, iconSize);
} else {
return DEFAULT_ICON;
}
} else if (SUPP_IMAGE_EXTENSIONS.contains(extension)) {
icon = generateImageThumbnail(content, iconSize);
thumbnail = generateImageThumbnail(content, iconSize);
}
if (icon == null) {
if (thumbnail == null) {
return DEFAULT_ICON;
} else {
if (saveFile.exists()) {
saveFile.delete();
}
Files.createParentDirs(saveFile);
ImageIO.write(icon, "png", saveFile); //NON-NLS
BufferedImage toSave = thumbnail;
imageSaver.execute(() -> {
try {
Files.createParentDirs(cacheFile);
if (cacheFile.exists()) {
cacheFile.delete();
}
ImageIO.write(toSave, FORMAT, cacheFile);
} catch (IllegalArgumentException | IOException ex1) {
LOGGER.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex1); //NON-NLS
}
});
}
} catch (NullPointerException | IOException ex) {
} catch (NullPointerException ex) {
logger.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex); //NON-NLS
}
return icon;
return thumbnail;
}
/*
/**
*
* Generate and return a scaled image
*
* @param content
* @param iconSize
*
* @return a Thumbnail of the given content at the given size, or null if
* there was a problem.
*/
@Nullable
private static BufferedImage generateImageThumbnail(Content content, int iconSize) {
InputStream inputStream = null;
BufferedImage bi = null;
try {
inputStream = new ReadContentInputStream(content);
bi = ImageIO.read(inputStream);
try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(content));) {
BufferedImage bi = ImageIO.read(inputStream);
if (bi == null) {
logger.log(Level.WARNING, "No image reader for file: " + content.getName()); //NON-NLS
LOGGER.log(Level.WARNING, "No image reader for file: {0}", content.getName()); //NON-NLS
return null;
}
return ScalrWrapper.resizeFast(bi, iconSize);
} catch (IllegalArgumentException e) {
// if resizing does not work due to extremely small height/width ratio,
// crop the image instead.
BufferedImage biCropped = ScalrWrapper.cropImage(bi, Math.min(iconSize, bi.getWidth()), Math.min(iconSize, bi.getHeight()));
return biCropped;
try {
return ScalrWrapper.resizeFast(bi, iconSize);
} catch (IllegalArgumentException e) {
// if resizing does not work due to extreme aspect ratio,
// crop the image instead.
return ScalrWrapper.cropImage(bi, Math.min(iconSize, bi.getWidth()), Math.min(iconSize, bi.getHeight()));
}
} catch (OutOfMemoryError e) {
logger.log(Level.WARNING, "Could not scale image (too large): " + content.getName(), e); //NON-NLS
LOGGER.log(Level.WARNING, "Could not scale image (too large): " + content.getName(), e); //NON-NLS
return null;
} catch (Exception e) {
logger.log(Level.WARNING, "Could not scale image: " + content.getName(), e); //NON-NLS
LOGGER.log(Level.WARNING, "Could not scale image: " + content.getName(), e); //NON-NLS
return null;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not close input stream after resizing thumbnail: " + content.getName(), ex); //NON-NLS
}
}
}
}
@ -411,7 +556,4 @@ public class ImageUtils {
}
progress.finish();
}
private ImageUtils() {
}
}

View File

@ -53,7 +53,9 @@ public class MessageNotifyUtil {
INFO(NotifyDescriptor.INFORMATION_MESSAGE, "info-icon-16.png"), //NON-NLS
ERROR(NotifyDescriptor.ERROR_MESSAGE, "error-icon-16.png"), //NON-NLS
WARNING(NotifyDescriptor.WARNING_MESSAGE, "warning-icon-16.png"); //NON-NLS
WARNING(NotifyDescriptor.WARNING_MESSAGE, "warning-icon-16.png"), //NON-NLS
CONFIRM(NotifyDescriptor.YES_NO_OPTION, "warning-icon-16.png"); //NON-NLS
private final int notifyDescriptorType;
private final Icon icon;
@ -110,6 +112,17 @@ public class MessageNotifyUtil {
getDialogDisplayer().notify(new NotifyDescriptor.Message(message,
messageType.getNotifyDescriptorType()));
}
/**
* Show an confirm, yes-no dialog
*
* @param message message to show
* @return true if yes is clicked
*/
public static boolean confirm(String message) {
return getDialogDisplayer().notify(new NotifyDescriptor.Confirmation(message,
MessageType.CONFIRM.getNotifyDescriptorType())) == NotifyDescriptor.YES_OPTION;
}
/**
* Show an information dialog
@ -123,7 +136,7 @@ public class MessageNotifyUtil {
/**
* Show an error dialog
*
* @param message message to shpw
* @param message message to show
*/
public static void error(String message) {
show(message, MessageType.ERROR);
@ -137,6 +150,7 @@ public class MessageNotifyUtil {
public static void warn(String message) {
show(message, MessageType.WARNING);
}
}
/**
@ -164,6 +178,10 @@ public class MessageNotifyUtil {
/**
* Show message with the specified type and action listener
* @param title message title
* @param message message text
* @param type type of the message
* @param actionListener action listener
*/
public static void show(String title, String message, MessageType type, ActionListener actionListener) {
Notification newNotification

View File

@ -280,3 +280,9 @@ VolumeNode.createSheet.flags.displayName=Flags
VolumeNode.createSheet.flags.desc=no description
AbstractAbstractFileNode.objectId=Object ID
ArtifactStringContent.getStr.artifactId.text=Artifact ID
DeleteReportAction.actionDisplayName.singleReport=Delete Report
DeleteReportAction.actionDisplayName.multipleReports=Delete Reports
DeleteReportAction.actionPerformed.showConfirmDialog.title=Confirm Deletion
DeleteReportAction.actionPerformed.showConfirmDialog.single.msg=Do you want to delete 1 report?
DeleteReportAction.actionPerformed.showConfirmDialog.multiple.msg=Do you want to delete {0} reports?
DeleteReportAction.actionPerformed.showConfirmDialog.checkbox.msg=Check to delete reports from the disk.

View File

@ -21,10 +21,10 @@ package org.sleuthkit.autopsy.datamodel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Action;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction;
@ -118,7 +118,7 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
// Images
for (String s : FileTypeExtensions.getImageExtensions()) {
if (ext.equals(s)) {
if (ImageUtils.thumbnailSupported(file) || ext.equals(s)) {
return "org/sleuthkit/autopsy/images/image-file.png"; //NON-NLS
}
}

View File

@ -27,18 +27,22 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.TskCoreException;
@ -97,7 +101,7 @@ public final class Reports implements AutopsyVisitableItem {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName();
if (eventType.equals(Case.Events.REPORT_ADDED.toString())) {
if (eventType.equals(Case.Events.REPORT_ADDED.toString()) || eventType.equals(Case.Events.REPORT_DELETED.toString())) {
ReportNodeFactory.this.refresh(true);
}
}
@ -183,6 +187,7 @@ public final class Reports implements AutopsyVisitableItem {
List<Action> actions = new ArrayList<>();
actions.addAll(Arrays.asList(super.getActions(true)));
actions.add(new OpenReportAction());
actions.add(DeleteReportAction.getInstance());
return actions.toArray(new Action[actions.size()]);
}
@ -191,6 +196,58 @@ public final class Reports implements AutopsyVisitableItem {
return new OpenReportAction();
}
private static class DeleteReportAction extends AbstractAction {
private static DeleteReportAction instance;
// This class is a singleton to support multi-selection of nodes,
// since org.openide.nodes.NodeOp.findActions(Node[] nodes) will
// only pick up an Action if every node in the array returns a
// reference to the same action object from Node.getActions(boolean).
private static DeleteReportAction getInstance() {
if (instance == null) {
instance = new DeleteReportAction();
}
if (Utilities.actionsGlobalContext().lookupAll(Report.class).size() == 1) {
instance.putValue(Action.NAME, NbBundle.getMessage(Reports.class, "DeleteReportAction.actionDisplayName.singleReport"));
} else {
instance.putValue(Action.NAME, NbBundle.getMessage(Reports.class, "DeleteReportAction.actionDisplayName.multipleReports"));
}
return instance;
}
/**
* Do not instantiate directly. Use
* DeleteReportAction.getInstance(), instead.
*/
private DeleteReportAction() {
}
@Override
public void actionPerformed(ActionEvent e) {
Collection<? extends Report> selectedReportsCollection = Utilities.actionsGlobalContext().lookupAll(Report.class);
String jOptionPaneMessage = selectedReportsCollection.size() > 1
? NbBundle.getMessage(Reports.class, "DeleteReportAction.actionPerformed.showConfirmDialog.multiple.msg", selectedReportsCollection.size())
: NbBundle.getMessage(Reports.class, "DeleteReportAction.actionPerformed.showConfirmDialog.single.msg");
JCheckBox checkbox = new JCheckBox(NbBundle.getMessage(Reports.class, "DeleteReportAction.actionPerformed.showConfirmDialog.checkbox.msg"));
checkbox.setSelected(false);
Object[] jOptionPaneContent = {jOptionPaneMessage, checkbox};
if (JOptionPane.showConfirmDialog(null, jOptionPaneContent,
NbBundle.getMessage(Reports.class, "DeleteReportAction.actionPerformed.showConfirmDialog.title"),
JOptionPane.YES_NO_OPTION) == 0) {
try {
Case.getCurrentCase().deleteReports(selectedReportsCollection, checkbox.isSelected());
DataContentTopComponent.findInstance().repaint();
} catch (TskCoreException | IllegalStateException ex) {
Logger.getLogger(DeleteReportAction.class.getName()).log(Level.INFO, "Error deleting the reports. ", ex); // NON-NLS - Provide solution to the user?
}
}
}
}
private final class OpenReportAction extends AbstractAction {
private OpenReportAction() {

View File

@ -118,7 +118,10 @@ public class DataResultFilterNode extends FilterNode {
List<Action> actions = new ArrayList<>();
final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
actions.addAll(originalNode.accept(getActionsDIV));
List<Action> accept = originalNode.accept(getActionsDIV);
if(accept != null) {
actions.addAll(accept);
}
//actions.add(new IndexContentFilesAction(nodeContent, "Index"));
return actions.toArray(new Action[actions.size()]);

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseDialog.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="instructionLabel" min="-2" pref="220" max="-2" attributes="0"/>
<EmptySpace min="0" pref="41" max="32767" attributes="0"/>
</Group>
<Component id="jScrollPane1" max="32767" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="AddValuesToHashDatabaseButton" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="1" min="-2" pref="151" max="-2" attributes="0"/>
<Component id="pasteFromClipboardButton" alignment="1" min="-2" pref="151" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="instructionLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="AddValuesToHashDatabaseButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="pasteFromClipboardButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" pref="274" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="instructionLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseDialog.instructionLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="hashValuesTextArea">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
</Properties>
<Events>
<EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="hashValuesTextAreaMouseClicked"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="pasteFromClipboardButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pasteFromClipboardButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="AddValuesToHashDatabaseButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="AddValuesToHashDatabaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseDialog.cancelButton.text_2" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,231 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 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.modules.hashdatabase;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.datamodel.HashEntry;
/**
*
* @author sidhesh
*/
public class AddHashValuesToDatabaseDialog extends javax.swing.JDialog {
HashDb hashDb;
Pattern md5Pattern = Pattern.compile("^[a-fA-F0-9]{32}$");
List<HashEntry> hashes = new ArrayList<>();
List<String> invalidHashes = new ArrayList<>();
/**
* Displays a dialog that allows a user to add hash values to the selected
* database.
*/
AddHashValuesToDatabaseDialog(HashDb hashDb) {
super(new JFrame(),
NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.JDialog.Title", hashDb.getHashSetName()),
true);
this.hashDb = hashDb;
initComponents();
display();
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
/**
* Toggle the buttons and default close operation.
*
* @param enable Set true to enable buttons and DISPOSE_ON_CLOSE. Set false
* to disable buttons and DO_NOTHING_ON_CLOSE
*/
void enableAddHashValuesToDatabaseDialog(boolean enable) {
if (enable) {
setDefaultCloseOperation(2);
} else {
setDefaultCloseOperation(0);
}
AddValuesToHashDatabaseButton.setEnabled(enable);
cancelButton.setEnabled(enable);
pasteFromClipboardButton.setEnabled(enable);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
instructionLabel = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
hashValuesTextArea = new javax.swing.JTextArea();
pasteFromClipboardButton = new javax.swing.JButton();
AddValuesToHashDatabaseButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.title")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(instructionLabel, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.instructionLabel.text_1")); // NOI18N
hashValuesTextArea.setColumns(20);
hashValuesTextArea.setRows(5);
hashValuesTextArea.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
hashValuesTextAreaMouseClicked(evt);
}
});
jScrollPane1.setViewportView(hashValuesTextArea);
org.openide.awt.Mnemonics.setLocalizedText(pasteFromClipboardButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2")); // NOI18N
pasteFromClipboardButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pasteFromClipboardButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(AddValuesToHashDatabaseButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2")); // NOI18N
AddValuesToHashDatabaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
AddValuesToHashDatabaseButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.cancelButton.text_2")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(instructionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 41, Short.MAX_VALUE))
.addComponent(jScrollPane1))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(AddValuesToHashDatabaseButton, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(cancelButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 151, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(pasteFromClipboardButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 151, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(instructionLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(AddValuesToHashDatabaseButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pasteFromClipboardButton))
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void pasteFromClipboardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pasteFromClipboardButtonActionPerformed
hashValuesTextArea.paste();
hashValuesTextArea.append("\n");
// TODO - Avoid unnecessary \n appending in case nothing is pasted.
}//GEN-LAST:event_pasteFromClipboardButtonActionPerformed
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
this.dispose();
}//GEN-LAST:event_cancelButtonActionPerformed
private void hashValuesTextAreaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_hashValuesTextAreaMouseClicked
if (SwingUtilities.isRightMouseButton(evt)) {
JPopupMenu popup = new JPopupMenu();
JMenuItem cutMenu = new JMenuItem("Cut"); // NON-NLS
cutMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hashValuesTextArea.cut();
}
});
JMenuItem copyMenu = new JMenuItem("Copy"); // NON-NLS
copyMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hashValuesTextArea.copy();
}
});
JMenuItem pasteMenu = new JMenuItem("Paste"); // NON-NLS
pasteMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hashValuesTextArea.paste();
hashValuesTextArea.append("\n");
}
});
popup.add(cutMenu);
popup.add(copyMenu);
popup.add(pasteMenu);
popup.show(hashValuesTextArea, evt.getX(), evt.getY());
}
}//GEN-LAST:event_hashValuesTextAreaMouseClicked
private void AddValuesToHashDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddValuesToHashDatabaseButtonActionPerformed
AddHashValuesToDatabaseProgressDialog progressDialog = new AddHashValuesToDatabaseProgressDialog(this, hashDb, hashValuesTextArea.getText());
progressDialog.addHashValuesToDatabase();
}//GEN-LAST:event_AddValuesToHashDatabaseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton AddValuesToHashDatabaseButton;
private javax.swing.JButton cancelButton;
private javax.swing.JTextArea hashValuesTextArea;
private javax.swing.JLabel instructionLabel;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton pasteFromClipboardButton;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="0"/>
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseProgressDialog.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" attributes="0">
<Component id="statusLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="showErrorsButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="addingHashesToDatabaseProgressBar" min="-2" pref="300" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="okButton" min="-2" pref="91" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="addingHashesToDatabaseProgressBar" min="-2" max="-2" attributes="0"/>
<Component id="okButton" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="showErrorsButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="statusLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JProgressBar" name="addingHashesToDatabaseProgressBar">
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="addingHashesToDatabaseProgressBar.setIndeterminate(true);"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseProgressDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="okButton.setEnabled(false);"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="statusLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseProgressDialog.statusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="showErrorsButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="AddHashValuesToDatabaseProgressDialog.showErrorsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showErrorsButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="showErrorsButton.setVisible(false);"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,273 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 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.modules.hashdatabase;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.datamodel.HashEntry;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
* @author sidhesh
*/
public class AddHashValuesToDatabaseProgressDialog extends javax.swing.JDialog {
private final AddHashValuesToDatabaseDialog parentRef;
private boolean disposeParent = false;
private final HashDb hashDb;
private final List<HashEntry> hashes;
private final List<String> invalidHashes;
private final Pattern md5Pattern;
private String errorTitle;
private String errorMessage;
private final String text;
/**
* Creates new form AddHashValuesToDatabaseProgressDialog
*
* @param parent
* @param hashDb
* @param text
*/
AddHashValuesToDatabaseProgressDialog(AddHashValuesToDatabaseDialog parent, HashDb hashDb, String text) {
super(parent);
initComponents();
display();
this.hashes = new ArrayList<>();
this.invalidHashes = new ArrayList<>();
this.md5Pattern = Pattern.compile("^[a-fA-F0-9]{32}$"); // NON-NLS
this.parentRef = parent;
this.hashDb = hashDb;
this.text = text;
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
/**
* Executes a SwingWorker which performs addition of hashes into the
* database.
*/
final void addHashValuesToDatabase() {
parentRef.enableAddHashValuesToDatabaseDialog(false);
new SwingWorker<Object, Void>() {
@Override
protected Object doInBackground() throws Exception {
// parse the text for md5 hashes.
statusLabel.setText(NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.parsing"));
getHashesFromTextArea(text);
// Perform checks for invalid input. Then perform insertion
// of hashes in the database.
if (!invalidHashes.isEmpty()) {
statusLabel.setText(NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invalidHash"));
finish(false);
errorTitle = NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invaliHash.msg");
errorMessage = "";
for (String invalidHash : invalidHashes) {
errorMessage = errorMessage + invalidHash + "\n"; // NON-NLS
}
showErrorsButton.setVisible(true);
showErrorsButton.requestFocus();
} else if (hashes.isEmpty()) {
statusLabel.setText(NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.noHashesToAdd"));
finish(false);
} else {
try {
hashDb.addHashes(hashes);
okButton.requestFocus();
statusLabel.setText(NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.success", hashes.size()));
finish(true);
disposeParent = true;
} catch (TskCoreException ex) {
statusLabel.setText(NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash"));
finish(false);
errorTitle = NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash.msg");
errorMessage = ex.toString();
showErrorsButton.setVisible(true);
showErrorsButton.requestFocus();
}
}
return null;
}
}.execute();
}
/**
* Sets the progressbar to maximum value, change colors accordingly, and
* enables OK button.
*
* @param success
*/
private void finish(boolean success) {
okButton.setEnabled(true);
addingHashesToDatabaseProgressBar.setIndeterminate(false);
addingHashesToDatabaseProgressBar.setValue(addingHashesToDatabaseProgressBar.getMaximum());
if (success) {
// a hack to set progressbar color.
addingHashesToDatabaseProgressBar.setStringPainted(true);
addingHashesToDatabaseProgressBar.setForeground(new Color(50,205,50));
addingHashesToDatabaseProgressBar.setString("");
} else {
// a hack to set progressbar color.
addingHashesToDatabaseProgressBar.setStringPainted(true);
addingHashesToDatabaseProgressBar.setForeground(new Color(178,34,34));
addingHashesToDatabaseProgressBar.setString("");
}
}
/**
* Parses for String for MD5 hashes and adds new HashEntry objects into the
* list of hashes. It also populates the invalidHashes list for
* user-feedback.
*
* @param text
*/
private void getHashesFromTextArea(String text) {
String[] linesInTextArea = text.split("\\r?\\n"); // NON-NLS
// These entries may be of <MD5> or <MD5, comment> format
for (String hashEntry : linesInTextArea) {
hashEntry = hashEntry.trim();
Matcher m = md5Pattern.matcher(hashEntry);
if (m.find()) {
// more information can be added to the HashEntry - sha-1, sha-512, comment
hashes.add(new HashEntry(null, m.group(0), null, null, null));
} else {
if (!hashEntry.isEmpty()) {
invalidHashes.add(hashEntry);
}
}
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
addingHashesToDatabaseProgressBar = new javax.swing.JProgressBar();
okButton = new javax.swing.JButton();
statusLabel = new javax.swing.JLabel();
showErrorsButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle(org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.title")); // NOI18N
addingHashesToDatabaseProgressBar.setIndeterminate(true);
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.okButton.text")); // NOI18N
okButton.setEnabled(false);
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(statusLabel, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.statusLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(showErrorsButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseProgressDialog.class, "AddHashValuesToDatabaseProgressDialog.showErrorsButton.text")); // NOI18N
showErrorsButton.setVisible(false);
showErrorsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
showErrorsButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(statusLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(showErrorsButton))
.addGroup(layout.createSequentialGroup()
.addComponent(addingHashesToDatabaseProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 300, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(addingHashesToDatabaseProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(okButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(showErrorsButton)
.addComponent(statusLabel))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
parentRef.enableAddHashValuesToDatabaseDialog(true);
if (disposeParent) {
parentRef.dispose();
}
this.dispose();
}//GEN-LAST:event_okButtonActionPerformed
private void showErrorsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showErrorsButtonActionPerformed
JLabel textLabel = new JLabel(errorTitle);
JTextArea textArea = new JTextArea(errorMessage);
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(250, 100));
Object[] jOptionPaneComponents = {textLabel, scrollPane};
JOptionPane.showMessageDialog(this, jOptionPaneComponents, "Error:\n", JOptionPane.OK_OPTION); // NON-NLS
}//GEN-LAST:event_showErrorsButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JProgressBar addingHashesToDatabaseProgressBar;
private javax.swing.JButton okButton;
private javax.swing.JButton showErrorsButton;
private javax.swing.JLabel statusLabel;
// End of variables declaration//GEN-END:variables
}

View File

@ -196,3 +196,21 @@ HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected setting
HashLookupModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=Calculate MD5 even if no hash database is selected
HashDbSearchPanel.hashTable.defaultModel.title.text=MD5 Hashes
AddHashValuesToDatabaseDialog.JDialog.Title=Add Hashes to Database
HashLookupSettingsPanel.addHashesToDatabaseButton.text=Add Hashes to Database
AddHashValuesToDatabaseDialog.instructionLabel.text_1=Paste MD5 hash values (one per line) below:
AddHashValuesToDatabaseDialog.cancelButton.text_2=Cancel
AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2=Add Hashes to Database
AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2=Paste From Clipboard
AddHashValuesToDatabaseProgressDialog.okButton.text=OK
AddHashValuesToDatabaseProgressDialog.statusLabel.text=status
AddHashValuesToDatabaseProgressDialog.title=Add Hashes to Database Progress
AddHashValuesToDatabaseDialog.title=Add Hashes to Database
AddHashValuesToDatabaseProgressDialog.showErrorsButton.text=Show Errors
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.parsing=Parsing text for MD5 hashes...
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invalidHash=The input contains invalid hash.
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invaliHash.msg=Invalid Hashes:
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.noHashesToAdd=There are no hashes to add.
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.success={0} Hashes added successfully.
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash=There is an error adding valid hashes.
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash.msg=Error adding valid hashes to the database:

View File

@ -1,194 +1,194 @@
OpenIDE-Module-Display-Category=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB
OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
OpenIDE-Module-Long-Description=\
\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB \n\n\
\u30C7\u30A3\u30B9\u30AF\u30A4\u30E1\u30FC\u30B8\u306B\u3042\u308B\u30D5\u30A1\u30A4\u30EB\u3092\u89E3\u6790\u3057\u3001\u300C\u65E2\u77E5\u300D\uFF08NSRL\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u300C\u65E2\u77E5\u300D\u30D5\u30A1\u30A4\u30EB\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u3092\u57FA\u306B\uFF09\u307E\u305F\u306F\u300C\u60AA\u8CEA\uFF0F\u7591\u308F\u3057\u3044\u300D\uFF08\u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\uFF11\u3064\u307E\u305F\u306F\u8907\u6570\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u57FA\u306B\uFF09\u3068\u30DE\u30FC\u30AF\u3057\u307E\u3059\u3002\n\n\
\u30CF\u30C3\u30B7\u30E5\u3084\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u8A2D\u5B9A\u306B\u57FA\u3065\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u306A\u3069\u3001\u3053\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306FGUI\u306B\u9023\u643A\u3057\u3066\u3044\u308B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3057\u306A\u3044\u3001\u8FFD\u52A0\u306E\u30C4\u30FC\u30EB\u304C\u542B\u307E\u308C\u307E\u3059\u3002
OpenIDE-Module-Name=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbSearchPanel.hashTable.columnModel.title0=MD5\u30CF\u30C3\u30B7\u30E5
HashDbSearchPanel.addButton.text=\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
HashDbSearchPanel.hashLabel.text=MD5\u30CF\u30C3\u30B7\u30E5\uFF1A
HashDbSearchPanel.searchButton.text=\u691C\u7D22
HashDbSearchPanel.removeButton.text=\u9078\u629E\u3057\u305F\u3082\u306E\u3092\u524A\u9664
HashDbSearchPanel.titleLabel.text=\u4E0B\u8A18\u306EMD5\u30CF\u30C3\u30B7\u30E5\u4ED8\u304D\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\uFF1A
HashDbSearchPanel.errorField.text=\u30A8\u30E9\u30FC\uFF1A\u5168\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u30CF\u30C3\u30B7\u30E5\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002
HashDbSearchPanel.saveBox.text=\u30CF\u30C3\u30B7\u30E5\u3092\u8A18\u61B6
HashDbSearchPanel.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
OpenIDE-Module-Short-Description=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u304A\u3088\u3073\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30C4\u30FC\u30EB
HashDbImportDatabaseDialog.jLabel1.text=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\uFF1A
HashDbImportDatabaseDialog.knownBadRadioButton.text=\u65E2\u77E5\u306E\u60AA\u8CEA
HashDbImportDatabaseDialog.jLabel2.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30BF\u30A4\u30D7\uFF1A
\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb \n\n\
\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u306b\u3042\u308b\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u3057\u3001\u300c\u65e2\u77e5\u300d\uff08NSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u300c\u65e2\u77e5\u300d\u30d5\u30a1\u30a4\u30eb\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u57fa\u306b\uff09\u307e\u305f\u306f\u300c\u60aa\u8cea\uff0f\u7591\u308f\u3057\u3044\u300d\uff08\u30e6\u30fc\u30b6\u30fc\u304c\u6307\u5b9a\u3057\u305f\uff11\u3064\u307e\u305f\u306f\u8907\u6570\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u57fa\u306b\uff09\u3068\u30de\u30fc\u30af\u3057\u307e\u3059\u3002\n\n\
\u30cf\u30c3\u30b7\u30e5\u3084\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a\u306b\u57fa\u3065\u3044\u305f\u30d5\u30a1\u30a4\u30eb\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u306a\u3069\u3001\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306fGUI\u306b\u9023\u643a\u3057\u3066\u3044\u308b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3057\u306a\u3044\u3001\u8ffd\u52a0\u306e\u30c4\u30fc\u30eb\u304c\u542b\u307e\u308c\u307e\u3059\u3002
OpenIDE-Module-Name=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbSearchPanel.hashTable.columnModel.title0=MD5\u30cf\u30c3\u30b7\u30e5
HashDbSearchPanel.addButton.text=\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
HashDbSearchPanel.hashLabel.text=MD5\u30cf\u30c3\u30b7\u30e5\uff1a
HashDbSearchPanel.searchButton.text=\u691c\u7d22
HashDbSearchPanel.removeButton.text=\u9078\u629e\u3057\u305f\u3082\u306e\u3092\u524a\u9664
HashDbSearchPanel.titleLabel.text=\u4e0b\u8a18\u306eMD5\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\uff1a
HashDbSearchPanel.errorField.text=\u30a8\u30e9\u30fc\uff1a\u5168\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u30cf\u30c3\u30b7\u30e5\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002
HashDbSearchPanel.saveBox.text=\u30cf\u30c3\u30b7\u30e5\u3092\u8a18\u61b6
HashDbSearchPanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
OpenIDE-Module-Short-Description=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u304a\u3088\u3073\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c4\u30fc\u30eb
HashDbImportDatabaseDialog.jLabel1.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\uff1a
HashDbImportDatabaseDialog.knownBadRadioButton.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbImportDatabaseDialog.jLabel2.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30bf\u30a4\u30d7\uff1a
HashDbImportDatabaseDialog.okButton.text=OK
HashDbImportDatabaseDialog.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
HashDbCreateDatabaseDialog.jLabel2.text=\u30BF\u30A4\u30D7\uFF1A
HashDbCreateDatabaseDialog.knownBadRadioButton.text=\u65E2\u77E5\u306E\u60AA\u8CEA
HashDbCreateDatabaseDialog.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
ModalNoButtons.CURRENTLYON_LABEL.text=y\u306Ex\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.GO_GET_COFFEE_LABEL.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D\u3067\u3059\u3002\u6642\u9593\u304C\u304B\u304B\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002
ModalNoButtons.CANCEL_BUTTON.text=\u30AD\u30E3\u30F3\u30BB\u30EB
HashDbImportDatabaseDialog.knownRadioButton.text=\u65E2\u77E5\uFF08NSRL\u307E\u305F\u306F\u305D\u306E\u4ED6\uFF09
HashDbCreateDatabaseDialog.knownRadioButton.text=\u65E2\u77E5
HashDbCreateDatabaseDialog.jLabel1.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\uFF1A
HashDbCreateDatabaseDialog.saveAsButton.text=\u540D\u524D\u3092\u3064\u3051\u3066\u4FDD\u5B58\u2026
HashDbImportDatabaseDialog.jLabel3.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\uFF1A
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=\u30D2\u30C3\u30C8\u6BCE\u306B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u9001\u308B
HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=\u30D2\u30C3\u30C8\u6BCE\u306B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u9001\u308B
HashDbImportDatabaseDialog.openButton.text=\u958B\u304F...
HashDbCreateDatabaseDialog.jLabel3.text=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\uFF1A
HashDbImportDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbCreateDatabaseDialog.jLabel2.text=\u30bf\u30a4\u30d7\uff1a
HashDbCreateDatabaseDialog.knownBadRadioButton.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbCreateDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
ModalNoButtons.CURRENTLYON_LABEL.text=y\u306ex\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.GO_GET_COFFEE_LABEL.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u3067\u3059\u3002\u6642\u9593\u304c\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002
ModalNoButtons.CANCEL_BUTTON.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbImportDatabaseDialog.knownRadioButton.text=\u65e2\u77e5\uff08NSRL\u307e\u305f\u306f\u305d\u306e\u4ed6\uff09
HashDbCreateDatabaseDialog.knownRadioButton.text=\u65e2\u77e5
HashDbCreateDatabaseDialog.jLabel1.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashDbCreateDatabaseDialog.saveAsButton.text=\u540d\u524d\u3092\u3064\u3051\u3066\u4fdd\u5b58\u2026
HashDbImportDatabaseDialog.jLabel3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=\u30d2\u30c3\u30c8\u6bce\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=\u30d2\u30c3\u30c8\u6bce\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashDbImportDatabaseDialog.openButton.text=\u958b\u304f...
HashDbCreateDatabaseDialog.jLabel3.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\uff1a
HashDbCreateDatabaseDialog.okButton.text=OK
AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
AddContentToHashDbAction.ContentMenu.createDbItem=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4F5C\u6210...
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr1.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A8\u30E9\u30FC\u306B\u8FFD\u52A0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr2.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A8\u30E9\u30FC\u306B\u8FFD\u52A0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr3.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A8\u30E9\u30FC\u306B\u8FFD\u52A0
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B{0}\u3092\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileSzMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B{0}\u3092\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30CF\u30C3\u30B7\u30E5\u5024\u304C\u8A08\u7B97\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u9069\u5207\u306A\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u8A2D\u5B9A\u3057\u3001\u5B9F\u884C\u3057\u3066\u4E0B\u3055\u3044\u3002
HashDatabaseOptionsPanelController.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
HashDatabaseOptionsPanelController.moduleErrMsg=HashDatabaseOptionsPanelController\u306E\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3067\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u5B8C\u5168\u3067\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
HashDbConfigPanel.noSelectionText=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashDbConfigPanel.errorGettingPathText=\u30D1\u30B9\u306E\u53D6\u5F97\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
HashDbConfigPanel.errorGettingIndexStatusText=\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u78BA\u8A8D\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
HashDbConfigPanel.setName.hashSetConfig=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u8A2D\u5B9A
HashDbConfigPanel.indexButtonText.index=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9
HashDbConfigPanel.indexButtonText.indexing=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
HashDbConfigPanel.indexStatusText.indexGen=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3092\u4F5C\u6210\u4E2D\u3067\u3059
HashDbConfigPanel.indexStatusText.indexOnly=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306E\u307F
HashDbConfigPanel.indexStatusText.indexed=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u6E08\u307F
HashDbConfigPanel.indexButtonText.reIndex=\u518D\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9
HashDbConfigPanel.indexStatusText.noIndex=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u7121\u3057
HashDbConfigPanel.dbsNotIndexedMsg=\u4E0B\u8A18\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3057\u307E\u3059\u304B\uFF1F\n {0}
HashDbConfigPanel.unindexedDbsMsg=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbConfigPanel.allUnindexedDbsRmFromListMsg=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u30EA\u30B9\u30C8\u304B\u3089\u524A\u9664\u3055\u308C\u307E\u3059
HashDbConfigPanel.nameColLbl=\u540D\u524D
HashDbConfigPanel.editingCellsNotSupportedMsg=\u30BB\u30EB\u306F\u7DE8\u96C6\u4E0D\u53EF\u3067\u3059
HashDbConfigPanel.deleteDbActionConfirmMsg=\u5168\u3066\u306E\u30B1\u30FC\u30B9\u306B\u304A\u3051\u308B\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u524A\u9664\u3057\u307E\u3059\u3002\u5B9F\u884C\u3057\u307E\u3059\u304B\uFF1F
HashDbConfigPanel.deleteDbActionMsg=\u8A2D\u5B9A\u304B\u3089\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u524A\u9664
HashDbCreateDatabaseDialog.createHashDbMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4F5C\u6210
HashDbCreateDatabaseDialog.hashDbMustHaveFileExtensionMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u306F .{0} \u306E\u62E1\u5F35\u5B50\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.fileNameErr=\u30D5\u30A1\u30A4\u30EB\u540D\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.fileNameAlreadyExistsMsg=\u540C\u540D\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u8A2D\u5B9A\u3057\u3066\u4E0B\u3055\u3044\u3002
HashDbCreateDatabaseDialog.fileExistsErr=\u30D5\u30A1\u30A4\u30EB\u304C\u65E2\u306B\u5B58\u5728\u3057\u3066\u3044\u308B\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.mustEnterHashSetNameMsg=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\u306E\u5165\u529B\u304C\u5FC5\u8981\u3067\u3059
HashDbCreateDatabaseDialog.createHashDbErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u4F5C\u6210\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.mustEnterHashDbPathMsg=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\u306E\u5165\u529B\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.errMsg.hashDbCreationErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u4F5C\u6210\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.cannotCreateFileAtLocMsg=\u6307\u5B9A\u3055\u308C\u305F\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\u3067\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002
HashDbCreateDatabaseDialog.failedToCreateHashDbMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
HashDbImportDatabaseDialog.importHashDbMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashDbImportDatabaseDialog.fileNameExtFilter.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB
HashDbImportDatabaseDialog.failedToGetDbPathMsg=\u9078\u629E\u3057\u305F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30D1\u30B9\u306E\u5165\u624B\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
HashDbImportDatabaseDialog.importHashDbErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30DD\u30FC\u30C8\u30A8\u30E9\u30FC
HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u30D1\u30B9\u306E\u9078\u629E\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629E\u3055\u308C\u305F\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u5B58\u5728\u3057\u307E\u305B\u3093\u3002
HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u958B\u304F\u306E\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.moduleName=\u30CF\u30C3\u30B7\u30E5\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7
HashDbIngestModule.moduleDescription=\u6A19\u6E96\u306ENSRL\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306A\u3069\u3001\u63D0\u4F9B\u3055\u308C\u305F\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u5229\u7528\u3057\u3066\u3001\u65E2\u77E5\u307E\u305F\u306F\u7591\u308F\u3057\u3044\u3082\u306E\u3092\u7279\u5B9A\u3057\u307E\u3059\u3002
HashDbIngestModule.noKnownHashDbSetMsg=\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002
HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65E2\u77E5\u306E\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\u304C\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002
HashDbIngestModule.noKnownBadHashDbSetMsg=\u65E2\u77E5\u306E\u60AA\u8CEA\u306A\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30BB\u30C3\u30C8\u306F\u3042\u308A\u307E\u305B\u3093\u3002
HashDbConfigPanel.dbNotIndexedMsg=\u4E0B\u8A18\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3057\u307E\u3059\u304B\uFF1F\n{0}
HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65E2\u77E5\u306E\u60AA\u8CEA\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\u306F\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002
HashDbIngestModule.fileReadErrorMsg=\u8AAD\u307F\u8FBC\u307F\u30A8\u30E9\u30FC\uFF1A {0}
HashDbIngestModule.calcHashValueErr={0}\u306E\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u8A08\u7B97\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.hashLookupErrorMsg=\u30CF\u30C3\u30B7\u30E5\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u30A8\u30E9\u30FC\uFF1A {0}
HashDbIngestModule.settingKnownBadStateErr={0}\u306E\u30B9\u30C6\u30FC\u30BF\u30B9\u3092\u65E2\u77E5\u306E\u60AA\u8CEA\u3068\u8A2D\u5B9A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306E\u65E2\u77E5\u306E\u60AA\u8CEA\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306E\u65E2\u77E5\u306E\u60AA\u8CEA\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.postToBB.fileName=\u30D5\u30A1\u30A4\u30EB\u540D
HashDbIngestModule.postToBB.md5Hash=MD5\u30CF\u30C3\u30B7\u30E5
HashDbIngestModule.postToBB.hashsetName=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D
HashDbIngestModule.postToBB.knownBadMsg=\u65E2\u77E5\u306E\u60AA\u8CEA\: {0}
HashDbIngestModule.complete.knownBadsFound=\u767A\u898B\u3055\u308C\u305F\u65E2\u77E5\u306E\u60AA\u8CEA\uFF1A
HashDbIngestModule.complete.totalCalcTime=\u8A08\u7B97\u6642\u9593\u306E\u5408\u8A08
HashDbIngestModule.complete.totalLookupTime=\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u6642\u9593\u306E\u5408\u8A08
HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\uFF1A
HashDbIngestModule.complete.hashLookupResults=\u30CF\u30C3\u30B7\u30E5\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u7D50\u679C
HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u539F\u56E0\u306A\u306E\u304B\u3092\u30ED\u30B0\u3067\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u5B8C\u5168\u3067\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
HashDbManager.replacingDuplicateHashsetNameMsg=\u8907\u88FD\u306E\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D {0} \u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002\n {1}\u306B\u66F8\u304D\u63DB\u3048\u307E\u3059\u3002
HashDbManager.openHashDbErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u958B\u304F\u30A8\u30E9\u30FC
HashDbManager.unableToOpenHashDbMsg=\ {0} \u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u958B\u3051\u307E\u305B\u3093\u3002
HashDbManager.savedBackupOfOldConfigMsg={0}\n\u53E4\u3044\u8A2D\u5B9A\u306E\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u30B3\u30D4\u30FC\u304C\u4E0B\u8A18\u306E\u901A\u308A\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F\u3002\n{1}
HashDbManager.baseMessage.updatedFormatHashDbConfig=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306E\u5F62\u5F0F\u304C\u66F4\u65B0\u3055\u308C\u307E\u3057\u305F\u3002
HashDbManager.msgBoxTitle.confFileFmtChanged=\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u306E\u5909\u66F4\u5B8C\u4E86
HashDbManager.dlgMsg.dbNotFoundAtLoc=\ {0} \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u4E0B\u8A18\u306E\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\u306B\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\n {1}\n \u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3057\u307E\u3059\u304B\uFF1F
HashDbManager.dlgTitle.MissingDb=\u6B20\u843D\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbManager.progress.indexingHashSet=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D {0}
HashDbManager.dlgMsg.errorIndexingHashSet=\ {0} \u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D\u306E\u30A8\u30E9\u30FC
HashDbManager.hashDbIndexingErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D\u306E\u30A8\u30E9\u30FC
HashDbPanelSearchAction.actionName=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u57FA\u3065\u304F\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
HashDbSearchAction.dlgMsg.noFilesHaveMD5Calculated=MD5\u30CF\u30C3\u30B7\u30E5\u304C\u8A08\u7B97\u3055\u308C\u3066\u3044\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u307E\u305A\u306FHashDB\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3057\u3066\u4E0B\u3055\u3044\u3002
HashDbSearchManager.MD5HashSearch=MD5\u30CF\u30C3\u30B7\u30E5\u691C\u7D22
HashDbSearchManager.noResultsFoundMsg=\u4E00\u81F4\u3059\u308B\u3082\u306E\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
HashDbSearchPanel.titleText.ingestOngoing=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u4E2D\uFF1B\u5B8C\u4E86\u3059\u308B\u307E\u3067\u3053\u306E\u30B5\u30FC\u30D3\u30B9\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
HashDbSearchPanel.noFilesHaveMD5HashMsg=MD5\u30CF\u30C3\u30B7\u30E5\u4ED8\u304D\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093\u3002
HashDbSearchPanel.errorText.noHashesAddedMsg=\u30A8\u30E9\u30FC\uFF1A\u30CF\u30C3\u30B7\u30E5\u304C\u8FFD\u52A0\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
HashDbSearchPanel.errorText.hashAlreadyAddedMsg=\u30A8\u30E9\u30FC\uFF1A\u30CF\u30C3\u30B7\u30E5\u304C\u65E2\u306B\u8FFD\u52A0\u3055\u308C\u3066\u3044\u307E\u3059\u3002
HashDbSearchPanel.errorText.invalidMD5HashMsg=\u30A8\u30E9\u30FC\uFF1A\u6709\u52B9\u306AMD5\u30CF\u30C3\u30B7\u30E5\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
HashDbSearchThread.progress.cancellingSearch={0}\uFF08\u30AD\u30E3\u30F3\u30BB\u30EB\u4E2D\u2026\uFF09
HashDbSearchThread.name.searching=\u691C\u7D22\u4E2D
HashDbSearchThread.noMoreFilesWithMD5Msg=\u540C\u3058MD5\u30CF\u30C3\u30B7\u30E5\u4ED8\u304D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u4ED6\u306B\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
ModalNoButtons.indexingDbsTitle=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.indexingDbTitle=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.exitHashDbIndexingMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3092\u4E2D\u6B62\u3057\u307E\u3059\u3002\n\
\u4F5C\u6210\u3055\u308C\u305F\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306F\u5229\u7528\u4E0D\u53EF\u3068\u306A\u308A\u307E\u3059\u3002\u7D9A\u884C\u3059\u308B\u5834\u5408\u306F\n\
\u30CF\u30C3\u30B7\u30E5\u30D5\u30A9\u30EB\u30C0\u5185\u306B\u3042\u308B\u3001\u5BFE\u5FDC\u3059\u308B-md5.idx \u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664\u3057\u3066\u4E0B\u3055\u3044\u3002\n\
\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3092\u4E2D\u6B62\u3057\u307E\u3059\u304B\uFF1F
ModalNoButtons.dlgTitle.unfinishedIndexing=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u672A\u5B8C\u4E86
ModalNoButtons.indexThis.currentlyIndexing1Db=\uFF11\u3064\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=\uFF11\uFF0F {0}\u3064\u76EE\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.propChg.currentlyIndexingXofN={0}\uFF0F {1}\u3064\u76EE\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
HashDbManager.duplicateHashSetNameExceptionMsg=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D''{0}''\u306F\u65E2\u306B\u5225\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u4F7F\u308F\u308C\u3066\u3044\u307E\u3059\u3002
HashDbManager.hashDbDoesNotExistExceptionMsg=\u4E0B\u8A18\u3067\u306F\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\n{0}
HashDbManager.hashDbFileExistsExceptionMsg=\u4E0B\u8A18\u306B\u306F\u65E2\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u5B58\u5728\u3057\u307E\u3059\u3002\n{0}
HashDbManager.hashDbAlreadyAddedExceptionMsg=\u4E0B\u8A18\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\n{0}\n\u306F\u65E2\u306B\u4F5C\u6210\u307E\u305F\u306F\u30A4\u30F3\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\u3002
HashDbManager.illegalHashDbFileNameExtensionMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u540D\u306F.{0}\u306E\u62E1\u5F35\u5B50\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbManager.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
HashDbManager.knownBad.text=\u65E2\u77E5\u306E\u60AA\u8CEA
HashDbManager.known.text=\u65E2\u77E5
HashDbManager.fileNameExtensionFilter.title=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB
HashDbSearchAction.dlgMsg.title=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u57FA\u3065\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
HashDbSearchAction.getName.text=\u30CF\u30C3\u30B7\u30E5\u691C\u7D22
HashDbSearchPanel.dlgMsg.title=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u57FA\u3065\u304F\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
AddContentToHashDbAction.singleSelectionName=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0
AddContentToHashDbAction.multipleSelectionName=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0
OptionsCategory_Name_HashDatabase=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
OptionsCategory_Keywords_HashDatabase=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbManager.ingestRunningExceptionMsg=\u51E6\u7406\u4E2D\uFF1B\u5B8C\u4E86\u3059\u308B\u307E\u3067\u3053\u306E\u30B5\u30FC\u30D3\u30B9\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
ModalNoButtons.CURRENTDB_LABEL.text=\uFF08\u73FE\u5728\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\uFF09
HashDbCreateDatabaseDialog.defaultFileName=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8
HashDbManager.saveErrorExceptionMsg=\u30CF\u30C3\u30B7\u30E5\u8A2D\u5B9A\u306E\u4FDD\u5B58\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
AddContentToHashDbAction.addFilesToHashSet.files=\u30D5\u30A1\u30A4\u30EB
AddContentToHashDbAction.addFilesToHashSet.file=\u30D5\u30A1\u30A4\u30EB
HashDbManager.errCreatingIndex.title=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306E\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
HashDbManager.errCreatingIndex.msg=\u4E0B\u8A18\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306E\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF1A {0}
AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
AddContentToHashDbAction.ContentMenu.createDbItem=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210...
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr1.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr2.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr3.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileSzMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u8a08\u7b97\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u9069\u5207\u306a\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u8a2d\u5b9a\u3057\u3001\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002
HashDatabaseOptionsPanelController.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
HashDatabaseOptionsPanelController.moduleErrMsg=HashDatabaseOptionsPanelController\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3067\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002
HashDbConfigPanel.noSelectionText=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashDbConfigPanel.errorGettingPathText=\u30d1\u30b9\u306e\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
HashDbConfigPanel.errorGettingIndexStatusText=\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
HashDbConfigPanel.setName.hashSetConfig=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u8a2d\u5b9a
HashDbConfigPanel.indexButtonText.index=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashDbConfigPanel.indexButtonText.indexing=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
HashDbConfigPanel.indexStatusText.indexGen=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u4f5c\u6210\u4e2d\u3067\u3059
HashDbConfigPanel.indexStatusText.indexOnly=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u307f
HashDbConfigPanel.indexStatusText.indexed=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u6e08\u307f
HashDbConfigPanel.indexButtonText.reIndex=\u518d\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashDbConfigPanel.indexStatusText.noIndex=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u7121\u3057
HashDbConfigPanel.dbsNotIndexedMsg=\u4e0b\u8a18\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n {0}
HashDbConfigPanel.unindexedDbsMsg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbConfigPanel.allUnindexedDbsRmFromListMsg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30ea\u30b9\u30c8\u304b\u3089\u524a\u9664\u3055\u308c\u307e\u3059
HashDbConfigPanel.nameColLbl=\u540d\u524d
HashDbConfigPanel.editingCellsNotSupportedMsg=\u30bb\u30eb\u306f\u7de8\u96c6\u4e0d\u53ef\u3067\u3059
HashDbConfigPanel.deleteDbActionConfirmMsg=\u5168\u3066\u306e\u30b1\u30fc\u30b9\u306b\u304a\u3051\u308b\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664\u3057\u307e\u3059\u3002\u5b9f\u884c\u3057\u307e\u3059\u304b\uff1f
HashDbConfigPanel.deleteDbActionMsg=\u8a2d\u5b9a\u304b\u3089\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664
HashDbCreateDatabaseDialog.createHashDbMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210
HashDbCreateDatabaseDialog.hashDbMustHaveFileExtensionMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f .{0} \u306e\u62e1\u5f35\u5b50\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.fileNameErr=\u30d5\u30a1\u30a4\u30eb\u540d\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.fileNameAlreadyExistsMsg=\u540c\u540d\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002\u5225\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u8a2d\u5b9a\u3057\u3066\u4e0b\u3055\u3044\u3002
HashDbCreateDatabaseDialog.fileExistsErr=\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u3066\u3044\u308b\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.mustEnterHashSetNameMsg=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\u306e\u5165\u529b\u304c\u5fc5\u8981\u3067\u3059
HashDbCreateDatabaseDialog.createHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u4f5c\u6210\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.mustEnterHashDbPathMsg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\u306e\u5165\u529b\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.errMsg.hashDbCreationErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u4f5c\u6210\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.cannotCreateFileAtLocMsg=\u6307\u5b9a\u3055\u308c\u305f\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002
HashDbCreateDatabaseDialog.failedToCreateHashDbMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
HashDbImportDatabaseDialog.importHashDbMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashDbImportDatabaseDialog.fileNameExtFilter.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
HashDbImportDatabaseDialog.failedToGetDbPathMsg=\u9078\u629e\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d1\u30b9\u306e\u5165\u624b\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
HashDbImportDatabaseDialog.importHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30dd\u30fc\u30c8\u30a8\u30e9\u30fc
HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u9078\u629e\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629e\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.moduleName=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7
HashDbIngestModule.moduleDescription=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u3001\u63d0\u4f9b\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5229\u7528\u3057\u3066\u3001\u65e2\u77e5\u307e\u305f\u306f\u7591\u308f\u3057\u3044\u3082\u306e\u3092\u7279\u5b9a\u3057\u307e\u3059\u3002
HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002
HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002
HashDbConfigPanel.dbNotIndexedMsg=\u4e0b\u8a18\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n{0}
HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002
HashDbIngestModule.fileReadErrorMsg=\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc\uff1a {0}
HashDbIngestModule.calcHashValueErr={0}\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.hashLookupErrorMsg=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u30a8\u30e9\u30fc\uff1a {0}
HashDbIngestModule.settingKnownBadStateErr={0}\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u65e2\u77e5\u306e\u60aa\u8cea\u3068\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.postToBB.fileName=\u30d5\u30a1\u30a4\u30eb\u540d
HashDbIngestModule.postToBB.md5Hash=MD5\u30cf\u30c3\u30b7\u30e5
HashDbIngestModule.postToBB.hashsetName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d
HashDbIngestModule.postToBB.knownBadMsg=\u65e2\u77e5\u306e\u60aa\u8cea\: {0}
HashDbIngestModule.complete.knownBadsFound=\u767a\u898b\u3055\u308c\u305f\u65e2\u77e5\u306e\u60aa\u8cea\uff1a
HashDbIngestModule.complete.totalCalcTime=\u8a08\u7b97\u6642\u9593\u306e\u5408\u8a08
HashDbIngestModule.complete.totalLookupTime=\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u6642\u9593\u306e\u5408\u8a08
HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a
HashDbIngestModule.complete.hashLookupResults=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u7d50\u679c
HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u539f\u56e0\u306a\u306e\u304b\u3092\u30ed\u30b0\u3067\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002
HashDbManager.replacingDuplicateHashsetNameMsg=\u8907\u88fd\u306e\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\n {1}\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002
HashDbManager.openHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u30a8\u30e9\u30fc
HashDbManager.unableToOpenHashDbMsg=\ {0} \u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002
HashDbManager.savedBackupOfOldConfigMsg={0}\n\u53e4\u3044\u8a2d\u5b9a\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u304c\u4e0b\u8a18\u306e\u901a\u308a\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f\u3002\n{1}
HashDbManager.baseMessage.updatedFormatHashDbConfig=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u5f62\u5f0f\u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f\u3002
HashDbManager.msgBoxTitle.confFileFmtChanged=\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u306e\u5909\u66f4\u5b8c\u4e86
HashDbManager.dlgMsg.dbNotFoundAtLoc=\ {0} \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u4e0b\u8a18\u306e\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n {1}\n \u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3057\u307e\u3059\u304b\uff1f
HashDbManager.dlgTitle.MissingDb=\u6b20\u843d\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbManager.progress.indexingHashSet=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d {0}
HashDbManager.dlgMsg.errorIndexingHashSet=\ {0} \u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u306e\u30a8\u30e9\u30fc
HashDbManager.hashDbIndexingErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u306e\u30a8\u30e9\u30fc
HashDbPanelSearchAction.actionName=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
HashDbSearchAction.dlgMsg.noFilesHaveMD5Calculated=MD5\u30cf\u30c3\u30b7\u30e5\u304c\u8a08\u7b97\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u307e\u305a\u306fHashDB\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3057\u3066\u4e0b\u3055\u3044\u3002
HashDbSearchManager.MD5HashSearch=MD5\u30cf\u30c3\u30b7\u30e5\u691c\u7d22
HashDbSearchManager.noResultsFoundMsg=\u4e00\u81f4\u3059\u308b\u3082\u306e\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
HashDbSearchPanel.titleText.ingestOngoing=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\uff1b\u5b8c\u4e86\u3059\u308b\u307e\u3067\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashDbSearchPanel.noFilesHaveMD5HashMsg=MD5\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002
HashDbSearchPanel.errorText.noHashesAddedMsg=\u30a8\u30e9\u30fc\uff1a\u30cf\u30c3\u30b7\u30e5\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
HashDbSearchPanel.errorText.hashAlreadyAddedMsg=\u30a8\u30e9\u30fc\uff1a\u30cf\u30c3\u30b7\u30e5\u304c\u65e2\u306b\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u3059\u3002
HashDbSearchPanel.errorText.invalidMD5HashMsg=\u30a8\u30e9\u30fc\uff1a\u6709\u52b9\u306aMD5\u30cf\u30c3\u30b7\u30e5\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
HashDbSearchThread.progress.cancellingSearch={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
HashDbSearchThread.name.searching=\u691c\u7d22\u4e2d
HashDbSearchThread.noMoreFilesWithMD5Msg=\u540c\u3058MD5\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u4ed6\u306b\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
ModalNoButtons.indexingDbsTitle=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.indexingDbTitle=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.exitHashDbIndexingMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3092\u4e2d\u6b62\u3057\u307e\u3059\u3002\n\
\u4f5c\u6210\u3055\u308c\u305f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f\u5229\u7528\u4e0d\u53ef\u3068\u306a\u308a\u307e\u3059\u3002\u7d9a\u884c\u3059\u308b\u5834\u5408\u306f\n\
\u30cf\u30c3\u30b7\u30e5\u30d5\u30a9\u30eb\u30c0\u5185\u306b\u3042\u308b\u3001\u5bfe\u5fdc\u3059\u308b-md5.idx \u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3057\u3066\u4e0b\u3055\u3044\u3002\n\
\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3092\u4e2d\u6b62\u3057\u307e\u3059\u304b\uff1f
ModalNoButtons.dlgTitle.unfinishedIndexing=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u672a\u5b8c\u4e86
ModalNoButtons.indexThis.currentlyIndexing1Db=\uff11\u3064\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=\uff11\uff0f {0}\u3064\u76ee\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.propChg.currentlyIndexingXofN={0}\uff0f {1}\u3064\u76ee\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
HashDbManager.duplicateHashSetNameExceptionMsg=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d''{0}''\u306f\u65e2\u306b\u5225\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059\u3002
HashDbManager.hashDbDoesNotExistExceptionMsg=\u4e0b\u8a18\u3067\u306f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\n{0}
HashDbManager.hashDbFileExistsExceptionMsg=\u4e0b\u8a18\u306b\u306f\u65e2\u306b\u30d5\u30a1\u30a4\u30eb\u304c\u5b58\u5728\u3057\u307e\u3059\u3002\n{0}
HashDbManager.hashDbAlreadyAddedExceptionMsg=\u4e0b\u8a18\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\n{0}\n\u306f\u65e2\u306b\u4f5c\u6210\u307e\u305f\u306f\u30a4\u30f3\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u3059\u3002
HashDbManager.illegalHashDbFileNameExtensionMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u540d\u306f.{0}\u306e\u62e1\u5f35\u5b50\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbManager.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
HashDbManager.knownBad.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbManager.known.text=\u65e2\u77e5
HashDbManager.fileNameExtensionFilter.title=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
HashDbSearchAction.dlgMsg.title=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u3044\u305f\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
HashDbSearchAction.getName.text=\u30cf\u30c3\u30b7\u30e5\u691c\u7d22
HashDbSearchPanel.dlgMsg.title=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
AddContentToHashDbAction.singleSelectionName=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u8ffd\u52a0
AddContentToHashDbAction.multipleSelectionName=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u8ffd\u52a0
OptionsCategory_Name_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
OptionsCategory_Keywords_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbManager.ingestRunningExceptionMsg=\u51e6\u7406\u4e2d\uff1b\u5b8c\u4e86\u3059\u308b\u307e\u3067\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
ModalNoButtons.CURRENTDB_LABEL.text=\uff08\u73fe\u5728\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff09
HashDbCreateDatabaseDialog.defaultFileName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8
HashDbManager.saveErrorExceptionMsg=\u30cf\u30c3\u30b7\u30e5\u8a2d\u5b9a\u306e\u4fdd\u5b58\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
AddContentToHashDbAction.addFilesToHashSet.files=\u30d5\u30a1\u30a4\u30eb
AddContentToHashDbAction.addFilesToHashSet.file=\u30d5\u30a1\u30a4\u30eb
HashDbManager.errCreatingIndex.title=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
HashDbManager.errCreatingIndex.msg=\u4e0b\u8a18\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0}
HashLookupSettingsPanel.optionsLabel.text=\u30AA\u30D7\u30B7\u30E7\u30F3
HashLookupSettingsPanel.jButton3.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashLookupSettingsPanel.indexPathLabelLabel.text=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u30D1\u30B9\uFF1A
HashLookupSettingsPanel.createDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4F5C\u6210
HashLookupSettingsPanel.jLabel6.text=\u30BF\u30A4\u30D7\uFF1A
HashLookupSettingsPanel.jLabel4.text=\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\uFF1A
HashLookupSettingsPanel.jLabel2.text=\u540D\u524D\uFF1A
HashLookupSettingsPanel.indexPathLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.ingestWarningLabel.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u4E2D\u3067\u3059\u3002\u5B8C\u4E86\u3059\u308B\u307E\u3067\u4E00\u90E8\u306E\u8A2D\u5B9A\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
HashLookupSettingsPanel.deleteDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u524A\u9664
HashLookupSettingsPanel.importDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashLookupSettingsPanel.hashDatabasesLabel.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\uFF1A
HashLookupSettingsPanel.nameLabel.text=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\uFF1A
HashLookupSettingsPanel.informationLabel.text=\u60C5\u5831
HashLookupSettingsPanel.sendIngestMessagesCheckBox.text=\u30D2\u30C3\u30C8\u6BCE\u306B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u9001\u308B
HashLookupSettingsPanel.hashDbLocationLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.hashDbNameLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.typeLabel.text=\u30BF\u30A4\u30D7\uFF1A
HashLookupSettingsPanel.locationLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\uFF1A
HashLookupSettingsPanel.hashDbIndexStatusLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.hashDbTypeLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.indexButton.text=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9
HashLookupSettingsPanel.indexLabel.text=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u30B9\u30C6\u30FC\u30BF\u30B9\uFF1A
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u306A\u304F\u3066\u3082\u3001\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u8A08\u7B97
HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308B\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u9078\u629E\uFF1A
HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51E6\u7406\u306B\u5229\u7528\u3059\u308B\u65E2\u77E5\u306E\u60AA\u8CEA\u306A\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u9078\u629E\uFF1A
HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u306A\u304F\u3066\u3082\u3001\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u8A08\u7B97
HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30CF\u30C3\u30B7\u30E5
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B{0}\u3092\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30D5\u30A1\u30A4\u30EB\u306B\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u3042\u308A\u307E\u305B\u3093\u3002
HashLookupSettingsPanel.optionsLabel.text=\u30aa\u30d7\u30b7\u30e7\u30f3
HashLookupSettingsPanel.jButton3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashLookupSettingsPanel.indexPathLabelLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30d1\u30b9\uff1a
HashLookupSettingsPanel.createDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210
HashLookupSettingsPanel.jLabel6.text=\u30bf\u30a4\u30d7\uff1a
HashLookupSettingsPanel.jLabel4.text=\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\uff1a
HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a
HashLookupSettingsPanel.indexPathLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u3067\u3059\u3002\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashLookupSettingsPanel.deleteDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664
HashLookupSettingsPanel.importDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashLookupSettingsPanel.hashDatabasesLabel.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a
HashLookupSettingsPanel.nameLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\uff1a
HashLookupSettingsPanel.informationLabel.text=\u60c5\u5831
HashLookupSettingsPanel.sendIngestMessagesCheckBox.text=\u30d2\u30c3\u30c8\u6bce\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashLookupSettingsPanel.hashDbLocationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.hashDbNameLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.typeLabel.text=\u30bf\u30a4\u30d7\uff1a
HashLookupSettingsPanel.locationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashLookupSettingsPanel.hashDbIndexStatusLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.hashDbTypeLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.indexButton.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashLookupSettingsPanel.indexLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30b9\u30c6\u30fc\u30bf\u30b9\uff1a
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97
HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a
HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51e6\u7406\u306b\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a
HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97
HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30cf\u30c3\u30b7\u30e5
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u3042\u308a\u307e\u305b\u3093\u3002

View File

@ -127,6 +127,10 @@
<Component id="hashDbLocationLabel" alignment="0" max="32767" attributes="0"/>
<Component id="indexPathLabel" max="32767" attributes="0"/>
<Component id="hashDbIndexStatusLabel" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="addHashesToDatabaseButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
@ -204,7 +208,10 @@
<Component id="hashDbIndexStatusLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="indexButton" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="indexButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="addHashesToDatabaseButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="optionsLabel" min="-2" max="-2" attributes="0"/>
@ -452,6 +459,17 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="addHashesToDatabaseButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.addHashesToDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addHashesToDatabaseButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>

View File

@ -34,6 +34,7 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
@ -121,6 +122,7 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
hashDbIndexStatusLabel.setForeground(Color.black);
indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index"));
indexButton.setEnabled(false);
addHashesToDatabaseButton.setEnabled(false);
// Update ingest options.
sendIngestMessagesCheckBox.setSelected(false);
@ -157,6 +159,13 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
Logger.getLogger(HashLookupSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting index path of " + db.getHashSetName() + " hash database", ex); //NON-NLS
indexPathLabel.setText(ERROR_GETTING_PATH_TEXT);
}
try {
addHashesToDatabaseButton.setEnabled(!ingestIsRunning && db.isUpdateable());
} catch (TskCoreException ex) {
Logger.getLogger(HashLookupSettingsPanel.class.getName()).log(Level.SEVERE, "Error identifying if the database is updateable.", ex); //NON-NLS
addHashesToDatabaseButton.setEnabled(false);
}
// Update indexing components.
try {
@ -481,6 +490,7 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
createDatabaseButton = new javax.swing.JButton();
indexPathLabelLabel = new javax.swing.JLabel();
indexPathLabel = new javax.swing.JLabel();
addHashesToDatabaseButton = new javax.swing.JButton();
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.jLabel2.text")); // NOI18N
@ -590,6 +600,14 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
org.openide.awt.Mnemonics.setLocalizedText(indexPathLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.indexPathLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(addHashesToDatabaseButton, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.addHashesToDatabaseButton.text")); // NOI18N
addHashesToDatabaseButton.setEnabled(false);
addHashesToDatabaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addHashesToDatabaseButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
@ -628,7 +646,10 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
.addComponent(hashDbTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(hashDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(indexPathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(hashDbIndexStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addComponent(hashDbIndexStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(addHashesToDatabaseButton)
.addGap(0, 0, Short.MAX_VALUE))))
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(nameLabel)
.addGap(53, 53, 53)
@ -683,7 +704,9 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
.addComponent(indexLabel)
.addComponent(hashDbIndexStatusLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(indexButton)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(indexButton)
.addComponent(addHashesToDatabaseButton))
.addGap(18, 18, 18)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(optionsLabel)
@ -798,7 +821,15 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
((HashSetTable) hashSetTable).selectRowByName(hashDb.getHashSetName());
}
}//GEN-LAST:event_createDatabaseButtonActionPerformed
private void addHashesToDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addHashesToDatabaseButtonActionPerformed
HashDb hashDb = ((HashSetTable) hashSetTable).getSelection();
new AddHashValuesToDatabaseDialog(hashDb);
}//GEN-LAST:event_addHashesToDatabaseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addHashesToDatabaseButton;
private javax.swing.JButton createDatabaseButton;
private javax.swing.JButton deleteDatabaseButton;
private javax.swing.JLabel hashDatabasesLabel;

View File

@ -41,10 +41,10 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.openide.filesystems.FileUtil;
import org.sleuthkit.autopsy.casemodule.services.Services;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
@ -52,13 +52,13 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
class ReportHTML implements TableReportModule {
@ -1109,7 +1109,7 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
}
private String prepareThumbnail(AbstractFile file) {
File thumbFile = ImageUtils.getIconFile(file, ImageUtils.ICON_SIZE_MEDIUM);
File thumbFile = ImageUtils.getCachedThumbnailFile(file, ImageUtils.ICON_SIZE_MEDIUM);
if (thumbFile.exists() == false) {
return null;
}

View File

@ -94,15 +94,11 @@ class ReportKML implements GeneralReportModule {
progressPanel.setMaximumProgress(5);
progressPanel.increment();
// @@@ BC: I don't get why we do this in two passes.
// Why not just print the coordinates as we find them and make some utility methods to do the printing?
// Should pull out time values for all of these points and store in TimeSpan element
try {
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(reportPath2));
try (BufferedWriter out = new BufferedWriter(new FileWriter(reportPath2))) {
double lat = 0; // temp latitude
double lon = 0; //temp longitude
@ -110,7 +106,6 @@ class ReportKML implements GeneralReportModule {
String geoPath = ""; // will hold values of images to put in kml
String imageName = "";
File f;
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF)) {
lat = 0;
@ -131,7 +126,7 @@ class ReportKML implements GeneralReportModule {
if (lon != 0 && lat != 0) {
aFile = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
if(aFile != null){
if (aFile != null) {
extractedToPath = reportPath + aFile.getName();
geoPath = extractedToPath;
f = new File(extractedToPath);
@ -150,7 +145,7 @@ class ReportKML implements GeneralReportModule {
// lat lon path name
}
}
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT)) {
lat = 0;
lon = 0;
@ -168,7 +163,7 @@ class ReportKML implements GeneralReportModule {
out.write(lat + ";" + lon + "\n");
}
}
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE)) {
lat = 0;
lon = 0;
@ -197,24 +192,23 @@ class ReportKML implements GeneralReportModule {
location = attribute.getValueString();
}
}
// @@@ Should do something more fancy with these in KML and store them as a single point.
String display = name;
if (display.isEmpty())
display = location;
if (lon != 0 && lat != 0) {
out.write(NbBundle.getMessage(this.getClass(), "ReportKML.latLongStartPoint", lat, lon, display));
}
if (destlat != 0 && destlon != 0) {
out.write(NbBundle.getMessage(this.getClass(), "ReportKML.latLongEndPoint", destlat, destlon,
display));
display));
}
}
out.flush();
out.close();
progressPanel.increment();
/*
* Step 1: generate XML stub
@ -236,7 +230,6 @@ class ReportKML implements GeneralReportModule {
/*
* Step 2: add in Style elements
*/
// Style
Element style = new Element("Style", ns); //NON-NLS
style.setAttribute("id", "redIcon"); //NON-NLS
@ -266,72 +259,69 @@ class ReportKML implements GeneralReportModule {
*/
File file = new File(reportPath2);
BufferedReader reader;
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line = reader.readLine();
while (line != null) {
String[] lineParts = line.split(";");
if (lineParts.length > 1) {
String coordinates = lineParts[1].trim() + "," + lineParts[0].trim(); //lat,lon
// Placemark
Element placemark = new Element("Placemark", ns); //NON-NLS
document.addContent(placemark);
reader = new BufferedReader(new FileReader(file));
if (lineParts.length == 4) {
// name
Element pmName = new Element("name", ns); //NON-NLS
pmName.setText(lineParts[3].trim());
placemark.addContent(pmName);
String line = reader.readLine();
while (line != null) {
String[] lineParts = line.split(";");
if (lineParts.length > 1) {
String coordinates = lineParts[1].trim() + "," + lineParts[0].trim(); //lat,lon
// Placemark
Element placemark = new Element("Placemark", ns); //NON-NLS
document.addContent(placemark);
String savedPath = lineParts[2].trim();
if (savedPath.isEmpty() == false) {
// Path
Element pmPath = new Element("Path", ns); //NON-NLS
pmPath.setText(savedPath);
placemark.addContent(pmPath);
if (lineParts.length == 4) {
// name
Element pmName = new Element("name", ns); //NON-NLS
pmName.setText(lineParts[3].trim());
placemark.addContent(pmName);
String savedPath = lineParts[2].trim();
if (savedPath.isEmpty() == false) {
// Path
Element pmPath = new Element("Path", ns); //NON-NLS
pmPath.setText(savedPath);
placemark.addContent(pmPath);
// description
Element pmDescription = new Element("description", ns); //NON-NLS
String xml = "<![CDATA[ \n" + " <img src='file:///" + savedPath + "' width='400' /><br/&gt; \n"; //NON-NLS
StringEscapeUtils.unescapeXml(xml);
pmDescription.setText(xml);
placemark.addContent(pmDescription);
// description
Element pmDescription = new Element("description", ns); //NON-NLS
String xml = "<![CDATA[ \n" + " <img src='file:///" + savedPath + "' width='400' /><br/&gt; \n"; //NON-NLS
StringEscapeUtils.unescapeXml(xml);
pmDescription.setText(xml);
placemark.addContent(pmDescription);
}
}
// styleUrl
Element pmStyleUrl = new Element("styleUrl", ns); //NON-NLS
pmStyleUrl.setText("#redIcon"); //NON-NLS
placemark.addContent(pmStyleUrl);
// Point
Element pmPoint = new Element("Point", ns); //NON-NLS
placemark.addContent(pmPoint);
// coordinates
Element pmCoordinates = new Element("coordinates", ns); //NON-NLS
pmCoordinates.setText(coordinates);
pmPoint.addContent(pmCoordinates);
}
// styleUrl
Element pmStyleUrl = new Element("styleUrl", ns); //NON-NLS
pmStyleUrl.setText("#redIcon"); //NON-NLS
placemark.addContent(pmStyleUrl);
// Point
Element pmPoint = new Element("Point", ns); //NON-NLS
placemark.addContent(pmPoint);
// coordinates
Element pmCoordinates = new Element("coordinates", ns); //NON-NLS
pmCoordinates.setText(coordinates);
pmPoint.addContent(pmCoordinates);
// read the next line
line = reader.readLine();
}
// read the next line
line = reader.readLine();
}
progressPanel.increment();
/*
* Step 4: write the XML file
*/
try {
try (FileOutputStream writer = new FileOutputStream(reportPath)) {
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
FileOutputStream writer = new FileOutputStream(reportPath);
outputter.output(kmlDocument, writer);
writer.close();
Case.getCurrentCase().addReport(reportPath, NbBundle.getMessage(this.getClass(),
"ReportKML.genReport.srcModuleName.text"), "");
"ReportKML.genReport.srcModuleName.text"), "");
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not write the KML file.", ex); //NON-NLS
} catch (TskCoreException ex) {

View File

@ -39,10 +39,29 @@
<!-- timeline and image analyzer -->
<dependency conf="autopsy_core->*" org="org.controlsfx" name="controlsfx" rev="8.40.9" />
<!-- timeline and -->
<!-- timeline -->
<dependency conf="autopsy_core->*" org="joda-time" name="joda-time" rev="2.4" />
<dependency conf="autopsy_core->*" org="org.jfxtras" name="jfxtras-fxml" rev="8.0-r1" />
<dependency conf="autopsy_core->*" org="org.jfxtras" name="jfxtras-controls" rev="8.0-r1" />
<dependency conf="autopsy_core->*" org="org.jfxtras" name="jfxtras-common" rev="8.0-r1" />
<!-- image support for autopsy and image gallery -->
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-jpeg" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-bmp" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-tiff" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-pnm" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-psd" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-iff" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-pcx" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-pict" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-sgi" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-tga" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-icns" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-thumbsdb" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.common" name="common-lang" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.common" name="common-io" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.common" name="common-image" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-core" rev="3.1.1" />
<dependency conf="autopsy_core->*" org="com.twelvemonkeys.imageio" name="imageio-metadata" rev="3.1.1" />
</dependencies>
</ivy-module>

View File

@ -1,11 +1,10 @@
<ivysettings>
<settings defaultResolver="main"/>
<resolvers>
<chain name="main">
<ibiblio name="central" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="xerial" m2compatible="true"
root="http://www.xerial.org/maven/repository/snapshot" />
</chain>
</resolvers>
<settings defaultResolver="main"/>
<resolvers>
<chain name="main">
<ibiblio name="central" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="xerial" m2compatible="true" root="http://www.xerial.org/maven/repository/snapshot" />
</chain>
</resolvers>
</ivysettings>

View File

@ -3,6 +3,9 @@ file.reference.ant-1.8.2.jar=release/modules/ext/ant-1.8.2.jar
file.reference.ant-launcher-1.8.2.jar=release/modules/ext/ant-launcher-1.8.2.jar
file.reference.AppleJavaExtensions-1.4.jar=release/modules/ext/AppleJavaExtensions-1.4.jar
file.reference.avalon-framework-4.1.5.jar=release/modules/ext/avalon-framework-4.1.5.jar
file.reference.common-image-3.1.1.jar=release/modules/ext/common-image-3.1.1.jar
file.reference.common-io-3.1.1.jar=release/modules/ext/common-io-3.1.1.jar
file.reference.common-lang-3.1.1.jar=release/modules/ext/common-lang-3.1.1.jar
file.reference.commons-codec-1.5.jar=release/modules/ext/commons-codec-1.5.jar
file.reference.commons-io-2.4.jar=release/modules/ext/commons-io-2.4.jar
file.reference.commons-lang-2.6.jar=release/modules/ext/commons-lang-2.6.jar
@ -18,6 +21,20 @@ file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.
file.reference.gson-1.4.jar=release/modules/ext/gson-1.4.jar
file.reference.gstreamer-java-1.5.jar=release/modules/ext/gstreamer-java-1.5.jar
file.reference.guava-11.0.2.jar=release/modules/ext/guava-11.0.2.jar
file.reference.imageio-bmp-3.1.1.jar=release/modules/ext/imageio-bmp-3.1.1.jar
file.reference.imageio-core-3.1.1.jar=release/modules/ext/imageio-core-3.1.1.jar
file.reference.imageio-icns-3.1.1.jar=release/modules/ext/imageio-icns-3.1.1.jar
file.reference.imageio-iff-3.1.1.jar=release/modules/ext/imageio-iff-3.1.1.jar
file.reference.imageio-jpeg-3.1.1.jar=release/modules/ext/imageio-jpeg-3.1.1.jar
file.reference.imageio-metadata-3.1.1.jar=release/modules/ext/imageio-metadata-3.1.1.jar
file.reference.imageio-pcx-3.1.1.jar=release/modules/ext/imageio-pcx-3.1.1.jar
file.reference.imageio-pict-3.1.1.jar=release/modules/ext/imageio-pict-3.1.1.jar
file.reference.imageio-pnm-3.1.1.jar=release/modules/ext/imageio-pnm-3.1.1.jar
file.reference.imageio-psd-3.1.1.jar=release/modules/ext/imageio-psd-3.1.1.jar
file.reference.imageio-sgi-3.1.1.jar=release/modules/ext/imageio-sgi-3.1.1.jar
file.reference.imageio-tga-3.1.1.jar=release/modules/ext/imageio-tga-3.1.1.jar
file.reference.imageio-thumbsdb-3.1.1.jar=release/modules/ext/imageio-thumbsdb-3.1.1.jar
file.reference.imageio-tiff-3.1.1.jar=release/modules/ext/imageio-tiff-3.1.1.jar
file.reference.imgscalr-lib-4.2-javadoc.jar=release/modules/ext/imgscalr-lib-4.2-javadoc.jar
file.reference.imgscalr-lib-4.2-sources.jar=release/modules/ext/imgscalr-lib-4.2-sources.jar
file.reference.imgscalr-lib-4.2.jar=release/modules/ext/imgscalr-lib-4.2.jar

View File

@ -64,6 +64,41 @@
<package>com.sun.mail.smtp</package>
<package>com.sun.mail.util</package>
<package>com.sun.mail.util.logging</package>
<package>com.twelvemonkeys.image</package>
<package>com.twelvemonkeys.imageio</package>
<package>com.twelvemonkeys.imageio.color</package>
<package>com.twelvemonkeys.imageio.metadata</package>
<package>com.twelvemonkeys.imageio.metadata.exif</package>
<package>com.twelvemonkeys.imageio.metadata.iptc</package>
<package>com.twelvemonkeys.imageio.metadata.jpeg</package>
<package>com.twelvemonkeys.imageio.metadata.psd</package>
<package>com.twelvemonkeys.imageio.metadata.xmp</package>
<package>com.twelvemonkeys.imageio.plugins.bmp</package>
<package>com.twelvemonkeys.imageio.plugins.dcx</package>
<package>com.twelvemonkeys.imageio.plugins.icns</package>
<package>com.twelvemonkeys.imageio.plugins.iff</package>
<package>com.twelvemonkeys.imageio.plugins.jpeg</package>
<package>com.twelvemonkeys.imageio.plugins.pcx</package>
<package>com.twelvemonkeys.imageio.plugins.pict</package>
<package>com.twelvemonkeys.imageio.plugins.pnm</package>
<package>com.twelvemonkeys.imageio.plugins.psd</package>
<package>com.twelvemonkeys.imageio.plugins.sgi</package>
<package>com.twelvemonkeys.imageio.plugins.tga</package>
<package>com.twelvemonkeys.imageio.plugins.thumbsdb</package>
<package>com.twelvemonkeys.imageio.plugins.tiff</package>
<package>com.twelvemonkeys.imageio.spi</package>
<package>com.twelvemonkeys.imageio.stream</package>
<package>com.twelvemonkeys.imageio.util</package>
<package>com.twelvemonkeys.io</package>
<package>com.twelvemonkeys.io.enc</package>
<package>com.twelvemonkeys.io.ole2</package>
<package>com.twelvemonkeys.lang</package>
<package>com.twelvemonkeys.net</package>
<package>com.twelvemonkeys.util</package>
<package>com.twelvemonkeys.util.convert</package>
<package>com.twelvemonkeys.util.regex</package>
<package>com.twelvemonkeys.util.service</package>
<package>com.twelvemonkeys.xml</package>
<package>javassist</package>
<package>javassist.bytecode</package>
<package>javassist.bytecode.analysis</package>
@ -475,7 +510,6 @@
<package>org.apache.xmlbeans.xml.stream.events</package>
<package>org.apache.xmlbeans.xml.stream.utils</package>
<package>org.apache.xmlcommons</package>
<package>org.controlsfx</package>
<package>org.controlsfx.control</package>
<package>org.controlsfx.control.action</package>
<package>org.controlsfx.control.cell</package>
@ -615,6 +649,18 @@
<runtime-relative-path>ext/logkit-1.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/logkit-1.0.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-bmp-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-bmp-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-pcx-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-pcx-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-jpeg-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-jpeg-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imgscalr-lib-4.2-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imgscalr-lib-4.2-javadoc.jar</binary-origin>
@ -675,6 +721,18 @@
<runtime-relative-path>ext/mail-1.4.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/mail-1.4.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-tiff-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-tiff-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-pnm-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-pnm-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/common-lang-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/common-lang-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/slf4j-api-1.6.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/slf4j-api-1.6.1.jar</binary-origin>
@ -711,6 +769,10 @@
<runtime-relative-path>ext/poi-excelant-3.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-excelant-3.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/common-image-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/common-image-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/log4j-1.2.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/log4j-1.2.17.jar</binary-origin>
@ -743,6 +805,10 @@
<runtime-relative-path>ext/jfxtras-fxml-8.0-r1-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r1-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/common-io-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/common-io-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jfxtras-fxml-8.0-r1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r1.jar</binary-origin>
@ -791,6 +857,10 @@
<runtime-relative-path>ext/commons-codec-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-codec-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-icns-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-icns-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/javassist-3.12.1.GA.jar</runtime-relative-path>
<binary-origin>release/modules/ext/javassist-3.12.1.GA.jar</binary-origin>
@ -799,14 +869,26 @@
<runtime-relative-path>ext/commons-logging-1.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-1.1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-psd-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-psd-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-io-2.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-io-2.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-sgi-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-sgi-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-thumbsdb-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-thumbsdb-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang3-3.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang3-3.0.jar</binary-origin>
@ -815,6 +897,18 @@
<runtime-relative-path>ext/jfxtras-common-8.0-r1-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfxtras-common-8.0-r1-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-iff-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-iff-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-tga-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-tga-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-core-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-core-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/javaee-api-5.0-2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/javaee-api-5.0-2.jar</binary-origin>
@ -823,10 +917,18 @@
<runtime-relative-path>ext/gstreamer-java-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/gstreamer-java-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-metadata-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-metadata-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jfxtras-controls-8.0-r1-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfxtras-controls-8.0-r1-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-pict-3.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-pict-3.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/dom4j-1.6.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/dom4j-1.6.1.jar</binary-origin>

View File

@ -39,7 +39,10 @@ import org.sleuthkit.datamodel.TskCoreException;
/**
* Enum style singleton to provide utilities related to questions about a files
* type
* type, and wheather it should be supported in Image Gallery.
*
* TODO: refactor this to remove code that duplicates
* org.sleuthkit.autopsy.coreutils.ImageUtils
*/
public enum FileTypeUtils {
@ -87,6 +90,7 @@ public enum FileTypeUtils {
* to be supported
*/
static {
ImageIO.scanForPlugins();
//add all extension ImageIO claims to support
imageExtensions.addAll(Stream.of(ImageIO.getReaderFileSuffixes())
.map(String::toLowerCase)
@ -105,6 +109,8 @@ public enum FileTypeUtils {
, "ai" //illustrator
, "svg" //scalable vector graphics
, "sn", "ras" //sun raster
, "ico" //windows icons
, "tga" //targa
));
//add list of known video extensions
@ -118,10 +124,14 @@ public enum FileTypeUtils {
videoMimeTypes.addAll(Arrays.asList("application/x-shockwave-flash"));
supportedMimeTypes.addAll(videoMimeTypes);
supportedMimeTypes.addAll(Arrays.asList("application/x-123"));
//add list of mimetypes ImageIO claims to support
supportedMimeTypes.addAll(Stream.of(ImageIO.getReaderMIMETypes())
.map(String::toLowerCase)
.collect(Collectors.toList()));
supportedMimeTypes.removeIf("application/octet-stream"::equals); //this is rearely usefull
}
/**
@ -161,9 +171,12 @@ public enum FileTypeUtils {
*/
public static boolean isDrawable(AbstractFile file) {
return hasDrawableMimeType(file).orElseGet(() -> {
return FileTypeUtils.supportedExtensions.contains(file.getNameExtension())
|| ImageUtils.isJpegFileHeader(file)
|| ImageUtils.isPngFileHeader(file);
final boolean contains = FileTypeUtils.supportedExtensions.contains(file.getNameExtension());
final boolean jpegFileHeader = ImageUtils.isJpegFileHeader(file);
final boolean pngFileHeader = ImageUtils.isPngFileHeader(file);
return contains
|| jpegFileHeader
|| pngFileHeader;
});
}

View File

@ -453,15 +453,19 @@ public final class ImageGalleryController {
* getOldValue has fileID getNewValue has
* {@link Abstractfile}
*/
AbstractFile file = (AbstractFile) evt.getNewValue();
if (isListeningEnabled()) {
if (ImageGalleryModule.isDrawableAndNotKnown(file)) {
//this file should be included and we don't already know about it from hash sets (NSRL)
queueDBWorkerTask(new UpdateFileTask(file, db));
} else if (FileTypeUtils.getAllSupportedExtensions().contains(file.getNameExtension())) {
if (file.isFile()) {
if (ImageGalleryModule.isDrawableAndNotKnown(file)) {
//this file should be included and we don't already know about it from hash sets (NSRL)
queueDBWorkerTask(new UpdateFileTask(file, db));
} else if (FileTypeUtils.getAllSupportedExtensions().contains(file.getNameExtension())) {
//doing this check results in fewer tasks queued up, and faster completion of db update
//this file would have gotten scooped up in initial grab, but actually we don't need it
queueDBWorkerTask(new RemoveFileTask(file, db));
//this file would have gotten scooped up in initial grab, but actually we don't need it
queueDBWorkerTask(new RemoveFileTask(file, db));
}
}
} else { //TODO: keep track of what we missed for later
setStale(true);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -32,14 +32,17 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
import org.sleuthkit.autopsy.imagegallery.gui.Toolbar;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.TskCoreException;
@ -53,8 +56,6 @@ public enum ThumbnailCache {
instance;
/** save thumbnails to disk as this format */
private static final String FORMAT = "png";
private static final int MAX_THUMBNAIL_SIZE = 300;
private static final Logger LOGGER = Logger.getLogger(ThumbnailCache.class.getName());
@ -71,6 +72,9 @@ public enum ThumbnailCache {
return instance;
}
/** currently desired icon size. is bound in {@link Toolbar} */
public final SimpleIntegerProperty iconSize = new SimpleIntegerProperty(200);
/**
* Clear out the cache between cases
*/
@ -122,39 +126,43 @@ public enum ThumbnailCache {
return Optional.of(new Image(new BufferedInputStream(new ReadContentInputStream(file.getAbstractFile())), MAX_THUMBNAIL_SIZE, MAX_THUMBNAIL_SIZE, true, true));
}
Image thumbnail;
BufferedImage thumbnail = getCacheFile(file).map(new Function<File, BufferedImage>() {
@Override
public BufferedImage apply(File cachFile) {
if (cachFile.exists()) {
// If a thumbnail file is already saved locally, load it
try {
BufferedImage read = ImageIO.read(cachFile);
if (read.getWidth() < MAX_THUMBNAIL_SIZE) {
return read;
try {
thumbnail = getCacheFile(file.getId()).map(new Function<File, Image>() {
@Override
public Image apply(File cachFile) {
if (cachFile.exists()) {
// If a thumbnail file is already saved locally, load it
try {
BufferedImage read = ImageIO.read(cachFile);
if (read.getWidth() < MAX_THUMBNAIL_SIZE) {
return SwingFXUtils.toFXImage(read, null);
}
} catch (MalformedURLException ex) {
LOGGER.log(Level.WARNING, "Unable to parse cache file path..");
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
} catch (MalformedURLException ex) {
LOGGER.log(Level.WARNING, "Unable to parse cache file path..");
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return null;
}
}).orElse(null);
return null;
}
}).orElseGet(() -> {
return (BufferedImage) ImageUtils.getThumbnail(file.getAbstractFile(), MAX_THUMBNAIL_SIZE);
});
} catch (IllegalStateException e) {
LOGGER.log(Level.WARNING, "can't load icon when no case is open");
return Optional.empty();
// } catch (IllegalStateException e) {
// LOGGER.log(Level.WARNING, "can't load icon when no case is open");
// return Optional.empty();
// }
WritableImage jfxthumbnail;
if (thumbnail == ImageUtils.getDefaultThumbnail()) {
// if we go the default icon, ignore it
jfxthumbnail = null;
} else {
jfxthumbnail = SwingFXUtils.toFXImage(thumbnail, null);
}
if (thumbnail == null) { //if we failed to load the icon, try to generate it
thumbnail = generateAndSaveThumbnail(file);
}
return Optional.ofNullable(thumbnail); //return icon, or null if generation failed
return Optional.ofNullable(jfxthumbnail); //return icon, or null if generation failed
}
/**
@ -163,12 +171,12 @@ public enum ThumbnailCache {
* @param id the obj id of the file to get a cache file for
*
* @return a Optional containing a File to store the cahced icon in or an
* empty optional if there was a
* problem.
* empty optional if there was a problem.
*/
private static Optional<File> getCacheFile(long id) {
private static Optional<File> getCacheFile(DrawableFile<?> file) {
try {
return Optional.of(ImageUtils.getFile(id));
return Optional.of(ImageUtils.getCachedThumbnailFile(file.getAbstractFile(), MAX_THUMBNAIL_SIZE));
} catch (IllegalStateException e) {
LOGGER.log(Level.WARNING, "Failed to create cache file.{0}", e.getLocalizedMessage());
return Optional.empty();
@ -188,4 +196,5 @@ public enum ThumbnailCache {
final BufferedImage thumbnail = (BufferedImage) ImageUtils.getIcon(file.getAbstractFile(), MAX_THUMBNAIL_SIZE);
return (thumbnail == ImageUtils.getDefaultIcon()) ? null : SwingFXUtils.toFXImage(thumbnail, null);
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -34,12 +34,16 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
/**
* ImageGallery data model object that represents an image file. It is a
* wrapper(/decorator?/adapter?) around {@link AbstractFile} and provides
* methods to get an icon sized and a full sized {@link Image}.
*
*
* methods to get an thumbnail sized and a full sized {@link Image}.
*/
public class ImageFile<T extends AbstractFile> extends DrawableFile<T> {
private static final Logger LOGGER = Logger.getLogger(ImageFile.class.getName());
static {
ImageIO.scanForPlugins();
}
ImageFile(T f, Boolean analyzed) {
super(f, analyzed);
@ -53,20 +57,12 @@ public class ImageFile<T extends AbstractFile> extends DrawableFile<T> {
@Override
public Image getFullSizeImage() {
Image image = (imageRef != null) ? imageRef.get() : null;
if (image == null) {
try (BufferedInputStream readContentInputStream = new BufferedInputStream(new ReadContentInputStream(this.getAbstractFile()))) {
image = new Image(readContentInputStream);
} catch (IOException ex) {
Logger.getLogger(ImageFile.class.getName()).log(Level.WARNING, "unable to read file with JavaFX" + getName());
}
}
if (image == null || image.errorProperty().get()) {
if (image == null || image.isError()) {
try (BufferedInputStream readContentInputStream = new BufferedInputStream(new ReadContentInputStream(this.getAbstractFile()))) {
BufferedImage read = ImageIO.read(readContentInputStream);
image = SwingFXUtils.toFXImage(read, null);
} catch (IOException | NullPointerException ex) {
Logger.getLogger(ImageFile.class.getName()).log(Level.WARNING, "unable to read file with Swing" + getName());
LOGGER.log(Level.WARNING, "unable to read file " + getName());
return null;
}
}
@ -74,6 +70,11 @@ public class ImageFile<T extends AbstractFile> extends DrawableFile<T> {
return image;
}
@Override
public boolean isDisplayable() {
Image thumbnail = getThumbnail();
return Objects.nonNull(thumbnail) && thumbnail.errorProperty().get() == false;
}
@Override
Double getWidth() {

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.imagegallery.datamodel;
import com.google.common.io.Files;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@ -60,8 +61,8 @@ public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
Image image = (imageRef != null) ? imageRef.get() : null;
if (image == null) {
final BufferedImage bufferedImage = (BufferedImage) ImageUtils.getIcon(getAbstractFile(), 1024);
imageRef = new SoftReference<>((bufferedImage == ImageUtils.getDefaultIcon()) ? null : SwingFXUtils.toFXImage(bufferedImage, null));
final BufferedImage bufferedImage = (BufferedImage) ImageUtils.getThumbnail(getAbstractFile(), 1024);
imageRef = new SoftReference<>((bufferedImage == ImageUtils.getDefaultThumbnail()) ? null : SwingFXUtils.toFXImage(bufferedImage, null));
}
return image;
@ -79,10 +80,13 @@ public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
final File cacheFile = VideoUtils.getTempVideoFile(this.getAbstractFile());
if (cacheFile.exists() == false || cacheFile.length() < getAbstractFile().getSize()) {
Files.createParentDirs(cacheFile);
ProgressHandle progressHandle = ProgressHandleFactory.createHandle("writing temporary file to disk");
progressHandle.start(100);
ContentUtils.writeToFile(this.getAbstractFile(), cacheFile, progressHandle, null, true);
progressHandle.finish();
}
media = new Media(Paths.get(cacheFile.getAbsolutePath()).toUri().toString());

View File

@ -315,10 +315,10 @@ public abstract class DrawableTileBase extends DrawableUIBase {
Platform.runLater(() -> {
fileTypeImageView.setManaged(isVideo);
hashHitImageView.setManaged(hasHashSetHits);
undisplayableImageView.setManaged(isUndisplayable);
fileTypeImageView.setVisible(isVideo);
hashHitImageView.setManaged(hasHashSetHits);
hashHitImageView.setVisible(hasHashSetHits);
undisplayableImageView.setManaged(isUndisplayable);
undisplayableImageView.setVisible(isUndisplayable);
nameLabel.setText(text);
nameLabel.setTooltip(new Tooltip(text));