mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Revert "Revert "1501 ja image gallery - redo 1""
This commit is contained in:
parent
dc541c5eae
commit
2a25dab4c6
@ -39,7 +39,7 @@ public class FXMLConstructor {
|
|||||||
private static Logger logger = Logger.getLogger(FXMLConstructor.class.getName());
|
private static Logger logger = Logger.getLogger(FXMLConstructor.class.getName());
|
||||||
|
|
||||||
static public void construct(Object n, String fxmlFileName) {
|
static public void construct(Object n, String fxmlFileName) {
|
||||||
final String name = "nbres:/" + StringUtils.replace(n.getClass().getPackage().getName(), ".", "/") + "/" + fxmlFileName;
|
final String name = "nbres:/" + StringUtils.replace(n.getClass().getPackage().getName(), ".", "/") + "/" + fxmlFileName; //NON-NLS
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(new URL(name));
|
FXMLLoader fxmlLoader = new FXMLLoader(new URL(name));
|
||||||
@ -53,12 +53,12 @@ public class FXMLConstructor {
|
|||||||
fxmlLoader.setClassLoader(FXMLLoader.getDefaultClassLoader());
|
fxmlLoader.setClassLoader(FXMLLoader.getDefaultClassLoader());
|
||||||
fxmlLoader.load();
|
fxmlLoader.load();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
String msg = String.format("Failed to load fxml file %s", fxmlFileName);
|
String msg = String.format("Failed to load fxml file %s", fxmlFileName); //NON-NLS
|
||||||
logger.log(Level.SEVERE, msg, ex);
|
logger.log(Level.SEVERE, msg, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
String msg = String.format("Malformed URL %s", name);
|
String msg = String.format("Malformed URL %s", name); //NON-NLS
|
||||||
logger.log(Level.SEVERE, msg, ex);
|
logger.log(Level.SEVERE, msg, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ public class FileIDSelectionModel {
|
|||||||
try {
|
try {
|
||||||
fileNodes.add(new FileNode(controller.getSleuthKitCase().getAbstractFileById(id)));
|
fileNodes.add(new FileNode(controller.getSleuthKitCase().getAbstractFileById(id)));
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get abstract file by its ID", ex);
|
LOGGER.log(Level.SEVERE, "Failed to get abstract file by its ID", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileNode[] fileNodeArray = fileNodes.stream().toArray(FileNode[]::new);
|
FileNode[] fileNodeArray = fileNodes.stream().toArray(FileNode[]::new);
|
||||||
@ -84,7 +84,7 @@ public class FileIDSelectionModel {
|
|||||||
try {
|
try {
|
||||||
etc.getExplorerManager().setSelectedNodes(fileNodeArray);
|
etc.getExplorerManager().setSelectedNodes(fileNodeArray);
|
||||||
} catch (PropertyVetoException ex) {
|
} catch (PropertyVetoException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Explorer manager selection was vetoed.", ex);
|
LOGGER.log(Level.SEVERE, "Explorer manager selection was vetoed.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -93,31 +93,31 @@ public enum FileTypeUtils {
|
|||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
//add list of known image extensions
|
//add list of known image extensions
|
||||||
imageExtensions.addAll(Arrays.asList(
|
imageExtensions.addAll(Arrays.asList(
|
||||||
"bmp" //Bitmap
|
"bmp" //Bitmap NON-NLS
|
||||||
, "gif" //gif
|
, "gif" //gif NON-NLS
|
||||||
, "jpg", "jpeg", "jpe", "jp2", "jpx" //jpeg variants
|
, "jpg", "jpeg", "jpe", "jp2", "jpx" //jpeg variants NON-NLS
|
||||||
, "pbm", "pgm", "ppm" // Portable image format variants
|
, "pbm", "pgm", "ppm" // Portable image format variants NON-NLS
|
||||||
, "png" //portable network graphic
|
, "png" //portable network graphic NON-NLS
|
||||||
, "tga" //targa
|
, "tga" //targa NON-NLS
|
||||||
, "psd" //photoshop
|
, "psd" //photoshop NON-NLS
|
||||||
, "tif", "tiff" //tiff variants
|
, "tif", "tiff" //tiff variants NON-NLS
|
||||||
, "yuv", "ico" //icons
|
, "yuv", "ico" //icons NON-NLS
|
||||||
, "ai" //illustrator
|
, "ai" //illustrator NON-NLS
|
||||||
, "svg" //scalable vector graphics
|
, "svg" //scalable vector graphics NON-NLS
|
||||||
, "sn", "ras" //sun raster
|
, "sn", "ras" //sun raster NON-NLS
|
||||||
, "ico" //windows icons
|
, "ico" //windows icons NON-NLS
|
||||||
, "tga" //targa
|
, "tga" //targa NON-NLS
|
||||||
));
|
));
|
||||||
|
|
||||||
//add list of known video extensions
|
//add list of known video extensions
|
||||||
videoExtensions.addAll(Arrays.asList("fxm", "aaf", "3gp", "asf", "avi",
|
videoExtensions.addAll(Arrays.asList("fxm", "aaf", "3gp", "asf", "avi", //NON-NLS
|
||||||
"m1v", "m2v", "m4v", "mp4", "mov", "mpeg", "mpg", "mpe", "mp4",
|
"m1v", "m2v", "m4v", "mp4", "mov", "mpeg", "mpg", "mpe", "mp4", //NON-NLS
|
||||||
"rm", "wmv", "mpv", "flv", "swf"));
|
"rm", "wmv", "mpv", "flv", "swf")); //NON-NLS
|
||||||
|
|
||||||
supportedExtensions = Sets.union(imageExtensions, videoExtensions);
|
supportedExtensions = Sets.union(imageExtensions, videoExtensions);
|
||||||
|
|
||||||
//add list of mimetypes to count as videos even though they aren't prefixed by video/
|
//add list of mimetypes to count as videos even though they aren't prefixed by video/
|
||||||
videoMimeTypes.addAll(Arrays.asList("application/x-shockwave-flash"));
|
videoMimeTypes.addAll(Arrays.asList("application/x-shockwave-flash")); //NON-NLS
|
||||||
|
|
||||||
supportedMimeTypes.addAll(videoMimeTypes);
|
supportedMimeTypes.addAll(videoMimeTypes);
|
||||||
|
|
||||||
@ -128,14 +128,14 @@ public enum FileTypeUtils {
|
|||||||
* fixed, we should remove application/x-123 from the list of supported
|
* fixed, we should remove application/x-123 from the list of supported
|
||||||
* mime types.
|
* mime types.
|
||||||
*/
|
*/
|
||||||
supportedMimeTypes.addAll(Arrays.asList("application/x-123"));
|
supportedMimeTypes.addAll(Arrays.asList("application/x-123")); //NON-NLS
|
||||||
|
|
||||||
//add list of mimetypes ImageIO claims to support
|
//add list of mimetypes ImageIO claims to support
|
||||||
supportedMimeTypes.addAll(Stream.of(ImageIO.getReaderMIMETypes())
|
supportedMimeTypes.addAll(Stream.of(ImageIO.getReaderMIMETypes())
|
||||||
.map(String::toLowerCase)
|
.map(String::toLowerCase)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
supportedMimeTypes.removeIf("application/octet-stream"::equals); //this is rarely usefull
|
supportedMimeTypes.removeIf("application/octet-stream"::equals); //this is rarely usefull NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<String> getAllSupportedMimeTypes() {
|
public static Set<String> getAllSupportedMimeTypes() {
|
||||||
@ -151,7 +151,7 @@ public enum FileTypeUtils {
|
|||||||
try {
|
try {
|
||||||
FILE_TYPE_DETECTOR = new FileTypeDetector();
|
FILE_TYPE_DETECTOR = new FileTypeDetector();
|
||||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to initialize File Type Detector, will fall back on extensions in some situations.", ex);
|
LOGGER.log(Level.SEVERE, "Failed to initialize File Type Detector, will fall back on extensions in some situations.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FILE_TYPE_DETECTOR;
|
return FILE_TYPE_DETECTOR;
|
||||||
@ -196,8 +196,8 @@ public enum FileTypeUtils {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
} else {
|
} else {
|
||||||
mimeType = mimeType.toLowerCase();
|
mimeType = mimeType.toLowerCase();
|
||||||
return Optional.of(mimeType.startsWith("image/")
|
return Optional.of(mimeType.startsWith("image/") //NON-NLS
|
||||||
|| mimeType.startsWith("video/")
|
|| mimeType.startsWith("video/") //NON-NLS
|
||||||
|| supportedMimeTypes.contains(mimeType));
|
|| supportedMimeTypes.contains(mimeType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,11 +221,11 @@ public enum FileTypeUtils {
|
|||||||
String mimeType = fileTypeDetector.getFileType(file);
|
String mimeType = fileTypeDetector.getFileType(file);
|
||||||
if (nonNull(mimeType)) {
|
if (nonNull(mimeType)) {
|
||||||
mimeType = mimeType.toLowerCase();
|
mimeType = mimeType.toLowerCase();
|
||||||
return mimeType.startsWith("video/") || videoMimeTypes.contains(mimeType);
|
return mimeType.startsWith("video/") || videoMimeTypes.contains(mimeType); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex);
|
LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return FileTypeUtils.videoExtensions.contains(file.getNameExtension());
|
return FileTypeUtils.videoExtensions.contains(file.getNameExtension());
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||||
import org.openide.util.Cancellable;
|
import org.openide.util.Cancellable;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||||
@ -289,38 +290,44 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* aren't, add a blocking progress spinner with appropriate message.
|
* aren't, add a blocking progress spinner with appropriate message.
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
@NbBundle.Messages({"ImageGalleryController.noGroupsDlg.msg1=No groups are fully analyzed; but listening to ingest is disabled. " +
|
||||||
|
" No groups will be available until ingest is finished and listening is re-enabled.",
|
||||||
|
"ImageGalleryController.noGroupsDlg.msg2=No groups are fully analyzed yet, but ingest is still ongoing. Please Wait.",
|
||||||
|
"ImageGalleryController.noGroupsDlg.msg3=No groups are fully analyzed yet, but image / video data is still being populated. Please Wait.",
|
||||||
|
"ImageGalleryController.noGroupsDlg.msg4=There are no images/videos available from the added datasources; but listening to ingest is disabled. " +
|
||||||
|
" No groups will be available until ingest is finished and listening is re-enabled.",
|
||||||
|
"ImageGalleryController.noGroupsDlg.msg5=There are no images/videos in the added datasources.",
|
||||||
|
"ImageGalleryController.noGroupsDlg.msg6=There are no fully analyzed groups to display:" +
|
||||||
|
" the current Group By setting resulted in no groups, " +
|
||||||
|
"or no groups are fully analyzed but ingest is not running."})
|
||||||
public void checkForGroups() {
|
public void checkForGroups() {
|
||||||
if (groupManager.getAnalyzedGroups().isEmpty()) {
|
if (groupManager.getAnalyzedGroups().isEmpty()) {
|
||||||
if (IngestManager.getInstance().isIngestRunning()) {
|
if (IngestManager.getInstance().isIngestRunning()) {
|
||||||
if (listeningEnabled.get() == false) {
|
if (listeningEnabled.get() == false) {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("No groups are fully analyzed; but listening to ingest is disabled. "
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg1()));
|
||||||
+ " No groups will be available until ingest is finished and listening is re-enabled."));
|
|
||||||
} else {
|
} else {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("No groups are fully analyzed yet, but ingest is still ongoing. Please Wait.",
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg2(),
|
||||||
new ProgressIndicator()));
|
new ProgressIndicator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (getFileUpdateQueueSizeProperty().get() > 0) {
|
} else if (getFileUpdateQueueSizeProperty().get() > 0) {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("No groups are fully analyzed yet, but image / video data is still being populated. Please Wait.",
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg3(),
|
||||||
new ProgressIndicator()));
|
new ProgressIndicator()));
|
||||||
} else if (db != null && db.countAllFiles() <= 0) { // there are no files in db
|
} else if (db != null && db.countAllFiles() <= 0) { // there are no files in db
|
||||||
if (listeningEnabled.get() == false) {
|
if (listeningEnabled.get() == false) {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("There are no images/videos available from the added datasources; but listening to ingest is disabled. "
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg4()));
|
||||||
+ " No groups will be available until ingest is finished and listening is re-enabled."));
|
|
||||||
} else {
|
} else {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("There are no images/videos in the added datasources."));
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg5()));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!groupManager.isRegrouping()) {
|
} else if (!groupManager.isRegrouping()) {
|
||||||
replaceNotification(centralStackPane,
|
replaceNotification(centralStackPane,
|
||||||
new NoGroupsDialog("There are no fully analyzed groups to display:"
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg6()));
|
||||||
+ " the current Group By setting resulted in no groups, "
|
|
||||||
+ "or no groups are fully analyzed but ingest is not running."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -399,7 +406,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* reset the state of the controller (eg if the case is closed)
|
* reset the state of the controller (eg if the case is closed)
|
||||||
*/
|
*/
|
||||||
public synchronized void reset() {
|
public synchronized void reset() {
|
||||||
LOGGER.info("resetting ImageGalleryControler to initial state.");
|
LOGGER.info("resetting ImageGalleryControler to initial state."); //NON-NLS
|
||||||
selectionModel.clearSelection();
|
selectionModel.clearSelection();
|
||||||
setListeningEnabled(false);
|
setListeningEnabled(false);
|
||||||
ThumbnailCache.getDefault().clearCache();
|
ThumbnailCache.getDefault().clearCache();
|
||||||
@ -436,7 +443,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
@Nullable
|
@Nullable
|
||||||
synchronized public DrawableFile<?> getFileFromId(Long fileID) throws TskCoreException {
|
synchronized public DrawableFile<?> getFileFromId(Long fileID) throws TskCoreException {
|
||||||
if (Objects.isNull(db)) {
|
if (Objects.isNull(db)) {
|
||||||
LOGGER.log(Level.WARNING, "Could not get file from id, no DB set. The case is probably closed.");
|
LOGGER.log(Level.WARNING, "Could not get file from id, no DB set. The case is probably closed."); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return db.getFileFromID(fileID);
|
return db.getFileFromID(fileID);
|
||||||
@ -462,7 +469,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
*/
|
*/
|
||||||
void onStart() {
|
void onStart() {
|
||||||
Platform.setImplicitExit(false);
|
Platform.setImplicitExit(false);
|
||||||
LOGGER.info("setting up ImageGallery listeners");
|
LOGGER.info("setting up ImageGallery listeners"); //NON-NLS
|
||||||
//TODO can we do anything usefull in an InjestJobEventListener?
|
//TODO can we do anything usefull in an InjestJobEventListener?
|
||||||
//IngestManager.getInstance().addIngestJobEventListener((PropertyChangeEvent evt) -> {});
|
//IngestManager.getInstance().addIngestJobEventListener((PropertyChangeEvent evt) -> {});
|
||||||
IngestManager.getInstance().addIngestModuleEventListener(new IngestModuleEventListener());
|
IngestManager.getInstance().addIngestModuleEventListener(new IngestModuleEventListener());
|
||||||
@ -546,7 +553,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to run DB worker thread", ex);
|
LOGGER.log(Level.SEVERE, "Failed to run DB worker thread", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,6 +566,8 @@ public final class ImageGalleryController implements Executor {
|
|||||||
/**
|
/**
|
||||||
* Abstract base class for task to be done on {@link DBWorkerThread}
|
* Abstract base class for task to be done on {@link DBWorkerThread}
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"ImageGalleryController.InnerTask.progress.name=progress",
|
||||||
|
"ImageGalleryController.InnerTask.progress.name=status"})
|
||||||
static public abstract class InnerTask implements Runnable, Cancellable {
|
static public abstract class InnerTask implements Runnable, Cancellable {
|
||||||
|
|
||||||
public double getProgress() {
|
public double getProgress() {
|
||||||
@ -577,8 +586,8 @@ public final class ImageGalleryController implements Executor {
|
|||||||
this.message.set(Status);
|
this.message.set(Status);
|
||||||
}
|
}
|
||||||
SimpleObjectProperty<Worker.State> state = new SimpleObjectProperty<>(Worker.State.READY);
|
SimpleObjectProperty<Worker.State> state = new SimpleObjectProperty<>(Worker.State.READY);
|
||||||
SimpleDoubleProperty progress = new SimpleDoubleProperty(this, "pregress");
|
SimpleDoubleProperty progress = new SimpleDoubleProperty(this, Bundle.ImageGalleryController_InnerTask_progress_name());
|
||||||
SimpleStringProperty message = new SimpleStringProperty(this, "status");
|
SimpleStringProperty message = new SimpleStringProperty(this, Bundle.ImageGalleryController_InnerTask_progress_name());
|
||||||
|
|
||||||
public SimpleDoubleProperty progressProperty() {
|
public SimpleDoubleProperty progressProperty() {
|
||||||
return progress;
|
return progress;
|
||||||
@ -659,7 +668,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
// This is one of the places where we get many errors if the case is closed during processing.
|
// This is one of the places where we get many errors if the case is closed during processing.
|
||||||
// We don't want to print out a ton of exceptions if this is the case.
|
// We don't want to print out a ton of exceptions if this is the case.
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
Logger.getLogger(UpdateFileTask.class.getName()).log(Level.SEVERE, "Error in UpdateFile task");
|
Logger.getLogger(UpdateFileTask.class.getName()).log(Level.SEVERE, "Error in UpdateFile task"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -685,7 +694,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
// This is one of the places where we get many errors if the case is closed during processing.
|
// This is one of the places where we get many errors if the case is closed during processing.
|
||||||
// We don't want to print out a ton of exceptions if this is the case.
|
// We don't want to print out a ton of exceptions if this is the case.
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
Logger.getLogger(RemoveFileTask.class.getName()).log(Level.SEVERE, "Case was closed out from underneath RemoveFile task");
|
Logger.getLogger(RemoveFileTask.class.getName()).log(Level.SEVERE, "Case was closed out from underneath RemoveFile task"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,6 +708,11 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* adds them to the Drawable DB. Uses the presence of a mimetype as an
|
* adds them to the Drawable DB. Uses the presence of a mimetype as an
|
||||||
* approximation to 'analyzed'.
|
* approximation to 'analyzed'.
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"CopyAnalyzedFiles.populatingDb.status=populating analyzed image/video database",
|
||||||
|
"CopyAnalyzedFiles.committingDb.status=commiting image/video database",
|
||||||
|
"CopyAnalyzedFiles.stopCopy.status=Stopping copy to drawable db task.",
|
||||||
|
"CopyAnalyzedFiles.errPopulating.errMsg=There was an error populating Image Gallery database.",
|
||||||
|
""})
|
||||||
static private class CopyAnalyzedFiles extends InnerTask {
|
static private class CopyAnalyzedFiles extends InnerTask {
|
||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
@ -712,28 +726,28 @@ public final class ImageGalleryController implements Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static private final String FILE_EXTENSION_CLAUSE =
|
static private final String FILE_EXTENSION_CLAUSE =
|
||||||
"(name LIKE '%."
|
"(name LIKE '%." //NON-NLS
|
||||||
+ StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' OR name LIKE '%.")
|
+ StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' OR name LIKE '%.") //NON-NLS
|
||||||
+ "')";
|
+ "')";
|
||||||
|
|
||||||
static private final String MIMETYPE_CLAUSE =
|
static private final String MIMETYPE_CLAUSE =
|
||||||
"(mime_type LIKE '"
|
"(mime_type LIKE '" //NON-NLS
|
||||||
+ StringUtils.join(FileTypeUtils.getAllSupportedMimeTypes(), "' OR mime_type LIKE '")
|
+ StringUtils.join(FileTypeUtils.getAllSupportedMimeTypes(), "' OR mime_type LIKE '") //NON-NLS
|
||||||
+ "') ";
|
+ "') ";
|
||||||
|
|
||||||
static private final String DRAWABLE_QUERY =
|
static private final String DRAWABLE_QUERY =
|
||||||
//grab files with supported extension
|
//grab files with supported extension
|
||||||
FILE_EXTENSION_CLAUSE
|
FILE_EXTENSION_CLAUSE
|
||||||
//grab files with supported mime-types
|
//grab files with supported mime-types
|
||||||
+ " OR " + MIMETYPE_CLAUSE
|
+ " OR " + MIMETYPE_CLAUSE //NON-NLS
|
||||||
//grab files with image or video mime-types even if we don't officially support them
|
//grab files with image or video mime-types even if we don't officially support them
|
||||||
+ " OR mime_type LIKE 'video/%' OR mime_type LIKE 'image/%'";
|
+ " OR mime_type LIKE 'video/%' OR mime_type LIKE 'image/%'"; //NON-NLS
|
||||||
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("populating analyzed image/video database");
|
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle(Bundle.CopyAnalyzedFiles_populatingDb_status());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
updateMessage("populating analyzed image/video database");
|
updateMessage(Bundle.CopyAnalyzedFiles_populatingDb_status());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//grab all files with supported extension or detected mime types
|
//grab all files with supported extension or detected mime types
|
||||||
@ -747,7 +761,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
int units = 0;
|
int units = 0;
|
||||||
for (final AbstractFile f : files) {
|
for (final AbstractFile f : files) {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
LOGGER.log(Level.WARNING, "Task cancelled: not all contents may be transfered to drawable database.");
|
LOGGER.log(Level.WARNING, "Task cancelled: not all contents may be transfered to drawable database."); //NON-NLS
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -784,17 +798,17 @@ public final class ImageGalleryController implements Executor {
|
|||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
|
|
||||||
progressHandle = ProgressHandleFactory.createHandle("commiting image/video database");
|
progressHandle = ProgressHandleFactory.createHandle(Bundle.CopyAnalyzedFiles_committingDb_status());
|
||||||
updateMessage("commiting image/video database");
|
updateMessage(Bundle.CopyAnalyzedFiles_committingDb_status());
|
||||||
updateProgress(1.0);
|
updateProgress(1.0);
|
||||||
|
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
taskDB.commitTransaction(tr, true);
|
taskDB.commitTransaction(tr, true);
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
progressHandle.progress("Stopping copy to drawable db task.");
|
progressHandle.progress(Bundle.CopyAnalyzedFiles_stopCopy_status());
|
||||||
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.WARNING, "Stopping copy to drawable db task. Failed to transfer all database contents: " + ex.getMessage());
|
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.WARNING, "Stopping copy to drawable db task. Failed to transfer all database contents: " + ex.getMessage()); //NON-NLS
|
||||||
MessageNotifyUtil.Notify.warn("There was an error populating Image Gallery database.", ex.getMessage());
|
MessageNotifyUtil.Notify.warn(Bundle.CopyAnalyzedFiles_errPopulating_errMsg(), ex.getMessage());
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
updateMessage("");
|
updateMessage("");
|
||||||
updateProgress(-1.0);
|
updateProgress(-1.0);
|
||||||
@ -816,6 +830,8 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* TODO: create methods to simplify progress value/text updates to both
|
* TODO: create methods to simplify progress value/text updates to both
|
||||||
* netbeans and ImageGallery progress/status
|
* netbeans and ImageGallery progress/status
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"PrePopulateDataSourceFiles.prepopulatingDb.status=prepopulating image/video database",
|
||||||
|
"PrePopulateDataSourceFiles.committingDb.status=commiting image/video database"})
|
||||||
private class PrePopulateDataSourceFiles extends InnerTask {
|
private class PrePopulateDataSourceFiles extends InnerTask {
|
||||||
|
|
||||||
private final Content dataSource;
|
private final Content dataSource;
|
||||||
@ -826,9 +842,9 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* check for supported images
|
* check for supported images
|
||||||
*/
|
*/
|
||||||
// (name like '.jpg' or name like '.png' ...)
|
// (name like '.jpg' or name like '.png' ...)
|
||||||
private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' OR name LIKE '%.") + "') ";
|
private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' OR name LIKE '%.") + "') "; //NON-NLS
|
||||||
|
|
||||||
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("prepopulating image/video database", this);
|
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle(Bundle.PrePopulateDataSourceFiles_prepopulatingDb_status(), this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -848,10 +864,10 @@ public final class ImageGalleryController implements Executor {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
updateMessage("prepopulating image/video database");
|
updateMessage(Bundle.PrePopulateDataSourceFiles_prepopulatingDb_status());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String fsQuery = "(fs_obj_id IS NULL) "; //default clause
|
String fsQuery = "(fs_obj_id IS NULL) "; //default clause NON-NLS
|
||||||
/*
|
/*
|
||||||
* NOTE: Logical files currently (Apr '15) have a null value for
|
* NOTE: Logical files currently (Apr '15) have a null value for
|
||||||
* fs_obj_id in DB. for them, we will not specify a fs_obj_id,
|
* fs_obj_id in DB. for them, we will not specify a fs_obj_id,
|
||||||
@ -872,10 +888,10 @@ public final class ImageGalleryController implements Executor {
|
|||||||
//use this clause to only grab files from the newly added filesystems.
|
//use this clause to only grab files from the newly added filesystems.
|
||||||
fsQuery = fileSystems.stream()
|
fsQuery = fileSystems.stream()
|
||||||
.map(fileSystem -> String.valueOf(fileSystem.getId()))
|
.map(fileSystem -> String.valueOf(fileSystem.getId()))
|
||||||
.collect(Collectors.joining(" OR fs_obj_id = ", "(fs_obj_id = ", ") "));
|
.collect(Collectors.joining(" OR fs_obj_id = ", "(fs_obj_id = ", ") ")); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<AbstractFile> files = getSleuthKitCase().findAllFilesWhere(fsQuery + " AND " + DRAWABLE_QUERY);
|
final List<AbstractFile> files = getSleuthKitCase().findAllFilesWhere(fsQuery + " AND " + DRAWABLE_QUERY); //NON-NLS
|
||||||
progressHandle.switchToDeterminate(files.size());
|
progressHandle.switchToDeterminate(files.size());
|
||||||
|
|
||||||
//do in transaction
|
//do in transaction
|
||||||
@ -883,7 +899,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
int units = 0;
|
int units = 0;
|
||||||
for (final AbstractFile f : files) {
|
for (final AbstractFile f : files) {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
LOGGER.log(Level.WARNING, "task cancelled: not all contents may be transfered to database");
|
LOGGER.log(Level.WARNING, "task cancelled: not all contents may be transfered to database"); //NON-NLS
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -893,13 +909,13 @@ public final class ImageGalleryController implements Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
progressHandle = ProgressHandleFactory.createHandle("commiting image/video database");
|
progressHandle = ProgressHandleFactory.createHandle(Bundle.PrePopulateDataSourceFiles_committingDb_status());
|
||||||
|
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
db.commitTransaction(tr, false);
|
db.commitTransaction(tr, false);
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex);
|
Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
@ -954,7 +970,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
//TODO: What to do here?
|
//TODO: What to do here?
|
||||||
LOGGER.log(Level.WARNING, "Unable to determine if file is drawable and not known. Not making any changes to DB", ex);
|
LOGGER.log(Level.WARNING, "Unable to determine if file is drawable and not known. Not making any changes to DB", ex); //NON-NLS
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableDB;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableDB;
|
||||||
@ -30,11 +32,12 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
/** static definitions and utilities for the ImageGallery module */
|
/** static definitions and utilities for the ImageGallery module */
|
||||||
|
@NbBundle.Messages({"ImageGalleryModule.moduleName=Image Gallery"})
|
||||||
public class ImageGalleryModule {
|
public class ImageGalleryModule {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ImageGalleryModule.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ImageGalleryModule.class.getName());
|
||||||
|
|
||||||
private static final String MODULE_NAME = "Image Gallery";
|
private static final String MODULE_NAME = Bundle.ImageGalleryModule_moduleName();
|
||||||
|
|
||||||
static String getModuleName() {
|
static String getModuleName() {
|
||||||
return MODULE_NAME;
|
return MODULE_NAME;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery;
|
package org.sleuthkit.autopsy.imagegallery;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
@ -83,17 +84,17 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
furtherDescriptionArea.setBackground(new java.awt.Color(240, 240, 240));
|
furtherDescriptionArea.setBackground(new java.awt.Color(240, 240, 240));
|
||||||
furtherDescriptionArea.setColumns(20);
|
furtherDescriptionArea.setColumns(20);
|
||||||
furtherDescriptionArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
|
furtherDescriptionArea.setFont(furtherDescriptionArea.getFont().deriveFont(Font.PLAIN, 11)); // NOI18N
|
||||||
furtherDescriptionArea.setLineWrap(true);
|
furtherDescriptionArea.setLineWrap(true);
|
||||||
furtherDescriptionArea.setRows(5);
|
furtherDescriptionArea.setRows(5);
|
||||||
furtherDescriptionArea.setText(NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.furtherDescriptionArea.text")); // NOI18N
|
furtherDescriptionArea.setText(NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.furtherDescriptionArea.text")); // NOI18N
|
||||||
furtherDescriptionArea.setWrapStyleWord(true);
|
furtherDescriptionArea.setWrapStyleWord(true);
|
||||||
furtherDescriptionArea.setPreferredSize(new java.awt.Dimension(378, 74));
|
furtherDescriptionArea.setPreferredSize(new java.awt.Dimension(378, 74));
|
||||||
|
|
||||||
infoIconLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"))); // NOI18N
|
infoIconLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"))); // NOI18N NON-NLS
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(infoIconLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.infoIconLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(infoIconLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.infoIconLabel.text")); // NOI18N
|
||||||
|
|
||||||
unavailableDuringInjestLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/warning16.png"))); // NOI18N
|
unavailableDuringInjestLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/warning16.png"))); // NOI18N NON-NLS
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(unavailableDuringInjestLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.unavailableDuringInjestLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(unavailableDuringInjestLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.unavailableDuringInjestLabel.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
@ -29,7 +29,7 @@ class ImageGalleryPreferences {
|
|||||||
private static final Preferences preferences = NbPreferences.forModule(ImageGalleryPreferences.class);
|
private static final Preferences preferences = NbPreferences.forModule(ImageGalleryPreferences.class);
|
||||||
|
|
||||||
/** key for the listening enabled for new cases setting */
|
/** key for the listening enabled for new cases setting */
|
||||||
private static final String ENABLED_BY_DEFAULT = "enabled_by_default";
|
private static final String ENABLED_BY_DEFAULT = "enabled_by_default"; //NON-NLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return setting of whether Image Analyzer should be automatically enabled
|
* Return setting of whether Image Analyzer should be automatically enabled
|
||||||
|
@ -68,7 +68,7 @@ import org.sleuthkit.autopsy.imagegallery.gui.navpanel.HashHitGroupList;
|
|||||||
})
|
})
|
||||||
public final class ImageGalleryTopComponent extends TopComponent implements ExplorerManager.Provider, Lookup.Provider {
|
public final class ImageGalleryTopComponent extends TopComponent implements ExplorerManager.Provider, Lookup.Provider {
|
||||||
|
|
||||||
public final static String PREFERRED_ID = "ImageGalleryTopComponent";
|
public final static String PREFERRED_ID = "ImageGalleryTopComponent"; // NON-NLS
|
||||||
private static final Logger LOGGER = Logger.getLogger(ImageGalleryTopComponent.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ImageGalleryTopComponent.class.getName());
|
||||||
private static boolean topComponentInitialized = false;
|
private static boolean topComponentInitialized = false;
|
||||||
|
|
||||||
@ -81,11 +81,11 @@ public final class ImageGalleryTopComponent extends TopComponent implements Expl
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// timeLineController.openTimeLine();
|
// timeLineController.openTimeLine();
|
||||||
final ImageGalleryTopComponent tc = (ImageGalleryTopComponent) WindowManager.getDefault().findTopComponent("ImageGalleryTopComponent");
|
final ImageGalleryTopComponent tc = (ImageGalleryTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
|
||||||
if (tc != null) {
|
if (tc != null) {
|
||||||
topComponentInitialized = true;
|
topComponentInitialized = true;
|
||||||
WindowManager.getDefault().isTopComponentFloating(tc);
|
WindowManager.getDefault().isTopComponentFloating(tc);
|
||||||
Mode mode = WindowManager.getDefault().findMode("timeline");
|
Mode mode = WindowManager.getDefault().findMode("timeline"); // NON-NLS
|
||||||
if (mode != null) {
|
if (mode != null) {
|
||||||
mode.dockInto(tc);
|
mode.dockInto(tc);
|
||||||
}
|
}
|
||||||
@ -96,12 +96,12 @@ public final class ImageGalleryTopComponent extends TopComponent implements Expl
|
|||||||
|
|
||||||
public static void closeTopComponent() {
|
public static void closeTopComponent() {
|
||||||
if (topComponentInitialized) {
|
if (topComponentInitialized) {
|
||||||
final TopComponent etc = WindowManager.getDefault().findTopComponent("ImageGalleryTopComponent");
|
final TopComponent etc = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
|
||||||
if (etc != null) {
|
if (etc != null) {
|
||||||
try {
|
try {
|
||||||
etc.close();
|
etc.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.log(Level.SEVERE, "failed to close ImageGalleryTopComponent", e);
|
LOGGER.log(Level.SEVERE, "failed to close " + PREFERRED_ID, e); // NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,9 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
*/
|
*/
|
||||||
class PerCaseProperties {
|
class PerCaseProperties {
|
||||||
|
|
||||||
public static final String ENABLED = "enabled";
|
public static final String ENABLED = "enabled"; //NON-NLS
|
||||||
|
|
||||||
public static final String STALE = "stale";
|
public static final String STALE = "stale"; //NON-NLS
|
||||||
|
|
||||||
private final Case theCase;
|
private final Case theCase;
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ class PerCaseProperties {
|
|||||||
* @return true if the config exists, false otherwise.
|
* @return true if the config exists, false otherwise.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean configExists(String moduleName) {
|
public synchronized boolean configExists(String moduleName) {
|
||||||
Path get = Paths.get(theCase.getModuleDirectory(), moduleName, theCase.getName() + ".properties");
|
Path get = Paths.get(theCase.getModuleDirectory(), moduleName, theCase.getName() + ".properties"); //NON-NLS
|
||||||
return Files.exists(get);
|
return Files.exists(get);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ public enum ThumbnailCache {
|
|||||||
try {
|
try {
|
||||||
return cache.get(file.getId(), () -> load(file));
|
return cache.get(file.getId(), () -> load(file));
|
||||||
} catch (UncheckedExecutionException | CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
|
} catch (UncheckedExecutionException | CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to load thumbnail for file: " + file.getName(), ex.getCause());
|
LOGGER.log(Level.WARNING, "Failed to load thumbnail for file: " + file.getName(), ex.getCause()); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ public enum ThumbnailCache {
|
|||||||
try {
|
try {
|
||||||
return get(ImageGalleryController.getDefault().getFileFromId(fileID));
|
return get(ImageGalleryController.getDefault().getFileFromId(fileID));
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to load thumbnail for file: " + fileID, ex.getCause());
|
LOGGER.log(Level.WARNING, "Failed to load thumbnail for file: " + fileID, ex.getCause()); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,9 +142,9 @@ public enum ThumbnailCache {
|
|||||||
return cachedThumbnail;
|
return cachedThumbnail;
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Unable to parse cache file path: " + cachFile.getPath(), ex);
|
LOGGER.log(Level.WARNING, "Unable to parse cache file path: " + cachFile.getPath(), ex); //NON-NLS
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Unable to read cache file " + cachFile.getPath(), ex);
|
LOGGER.log(Level.WARNING, "Unable to read cache file " + cachFile.getPath(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -176,7 +176,7 @@ public enum ThumbnailCache {
|
|||||||
return Optional.of(ImageUtils.getCachedThumbnailFile(file.getAbstractFile(), MAX_THUMBNAIL_SIZE));
|
return Optional.of(ImageUtils.getCachedThumbnailFile(file.getAbstractFile(), MAX_THUMBNAIL_SIZE));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to create cache file.{0}", e.getLocalizedMessage());
|
LOGGER.log(Level.WARNING, "Failed to create cache file.{0}", e.getLocalizedMessage()); //NON-NLS
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ public enum ThumbnailCache {
|
|||||||
try {
|
try {
|
||||||
cache.put(Long.MIN_VALUE, newGetThumbnailTask.get());
|
cache.put(Long.MIN_VALUE, newGetThumbnailTask.get());
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "There was an exception even though thumbnail task succedded for. This should not be possible.", ex);
|
LOGGER.log(Level.SEVERE, "There was an exception even though thumbnail task succedded for. This should not be possible.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -28,6 +28,8 @@ import javafx.application.Platform;
|
|||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Menu;
|
import javafx.scene.control.Menu;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.Utilities;
|
import org.openide.util.Utilities;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
@ -59,8 +61,12 @@ public class AddDrawableTagAction extends AddTagAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NbBundle.Messages({"AddDrawableTagAction.displayName.plural=Tag Files",
|
||||||
|
"AddDrawableTagAction.displayName.singular=Tag File"})
|
||||||
protected String getActionDisplayName() {
|
protected String getActionDisplayName() {
|
||||||
return Utilities.actionsGlobalContext().lookupAll(AbstractFile.class).size() > 1 ? "Tag Files" : "Tag File";
|
return Utilities.actionsGlobalContext().lookupAll(AbstractFile.class).size() > 1
|
||||||
|
? Bundle.AddDrawableTagAction_displayName_plural()
|
||||||
|
: Bundle.AddDrawableTagAction_displayName_singular();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,6 +76,8 @@ public class AddDrawableTagAction extends AddTagAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NbBundle.Messages({"# {0} - fileID",
|
||||||
|
"AddDrawableTagAction.addTagsToFiles.alert=Unable to tag file {0}."})
|
||||||
public void addTagsToFiles(TagName tagName, String comment, Set<Long> selectedFiles) {
|
public void addTagsToFiles(TagName tagName, String comment, Set<Long> selectedFiles) {
|
||||||
new SwingWorker<Void, Void>() {
|
new SwingWorker<Void, Void>() {
|
||||||
|
|
||||||
@ -78,7 +86,7 @@ public class AddDrawableTagAction extends AddTagAction {
|
|||||||
for (Long fileID : selectedFiles) {
|
for (Long fileID : selectedFiles) {
|
||||||
try {
|
try {
|
||||||
final DrawableFile<?> file = controller.getFileFromId(fileID);
|
final DrawableFile<?> file = controller.getFileFromId(fileID);
|
||||||
LOGGER.log(Level.INFO, "tagging {0} with {1} and comment {2}", new Object[]{file.getName(), tagName.getDisplayName(), comment});
|
LOGGER.log(Level.INFO, "tagging {0} with {1} and comment {2}", new Object[]{file.getName(), tagName.getDisplayName(), comment}); //NON-NLS
|
||||||
|
|
||||||
// check if the same tag is being added for the same abstract file.
|
// check if the same tag is being added for the same abstract file.
|
||||||
DrawableTagsManager tagsManager = controller.getTagsManager();
|
DrawableTagsManager tagsManager = controller.getTagsManager();
|
||||||
@ -89,16 +97,16 @@ public class AddDrawableTagAction extends AddTagAction {
|
|||||||
.findAny();
|
.findAny();
|
||||||
|
|
||||||
if (duplicateTagName.isPresent()) {
|
if (duplicateTagName.isPresent()) {
|
||||||
LOGGER.log(Level.INFO, "{0} already tagged as {1}. Skipping.", new Object[]{file.getName(), tagName.getDisplayName()});
|
LOGGER.log(Level.INFO, "{0} already tagged as {1}. Skipping.", new Object[]{file.getName(), tagName.getDisplayName()}); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.INFO, "Tagging {0} as {1}", new Object[]{file.getName(), tagName.getDisplayName()});
|
LOGGER.log(Level.INFO, "Tagging {0} as {1}", new Object[]{file.getName(), tagName.getDisplayName()}); //NON-NLS
|
||||||
controller.getTagsManager().addContentTag(file, tagName, comment);
|
controller.getTagsManager().addContentTag(file, tagName, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
LOGGER.log(Level.SEVERE, "Error tagging file", tskCoreException);
|
LOGGER.log(Level.SEVERE, "Error tagging file", tskCoreException); //NON-NLS
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
new Alert(Alert.AlertType.ERROR, "Unable to tag file " + fileID + ".").show();
|
new Alert(Alert.AlertType.ERROR, Bundle.AddDrawableTagAction_addTagsToFiles_alert(fileID)).show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +119,7 @@ public class AddDrawableTagAction extends AddTagAction {
|
|||||||
try {
|
try {
|
||||||
get();
|
get();
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "unexpected exception while tagging files", ex);
|
LOGGER.log(Level.SEVERE, "unexpected exception while tagging files", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
|
@ -25,6 +25,8 @@ import javafx.event.ActionEvent;
|
|||||||
import javafx.scene.control.Menu;
|
import javafx.scene.control.Menu;
|
||||||
import javafx.scene.control.MenuItem;
|
import javafx.scene.control.MenuItem;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog;
|
import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog;
|
||||||
@ -71,13 +73,17 @@ abstract class AddTagAction {
|
|||||||
*/
|
*/
|
||||||
// @@@ This user interface has some significant usability issues and needs
|
// @@@ This user interface has some significant usability issues and needs
|
||||||
// to be reworked.
|
// to be reworked.
|
||||||
|
@NbBundle.Messages({"AddTagAction.menuItem.quickTag=Quick Tag",
|
||||||
|
"AddTagAction.menuItem.noTags=No tags",
|
||||||
|
"AddTagAction.menuItem.newTag=New Tag...",
|
||||||
|
"AddTagAction.menuItem.tagAndComment=Tag and Comment..."})
|
||||||
protected class TagMenu extends Menu {
|
protected class TagMenu extends Menu {
|
||||||
|
|
||||||
TagMenu(ImageGalleryController controller) {
|
TagMenu(ImageGalleryController controller) {
|
||||||
super(getActionDisplayName());
|
super(getActionDisplayName());
|
||||||
|
|
||||||
// Create a "Quick Tag" sub-menu.
|
// Create a "Quick Tag" sub-menu.
|
||||||
Menu quickTagMenu = new Menu("Quick Tag");
|
Menu quickTagMenu = new Menu(Bundle.AddTagAction_menuItem_quickTag());
|
||||||
getItems().add(quickTagMenu);
|
getItems().add(quickTagMenu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -87,7 +93,7 @@ abstract class AddTagAction {
|
|||||||
*/
|
*/
|
||||||
Collection<TagName> tagNames = controller.getTagsManager().getNonCategoryTagNames();
|
Collection<TagName> tagNames = controller.getTagsManager().getNonCategoryTagNames();
|
||||||
if (tagNames.isEmpty()) {
|
if (tagNames.isEmpty()) {
|
||||||
MenuItem empty = new MenuItem("No tags");
|
MenuItem empty = new MenuItem(Bundle.AddTagAction_menuItem_noTags());
|
||||||
empty.setDisable(true);
|
empty.setDisable(true);
|
||||||
quickTagMenu.getItems().add(empty);
|
quickTagMenu.getItems().add(empty);
|
||||||
} else {
|
} else {
|
||||||
@ -105,7 +111,7 @@ abstract class AddTagAction {
|
|||||||
* Selecting this item initiates a dialog that can be used to create
|
* Selecting this item initiates a dialog that can be used to create
|
||||||
* or select a tag name and adds a tag with the resulting name.
|
* or select a tag name and adds a tag with the resulting name.
|
||||||
*/
|
*/
|
||||||
MenuItem newTagMenuItem = new MenuItem("New Tag...");
|
MenuItem newTagMenuItem = new MenuItem(Bundle.AddTagAction_menuItem_newTag());
|
||||||
newTagMenuItem.setOnAction((ActionEvent t) -> {
|
newTagMenuItem.setOnAction((ActionEvent t) -> {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
TagName tagName = GetTagNameDialog.doDialog(getIGWindow());
|
TagName tagName = GetTagNameDialog.doDialog(getIGWindow());
|
||||||
@ -122,7 +128,7 @@ abstract class AddTagAction {
|
|||||||
* name with an optional comment and adds a tag with the resulting
|
* name with an optional comment and adds a tag with the resulting
|
||||||
* name.
|
* name.
|
||||||
*/
|
*/
|
||||||
MenuItem tagAndCommentItem = new MenuItem("Tag and Comment...");
|
MenuItem tagAndCommentItem = new MenuItem(Bundle.AddTagAction_menuItem_tagAndComment());
|
||||||
tagAndCommentItem.setOnAction((ActionEvent t) -> {
|
tagAndCommentItem.setOnAction((ActionEvent t) -> {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
GetTagNameAndCommentDialog.TagNameAndComment tagNameAndComment = GetTagNameAndCommentDialog.doDialog(getIGWindow());
|
GetTagNameAndCommentDialog.TagNameAndComment tagNameAndComment = GetTagNameAndCommentDialog.doDialog(getIGWindow());
|
||||||
|
@ -24,6 +24,7 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,12 +33,13 @@ import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
|||||||
//TODO: This and the corresponding timeline action are identical except for the type of the controller... abstract something! -jm
|
//TODO: This and the corresponding timeline action are identical except for the type of the controller... abstract something! -jm
|
||||||
public class Back extends Action {
|
public class Back extends Action {
|
||||||
|
|
||||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/arrow-180.png", 16, 16, true, true, true);
|
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/arrow-180.png", 16, 16, true, true, true); //NON-NLS
|
||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
|
|
||||||
|
@NbBundle.Messages({"Back.diplayName=Back"})
|
||||||
public Back(ImageGalleryController controller) {
|
public Back(ImageGalleryController controller) {
|
||||||
super("Back");
|
super(Bundle.Back_displayName());
|
||||||
setGraphic(new ImageView(BACK_IMAGE));
|
setGraphic(new ImageView(BACK_IMAGE));
|
||||||
setAccelerator(new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN));
|
setAccelerator(new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN));
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
|
@ -35,6 +35,8 @@ import javafx.scene.input.KeyCodeCombination;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||||
@ -52,6 +54,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* TODO: since we are not using actionsGlobalContext anymore and this has
|
* TODO: since we are not using actionsGlobalContext anymore and this has
|
||||||
* diverged from autopsy action, make this extend from controlsfx Action
|
* diverged from autopsy action, make this extend from controlsfx Action
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"CategorizeAction.displayName=Categorize"})
|
||||||
public class CategorizeAction extends AddTagAction {
|
public class CategorizeAction extends AddTagAction {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(CategorizeAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CategorizeAction.class.getName());
|
||||||
@ -71,7 +74,7 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getActionDisplayName() {
|
protected String getActionDisplayName() {
|
||||||
return "Categorize";
|
return Bundle.CategorizeAction_displayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -86,7 +89,7 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addTagsToFiles(TagName tagName, String comment, Set<Long> selectedFiles, boolean createUndo) {
|
public void addTagsToFiles(TagName tagName, String comment, Set<Long> selectedFiles, boolean createUndo) {
|
||||||
Logger.getAnonymousLogger().log(Level.INFO, "categorizing{0} as {1}", new Object[]{selectedFiles.toString(), tagName.getDisplayName()});
|
Logger.getAnonymousLogger().log(Level.INFO, "categorizing{0} as {1}", new Object[]{selectedFiles.toString(), tagName.getDisplayName()}); //NON-NLS
|
||||||
controller.queueDBWorkerTask(new CategorizeTask(selectedFiles, tagName, comment, createUndo));
|
controller.queueDBWorkerTask(new CategorizeTask(selectedFiles, tagName, comment, createUndo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
static private class CategoryMenu extends Menu {
|
static private class CategoryMenu extends Menu {
|
||||||
|
|
||||||
CategoryMenu(ImageGalleryController controller) {
|
CategoryMenu(ImageGalleryController controller) {
|
||||||
super("Categorize");
|
super(Bundle.CategorizeAction_displayName());
|
||||||
|
|
||||||
// Each category get an item in the sub-menu. Selecting one of these menu items adds
|
// Each category get an item in the sub-menu. Selecting one of these menu items adds
|
||||||
// a tag with the associated category.
|
// a tag with the associated category.
|
||||||
@ -114,6 +117,9 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({"# {0} - fileID number",
|
||||||
|
"CategorizeTask.errorUnable.msg=Unable to categorize {0}.",
|
||||||
|
"CategorizeTask.errorUnable.title=Categorizing Error"})
|
||||||
private class CategorizeTask extends ImageGalleryController.InnerTask {
|
private class CategorizeTask extends ImageGalleryController.InnerTask {
|
||||||
|
|
||||||
private final Set<Long> fileIDs;
|
private final Set<Long> fileIDs;
|
||||||
@ -132,6 +138,7 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final DrawableTagsManager tagsManager = controller.getTagsManager();
|
final DrawableTagsManager tagsManager = controller.getTagsManager();
|
||||||
@ -157,7 +164,7 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
try {
|
try {
|
||||||
tagsManager.deleteContentTag(ct);
|
tagsManager.deleteContentTag(ct);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error removing old categories result", ex);
|
LOGGER.log(Level.SEVERE, "Error removing old categories result", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -170,8 +177,11 @@ public class CategorizeAction extends AddTagAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error categorizing result", ex);
|
LOGGER.log(Level.SEVERE, "Error categorizing result", ex); //NON-NLS
|
||||||
JOptionPane.showMessageDialog(null, "Unable to categorize " + fileID + ".", "Categorizing Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null,
|
||||||
|
Bundle.CategorizeTask_errorUnable_msg(fileID),
|
||||||
|
Bundle.CategorizeTask_errorUnable_title(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import java.util.logging.Level;
|
|||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||||
@ -38,8 +39,9 @@ public class DeleteFollowUpTagAction extends Action {
|
|||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(DeleteFollowUpTagAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(DeleteFollowUpTagAction.class.getName());
|
||||||
|
|
||||||
|
@NbBundle.Messages("DeleteFollwUpTagAction.displayName=Delete Follow Up Tag")
|
||||||
public DeleteFollowUpTagAction(final ImageGalleryController controller, final DrawableFile<?> file) {
|
public DeleteFollowUpTagAction(final ImageGalleryController controller, final DrawableFile<?> file) {
|
||||||
super("Delete Follow Up Tag");
|
super(Bundle.DeleteFollwUpTagAction_displayName());
|
||||||
setEventHandler((ActionEvent t) -> {
|
setEventHandler((ActionEvent t) -> {
|
||||||
new SwingWorker<Void, Void>() {
|
new SwingWorker<Void, Void>() {
|
||||||
|
|
||||||
@ -57,7 +59,7 @@ public class DeleteFollowUpTagAction extends Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to delete follow up tag.", ex);
|
LOGGER.log(Level.SEVERE, "Failed to delete follow up tag.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -24,20 +24,22 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//TODO: This and the corresponding timeline action are identical except for the type of the controller... abstract something! -jm
|
//TODO: This and the corresponding timeline action are identical except for the type of the controller... abstract something! -jm
|
||||||
|
@NbBundle.Messages({"Forward.displayName=Forward"})
|
||||||
public class Forward extends Action {
|
public class Forward extends Action {
|
||||||
|
|
||||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/arrow.png", 16, 16, true, true, true);
|
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/arrow.png", 16, 16, true, true, true); //NON-NLS
|
||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
|
|
||||||
public Forward(ImageGalleryController controller) {
|
public Forward(ImageGalleryController controller) {
|
||||||
super("Forward");
|
super(Bundle.Forward_displayName());
|
||||||
setGraphic(new ImageView(BACK_IMAGE));
|
setGraphic(new ImageView(BACK_IMAGE));
|
||||||
setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN));
|
setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN));
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
|
@ -26,6 +26,7 @@ import javafx.event.ActionEvent;
|
|||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewState;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewState;
|
||||||
@ -34,15 +35,17 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewState;
|
|||||||
* Marks the currently fisplayed group as "seen" and advances to the next unseen
|
* Marks the currently fisplayed group as "seen" and advances to the next unseen
|
||||||
* group
|
* group
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"NextUnseenGroup.markGroupSeen=Mark Group Seen",
|
||||||
|
"NextUnseenGroup.nextUnseenGroup=Next Unseen group"})
|
||||||
public class NextUnseenGroup extends Action {
|
public class NextUnseenGroup extends Action {
|
||||||
|
|
||||||
private static final Image END =
|
private static final Image END =
|
||||||
new Image(NextUnseenGroup.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/control-stop.png"));
|
new Image(NextUnseenGroup.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/control-stop.png")); //NON-NLS
|
||||||
private static final Image ADVANCE =
|
private static final Image ADVANCE =
|
||||||
new Image(NextUnseenGroup.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/control-double.png"));
|
new Image(NextUnseenGroup.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/control-double.png")); //NON-NLS
|
||||||
|
|
||||||
private static final String MARK_GROUP_SEEN = "Mark Group Seen";
|
private static final String MARK_GROUP_SEEN = Bundle.NextUnseenGroup_markGroupSeen();
|
||||||
private static final String NEXT_UNSEEN_GROUP = "Next Unseen group";
|
private static final String NEXT_UNSEEN_GROUP = Bundle.NextUnseenGroup_nextUnseenGroup();
|
||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
|
|
||||||
|
@ -41,10 +41,14 @@ import org.sleuthkit.autopsy.imagegallery.ImageGalleryTopComponent;
|
|||||||
@ActionRegistration( // iconBase = "org/sleuthkit/autopsy/imagegallery/images/lightbulb.png",
|
@ActionRegistration( // iconBase = "org/sleuthkit/autopsy/imagegallery/images/lightbulb.png",
|
||||||
lazy = false,
|
lazy = false,
|
||||||
displayName = "#CTL_OpenAction")
|
displayName = "#CTL_OpenAction")
|
||||||
@Messages("CTL_OpenAction=View Images/Videos")
|
@Messages({"CTL_OpenAction=View Images/Videos",
|
||||||
|
"OpenAction.stale.confDlg.msg=The image / video database may be out of date. " +
|
||||||
|
"Do you want to update and listen for further ingest results?\n" +
|
||||||
|
"Choosing 'yes' will update the database and enable listening to future ingests.",
|
||||||
|
"OpenAction.stale.confDlg.title=Image Gallery"})
|
||||||
public final class OpenAction extends CallableSystemAction {
|
public final class OpenAction extends CallableSystemAction {
|
||||||
|
|
||||||
private static final String VIEW_IMAGES_VIDEOS = "View Images/Videos";
|
private static final String VIEW_IMAGES_VIDEOS = Bundle.CTL_OpenAction();
|
||||||
|
|
||||||
private static final boolean fxInited = Installer.isJavaFxInited();
|
private static final boolean fxInited = Installer.isJavaFxInited();
|
||||||
|
|
||||||
@ -83,11 +87,8 @@ public final class OpenAction extends CallableSystemAction {
|
|||||||
|
|
||||||
if (ImageGalleryModule.isDrawableDBStale(currentCase)) {
|
if (ImageGalleryModule.isDrawableDBStale(currentCase)) {
|
||||||
//drawable db is stale, ask what to do
|
//drawable db is stale, ask what to do
|
||||||
int answer = JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), "The image / video database may be out of date. " + "Do you want to update and listen for further ingest results?\n"
|
int answer = JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), Bundle.OpenAction.stale.confDlg.msg(),
|
||||||
+ "Choosing 'yes' will update the database and enable listening to future ingests."
|
Bundle.OpenAction_stale_confDlg.title(), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||||
+ " Choosing 'no' will display the out of date results."
|
|
||||||
+ " Choosing 'cancel' will close the image /video gallery",
|
|
||||||
"Image Gallery", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
|
|
||||||
|
|
||||||
switch (answer) {
|
switch (answer) {
|
||||||
case JOptionPane.YES_OPTION:
|
case JOptionPane.YES_OPTION:
|
||||||
|
@ -32,14 +32,15 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
|||||||
* Wraps {@link ExternalViewerAction} in a ControlsFX {@link Action} with
|
* Wraps {@link ExternalViewerAction} in a ControlsFX {@link Action} with
|
||||||
* appropriate text and graphic
|
* appropriate text and graphic
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer"})
|
@NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer",
|
||||||
|
"OpenExternalViewerAction.displayName=External Viewer"})
|
||||||
public class OpenExternalViewerAction extends Action {
|
public class OpenExternalViewerAction extends Action {
|
||||||
|
|
||||||
private static final Image EXTERNAL = new Image(OpenExternalViewerAction.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/external.png").toExternalForm());
|
private static final Image EXTERNAL = new Image(OpenExternalViewerAction.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/external.png").toExternalForm()); //NON-NLS
|
||||||
private static final ActionEvent ACTION_EVENT = new ActionEvent(OpenExternalViewerAction.class, ActionEvent.ACTION_PERFORMED, ""); //Swing ActionEvent //NOI18N
|
private static final ActionEvent ACTION_EVENT = new ActionEvent(OpenExternalViewerAction.class, ActionEvent.ACTION_PERFORMED, ""); //Swing ActionEvent //NOI18N
|
||||||
|
|
||||||
public OpenExternalViewerAction(DrawableFile<?> file) {
|
public OpenExternalViewerAction(DrawableFile<?> file) {
|
||||||
super("External Viewer");
|
super(Bundle.OpenExternalViewerAction_displayName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: why is the name passed to the action? it means we duplicate
|
* TODO: why is the name passed to the action? it means we duplicate
|
||||||
|
@ -44,9 +44,9 @@ public final class OpenHelpAction implements ActionListener {
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().browse(URI.create("http://sleuthkit.org/autopsy/docs/user-docs/4.0/image_gallery_page.html"));
|
Desktop.getDesktop().browse(URI.create("http://sleuthkit.org/autopsy/docs/user-docs/4.0/image_gallery_page.html")); //NON-NLS
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(OpenHelpAction.class.getName()).log(Level.SEVERE, "failed to open help page", ex);
|
Logger.getLogger(OpenHelpAction.class.getName()).log(Level.SEVERE, "failed to open help page", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,17 +23,19 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that redoes the last undone command
|
* Action that redoes the last undone command
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"RedoAction.name=Redo"})
|
||||||
public class RedoAction extends Action {
|
public class RedoAction extends Action {
|
||||||
|
|
||||||
private static final Image REDO_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/redo.png", 16, 16, true, true, true);
|
private static final Image REDO_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/redo.png", 16, 16, true, true, true); //NON-NLS
|
||||||
|
|
||||||
public RedoAction(ImageGalleryController controller) {
|
public RedoAction(ImageGalleryController controller) {
|
||||||
super("Redo");
|
super(Bundle.RedoAction_name());
|
||||||
setGraphic(new ImageView(REDO_IMAGE));
|
setGraphic(new ImageView(REDO_IMAGE));
|
||||||
setAccelerator(new KeyCodeCombination(KeyCode.Y, KeyCodeCombination.CONTROL_DOWN));
|
setAccelerator(new KeyCodeCombination(KeyCode.Y, KeyCodeCombination.CONTROL_DOWN));
|
||||||
setEventHandler(actionEvent -> controller.getUndoManager().redo());
|
setEventHandler(actionEvent -> controller.getUndoManager().redo());
|
||||||
|
@ -23,17 +23,19 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that undoes the last undoable command
|
* Action that undoes the last undoable command
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"UndoAction.displayName=Undo"})
|
||||||
public class UndoAction extends Action {
|
public class UndoAction extends Action {
|
||||||
|
|
||||||
private static final Image UNDO_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/undo.png", 16, 16, true, true, true);
|
private static final Image UNDO_IMAGE = new Image("/org/sleuthkit/autopsy/imagegallery/images/undo.png", 16, 16, true, true, true); //NON-NLS
|
||||||
|
|
||||||
public UndoAction(ImageGalleryController controller) {
|
public UndoAction(ImageGalleryController controller) {
|
||||||
super("Undo");
|
super(Bundle.UndoAction_displayName());
|
||||||
setGraphic(new ImageView(UNDO_IMAGE));
|
setGraphic(new ImageView(UNDO_IMAGE));
|
||||||
setAccelerator(new KeyCodeCombination(KeyCode.Z, KeyCodeCombination.CONTROL_DOWN));
|
setAccelerator(new KeyCodeCombination(KeyCode.Z, KeyCodeCombination.CONTROL_DOWN));
|
||||||
setEventHandler(actionEvent -> controller.getUndoManager().undo());
|
setEventHandler(actionEvent -> controller.getUndoManager().undo());
|
||||||
|
@ -24,10 +24,17 @@ import java.util.function.Function;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum to represent the six categories in the DHS image categorization scheme.
|
* Enum to represent the six categories in the DHS image categorization scheme.
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"Category.one=CAT-1: Child Exploitation (Illegal)",
|
||||||
|
"Category.two=CAT-2: Child Exploitation (Non-Illegal/Age Difficult)",
|
||||||
|
"Category.three=CAT-3: CGI/Animation (Child Exploitive)",
|
||||||
|
"Category.four=CAT-4: Exemplar/Comparison (Internal Use Only)",
|
||||||
|
"Category.five=CAT-5: Non-pertinent",
|
||||||
|
"Category.zero=CAT-0: Uncategorized"})
|
||||||
public enum Category {
|
public enum Category {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -35,12 +42,12 @@ public enum Category {
|
|||||||
* preserves the fact that lower category numbers are first/most sever,
|
* preserves the fact that lower category numbers are first/most sever,
|
||||||
* except 0 which is last
|
* except 0 which is last
|
||||||
*/
|
*/
|
||||||
ONE(Color.RED, 1, "CAT-1: Child Exploitation (Illegal)"),
|
ONE(Color.RED, 1, Bundle.Category_one()),
|
||||||
TWO(Color.ORANGE, 2, "CAT-2: Child Exploitation (Non-Illegal/Age Difficult)"),
|
TWO(Color.ORANGE, 2, Bundle.Category_two()),
|
||||||
THREE(Color.YELLOW, 3, "CAT-3: CGI/Animation (Child Exploitive)"),
|
THREE(Color.YELLOW, 3, Bundle.Category_three()),
|
||||||
FOUR(Color.BISQUE, 4, "CAT-4: Exemplar/Comparison (Internal Use Only)"),
|
FOUR(Color.BISQUE, 4, Bundle.Category_four()),
|
||||||
FIVE(Color.GREEN, 5, "CAT-5: Non-pertinent"),
|
FIVE(Color.GREEN, 5, Bundle.Category_five()),
|
||||||
ZERO(Color.LIGHTGREY, 0, "CAT-0: Uncategorized");
|
ZERO(Color.LIGHTGREY, 0, Bundle.Category_zero());
|
||||||
|
|
||||||
public static ImmutableList<Category> getNonZeroCategories() {
|
public static ImmutableList<Category> getNonZeroCategories() {
|
||||||
return nonZeroCategories;
|
return nonZeroCategories;
|
||||||
|
@ -68,8 +68,8 @@ public class CategoryManager {
|
|||||||
* Used to distribute {@link CategoryChangeEvent}s
|
* Used to distribute {@link CategoryChangeEvent}s
|
||||||
*/
|
*/
|
||||||
private final EventBus categoryEventBus = new AsyncEventBus(Executors.newSingleThreadExecutor(
|
private final EventBus categoryEventBus = new AsyncEventBus(Executors.newSingleThreadExecutor(
|
||||||
new BasicThreadFactory.Builder().namingPattern("Category Event Bus").uncaughtExceptionHandler((Thread t, Throwable e) -> {
|
new BasicThreadFactory.Builder().namingPattern("Category Event Bus").uncaughtExceptionHandler((Thread t, Throwable e) -> { //NON-NLS
|
||||||
LOGGER.log(Level.SEVERE, "Uncaught exception in category event bus handler", e);
|
LOGGER.log(Level.SEVERE, "Uncaught exception in category event bus handler", e); //NON-NLS
|
||||||
}).build()
|
}).build()
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ public class CategoryManager {
|
|||||||
longAdder.add(db.getCategoryCount(cat));
|
longAdder.add(db.getCategoryCount(cat));
|
||||||
longAdder.increment();
|
longAdder.increment();
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Case closed while getting files");
|
LOGGER.log(Level.WARNING, "Case closed while getting files"); //NON-NLS
|
||||||
}
|
}
|
||||||
return longAdder;
|
return longAdder;
|
||||||
}
|
}
|
||||||
@ -210,8 +210,8 @@ public class CategoryManager {
|
|||||||
try {
|
try {
|
||||||
categoryEventBus.unregister(listener);
|
categoryEventBus.unregister(listener);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (e.getMessage().contains("missing event subscriber for an annotated method. Is " + listener + " registered?")) {
|
if (e.getMessage().contains("missing event subscriber for an annotated method. Is " + listener + " registered?")) { //NON-NLS
|
||||||
LOGGER.log(Level.WARNING, "Attempted to unregister {0} for category change events, but it was not registered.", listener.toString());
|
LOGGER.log(Level.WARNING, "Attempted to unregister {0} for category change events, but it was not registered.", listener.toString()); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -254,12 +254,12 @@ public class CategoryManager {
|
|||||||
try {
|
try {
|
||||||
tagsManager.deleteContentTag(ct);
|
tagsManager.deleteContentTag(ct);
|
||||||
} catch (TskCoreException tskException) {
|
} catch (TskCoreException tskException) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to delete content tag. Unable to maintain categories in a consistent state.", tskException);
|
LOGGER.log(Level.SEVERE, "Failed to delete content tag. Unable to maintain categories in a consistent state.", tskException); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException tskException) {
|
} catch (TskCoreException tskException) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get content tags for content. Unable to maintain category in a consistent state.", tskException);
|
LOGGER.log(Level.SEVERE, "Failed to get content tags for content. Unable to maintain category in a consistent state.", tskException); //NON-NLS
|
||||||
}
|
}
|
||||||
Category newCat = CategoryManager.categoryFromTagName(addedTag.getName());
|
Category newCat = CategoryManager.categoryFromTagName(addedTag.getName());
|
||||||
if (newCat != Category.ZERO) {
|
if (newCat != Category.ZERO) {
|
||||||
|
@ -27,6 +27,7 @@ import javafx.beans.property.ReadOnlyStringWrapper;
|
|||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.datamodel.TagName;
|
import org.sleuthkit.datamodel.TagName;
|
||||||
|
|
||||||
@ -37,22 +38,37 @@ import org.sleuthkit.datamodel.TagName;
|
|||||||
* TODO: Review and refactor DrawableAttribute related code with an eye to usage
|
* TODO: Review and refactor DrawableAttribute related code with an eye to usage
|
||||||
* of type paramaters and multivalued attributes
|
* of type paramaters and multivalued attributes
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"DrawableAttribute.md5hash=MD5 Hash",
|
||||||
|
"DrawableAttribute.name=Name",
|
||||||
|
"DrawableAttribute.analyzed=Analyzed",
|
||||||
|
"DrawableAttribute.category=Category",
|
||||||
|
"DrawableAttribute.tags=Tags",
|
||||||
|
"DrawableAttribute.path=Path",
|
||||||
|
"DrawableAttribute.createdTime=Created Time",
|
||||||
|
"DrawableAttribute.modifiedTime=Modified Time",
|
||||||
|
"DrawableAttribute.cameraMake=Camera Make",
|
||||||
|
"DrawableAttribute.cameraModel=Camera Model",
|
||||||
|
"DrawableAttribute.hashSet=Hashset",
|
||||||
|
"DrawableAttribute.intObjID=Internal Object ID",
|
||||||
|
"DrawableAttribute.width=Width",
|
||||||
|
"DrawableAttribute.height=Height",
|
||||||
|
"DrawableAttribute.mimeType=MIME type"})
|
||||||
public class DrawableAttribute<T extends Comparable<T>> {
|
public class DrawableAttribute<T extends Comparable<T>> {
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MD5_HASH =
|
public final static DrawableAttribute<String> MD5_HASH =
|
||||||
new DrawableAttribute<>(AttributeName.MD5_HASH, "MD5 Hash",
|
new DrawableAttribute<>(AttributeName.MD5_HASH, Bundle.DrawableAttribute_md5hash(),
|
||||||
false,
|
false,
|
||||||
"icon-hashtag.png",
|
"icon-hashtag.png", // NON-NLS
|
||||||
f -> Collections.singleton(f.getMd5Hash()));
|
f -> Collections.singleton(f.getMd5Hash()));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> NAME =
|
public final static DrawableAttribute<String> NAME =
|
||||||
new DrawableAttribute<>(AttributeName.NAME, "Name",
|
new DrawableAttribute<>(AttributeName.NAME, Bundle.DrawableAttribute_name(),
|
||||||
true,
|
true,
|
||||||
"folder-rename.png",
|
"folder-rename.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getName()));
|
f -> Collections.singleton(f.getName()));
|
||||||
|
|
||||||
public final static DrawableAttribute<Boolean> ANALYZED =
|
public final static DrawableAttribute<Boolean> ANALYZED =
|
||||||
new DrawableAttribute<>(AttributeName.ANALYZED, "Analyzed",
|
new DrawableAttribute<>(AttributeName.ANALYZED, Bundle.DrawableAttribute_analyzed(),
|
||||||
true,
|
true,
|
||||||
"",
|
"",
|
||||||
f -> Collections.singleton(f.isAnalyzed()));
|
f -> Collections.singleton(f.isAnalyzed()));
|
||||||
@ -66,75 +82,75 @@ public class DrawableAttribute<T extends Comparable<T>> {
|
|||||||
* advantage. move categories into DrawableDB?
|
* advantage. move categories into DrawableDB?
|
||||||
*/
|
*/
|
||||||
public final static DrawableAttribute<Category> CATEGORY =
|
public final static DrawableAttribute<Category> CATEGORY =
|
||||||
new DrawableAttribute<>(AttributeName.CATEGORY, "Category",
|
new DrawableAttribute<>(AttributeName.CATEGORY, Bundle.DrawableAttribute_category(),
|
||||||
false,
|
false,
|
||||||
"category-icon.png",
|
"category-icon.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getCategory()));
|
f -> Collections.singleton(f.getCategory()));
|
||||||
|
|
||||||
public final static DrawableAttribute<TagName> TAGS =
|
public final static DrawableAttribute<TagName> TAGS =
|
||||||
new DrawableAttribute<>(AttributeName.TAGS, "Tags",
|
new DrawableAttribute<>(AttributeName.TAGS, Bundle.DrawableAttribute_tags(),
|
||||||
false,
|
false,
|
||||||
"tag_red.png",
|
"tag_red.png", //NON-NLS
|
||||||
DrawableFile::getTagNames);
|
DrawableFile::getTagNames);
|
||||||
|
|
||||||
public final static DrawableAttribute<String> PATH =
|
public final static DrawableAttribute<String> PATH =
|
||||||
new DrawableAttribute<>(AttributeName.PATH, "Path",
|
new DrawableAttribute<>(AttributeName.PATH, Bundle.DrawableAttribute_path(),
|
||||||
true,
|
true,
|
||||||
"folder_picture.png",
|
"folder_picture.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getDrawablePath()));
|
f -> Collections.singleton(f.getDrawablePath()));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> CREATED_TIME =
|
public final static DrawableAttribute<String> CREATED_TIME =
|
||||||
new DrawableAttribute<>(AttributeName.CREATED_TIME, "Created Time",
|
new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(),
|
||||||
true,
|
true,
|
||||||
"clock--plus.png",
|
"clock--plus.png", //NON-NLS
|
||||||
f -> Collections.singleton(ContentUtils.getStringTime(f.getCrtime(), f)));
|
f -> Collections.singleton(ContentUtils.getStringTime(f.getCrtime(), f)));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MODIFIED_TIME =
|
public final static DrawableAttribute<String> MODIFIED_TIME =
|
||||||
new DrawableAttribute<>(AttributeName.MODIFIED_TIME, "Modified Time",
|
new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(),
|
||||||
true,
|
true,
|
||||||
"clock--pencil.png",
|
"clock--pencil.png", //NON-NLS
|
||||||
f -> Collections.singleton(ContentUtils.getStringTime(f.getMtime(), f)));
|
f -> Collections.singleton(ContentUtils.getStringTime(f.getMtime(), f)));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MAKE =
|
public final static DrawableAttribute<String> MAKE =
|
||||||
new DrawableAttribute<>(AttributeName.MAKE, "Camera Make",
|
new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(),
|
||||||
true,
|
true,
|
||||||
"camera.png",
|
"camera.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getMake()));
|
f -> Collections.singleton(f.getMake()));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MODEL =
|
public final static DrawableAttribute<String> MODEL =
|
||||||
new DrawableAttribute<>(AttributeName.MODEL, "Camera Model",
|
new DrawableAttribute<>(AttributeName.MODEL, Bundle.DrawableAttribute_cameraModel(),
|
||||||
true,
|
true,
|
||||||
"camera.png",
|
"camera.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getModel()));
|
f -> Collections.singleton(f.getModel()));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> HASHSET =
|
public final static DrawableAttribute<String> HASHSET =
|
||||||
new DrawableAttribute<>(AttributeName.HASHSET, "Hashset",
|
new DrawableAttribute<>(AttributeName.HASHSET, Bundle.DrawableAttribute_hashSet(),
|
||||||
true,
|
true,
|
||||||
"hashset_hits.png",
|
"hashset_hits.png", //NON-NLS
|
||||||
DrawableFile::getHashSetNamesUnchecked);
|
DrawableFile::getHashSetNamesUnchecked);
|
||||||
|
|
||||||
public final static DrawableAttribute<Long> OBJ_ID =
|
public final static DrawableAttribute<Long> OBJ_ID =
|
||||||
new DrawableAttribute<>(AttributeName.OBJ_ID, "Internal Object ID",
|
new DrawableAttribute<>(AttributeName.OBJ_ID, Bundle.DrawableAttribute_intObjID(),
|
||||||
true,
|
true,
|
||||||
"",
|
"",
|
||||||
f -> Collections.singleton(f.getId()));
|
f -> Collections.singleton(f.getId()));
|
||||||
|
|
||||||
public final static DrawableAttribute<Double> WIDTH =
|
public final static DrawableAttribute<Double> WIDTH =
|
||||||
new DrawableAttribute<>(AttributeName.WIDTH, "Width",
|
new DrawableAttribute<>(AttributeName.WIDTH, Bundle.DrawableAttribute_width(),
|
||||||
false,
|
false,
|
||||||
"arrow-resize.png",
|
"arrow-resize.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getWidth()));
|
f -> Collections.singleton(f.getWidth()));
|
||||||
|
|
||||||
public final static DrawableAttribute<Double> HEIGHT =
|
public final static DrawableAttribute<Double> HEIGHT =
|
||||||
new DrawableAttribute<>(AttributeName.HEIGHT, "Height",
|
new DrawableAttribute<>(AttributeName.HEIGHT, Bundle.DrawableAttribute_height(),
|
||||||
false,
|
false,
|
||||||
"arrow-resize-090.png",
|
"arrow-resize-090.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getHeight()));
|
f -> Collections.singleton(f.getHeight()));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MIME_TYPE =
|
public final static DrawableAttribute<String> MIME_TYPE =
|
||||||
new DrawableAttribute<>(AttributeName.MIME_TYPE, "MIME type",
|
new DrawableAttribute<>(AttributeName.MIME_TYPE, Bundle.DrawableAttribute_mimeType(),
|
||||||
false,
|
false,
|
||||||
"mime_types.png",
|
"mime_types.png", //NON-NLS
|
||||||
f -> Collections.singleton(f.getMIMEType()));
|
f -> Collections.singleton(f.getMIMEType()));
|
||||||
|
|
||||||
final private static List< DrawableAttribute<?>> groupables =
|
final private static List< DrawableAttribute<?>> groupables =
|
||||||
@ -170,7 +186,7 @@ public class DrawableAttribute<T extends Comparable<T>> {
|
|||||||
* time they are needed
|
* time they are needed
|
||||||
*/
|
*/
|
||||||
if (null == icon && StringUtils.isNotBlank(imageName)) {
|
if (null == icon && StringUtils.isNotBlank(imageName)) {
|
||||||
this.icon = new Image("org/sleuthkit/autopsy/imagegallery/images/" + imageName, true);
|
this.icon = new Image("org/sleuthkit/autopsy/imagegallery/images/" + imageName, true); //NON-NLS
|
||||||
}
|
}
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
@ -77,11 +77,11 @@ public final class DrawableDB {
|
|||||||
private static final org.sleuthkit.autopsy.coreutils.Logger LOGGER = Logger.getLogger(DrawableDB.class.getName());
|
private static final org.sleuthkit.autopsy.coreutils.Logger LOGGER = Logger.getLogger(DrawableDB.class.getName());
|
||||||
|
|
||||||
//column name constants//////////////////////
|
//column name constants//////////////////////
|
||||||
private static final String ANALYZED = "analyzed";
|
private static final String ANALYZED = "analyzed"; //NON-NLS
|
||||||
|
|
||||||
private static final String OBJ_ID = "obj_id";
|
private static final String OBJ_ID = "obj_id"; //NON-NLS
|
||||||
|
|
||||||
private static final String HASH_SET_NAME = "hash_set_name";
|
private static final String HASH_SET_NAME = "hash_set_name"; //NON-NLS
|
||||||
|
|
||||||
private final PreparedStatement insertHashSetStmt;
|
private final PreparedStatement insertHashSetStmt;
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ public final class DrawableDB {
|
|||||||
try {
|
try {
|
||||||
Class.forName("org.sqlite.JDBC");
|
Class.forName("org.sqlite.JDBC");
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to load sqlite JDBC driver", ex);
|
LOGGER.log(Level.SEVERE, "Failed to load sqlite JDBC driver", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private final SleuthkitCase tskCase;
|
private final SleuthkitCase tskCase;
|
||||||
@ -201,33 +201,33 @@ public final class DrawableDB {
|
|||||||
Files.createDirectories(dbPath.getParent());
|
Files.createDirectories(dbPath.getParent());
|
||||||
if (initializeDBSchema()) {
|
if (initializeDBSchema()) {
|
||||||
updateFileStmt = prepareStatement(
|
updateFileStmt = prepareStatement(
|
||||||
"INSERT OR REPLACE INTO drawable_files (obj_id , path, name, created_time, modified_time, make, model, analyzed) "
|
"INSERT OR REPLACE INTO drawable_files (obj_id , path, name, created_time, modified_time, make, model, analyzed) " //NON-NLS
|
||||||
+ "VALUES (?,?,?,?,?,?,?,?)");
|
+ "VALUES (?,?,?,?,?,?,?,?)"); //NON-NLS
|
||||||
insertFileStmt = prepareStatement(
|
insertFileStmt = prepareStatement(
|
||||||
"INSERT OR IGNORE INTO drawable_files (obj_id , path, name, created_time, modified_time, make, model, analyzed) "
|
"INSERT OR IGNORE INTO drawable_files (obj_id , path, name, created_time, modified_time, make, model, analyzed) " //NON-NLS
|
||||||
+ "VALUES (?,?,?,?,?,?,?,?)");
|
+ "VALUES (?,?,?,?,?,?,?,?)"); //NON-NLS
|
||||||
|
|
||||||
removeFileStmt = prepareStatement("DELETE FROM drawable_files WHERE obj_id = ?");
|
removeFileStmt = prepareStatement("DELETE FROM drawable_files WHERE obj_id = ?"); //NON-NLS
|
||||||
|
|
||||||
pathGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE path = ? ", DrawableAttribute.PATH);
|
pathGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE path = ? ", DrawableAttribute.PATH); //NON-NLS
|
||||||
nameGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE name = ? ", DrawableAttribute.NAME);
|
nameGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE name = ? ", DrawableAttribute.NAME); //NON-NLS
|
||||||
created_timeGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE created_time = ? ", DrawableAttribute.CREATED_TIME);
|
created_timeGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE created_time = ? ", DrawableAttribute.CREATED_TIME); //NON-NLS
|
||||||
modified_timeGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE modified_time = ? ", DrawableAttribute.MODIFIED_TIME);
|
modified_timeGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE modified_time = ? ", DrawableAttribute.MODIFIED_TIME); //NON-NLS
|
||||||
makeGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE make = ? ", DrawableAttribute.MAKE);
|
makeGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE make = ? ", DrawableAttribute.MAKE); //NON-NLS
|
||||||
modelGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE model = ? ", DrawableAttribute.MODEL);
|
modelGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE model = ? ", DrawableAttribute.MODEL); //NON-NLS
|
||||||
analyzedGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE analyzed = ?", DrawableAttribute.ANALYZED);
|
analyzedGroupStmt = prepareStatement("SELECT obj_id , analyzed FROM drawable_files WHERE analyzed = ?", DrawableAttribute.ANALYZED); //NON-NLS
|
||||||
hashSetGroupStmt = prepareStatement("SELECT drawable_files.obj_id AS obj_id, analyzed FROM drawable_files , hash_sets , hash_set_hits WHERE drawable_files.obj_id = hash_set_hits.obj_id AND hash_sets.hash_set_id = hash_set_hits.hash_set_id AND hash_sets.hash_set_name = ?", DrawableAttribute.HASHSET);
|
hashSetGroupStmt = prepareStatement("SELECT drawable_files.obj_id AS obj_id, analyzed FROM drawable_files , hash_sets , hash_set_hits WHERE drawable_files.obj_id = hash_set_hits.obj_id AND hash_sets.hash_set_id = hash_set_hits.hash_set_id AND hash_sets.hash_set_name = ?", DrawableAttribute.HASHSET); //NON-NLS
|
||||||
|
|
||||||
updateGroupStmt = prepareStatement("insert or replace into groups (seen, value, attribute) values( ?, ? , ?)");
|
updateGroupStmt = prepareStatement("insert or replace into groups (seen, value, attribute) values( ?, ? , ?)"); //NON-NLS
|
||||||
insertGroupStmt = prepareStatement("insert or ignore into groups (value, attribute) values (?,?)");
|
insertGroupStmt = prepareStatement("insert or ignore into groups (value, attribute) values (?,?)"); //NON-NLS
|
||||||
|
|
||||||
groupSeenQueryStmt = prepareStatement("SELECT seen FROM groups WHERE value = ? AND attribute = ?");
|
groupSeenQueryStmt = prepareStatement("SELECT seen FROM groups WHERE value = ? AND attribute = ?"); //NON-NLS
|
||||||
|
|
||||||
selectHashSetNamesStmt = prepareStatement("SELECT DISTINCT hash_set_name FROM hash_sets");
|
selectHashSetNamesStmt = prepareStatement("SELECT DISTINCT hash_set_name FROM hash_sets"); //NON-NLS
|
||||||
insertHashSetStmt = prepareStatement("INSERT OR IGNORE INTO hash_sets (hash_set_name) VALUES (?)");
|
insertHashSetStmt = prepareStatement("INSERT OR IGNORE INTO hash_sets (hash_set_name) VALUES (?)"); //NON-NLS
|
||||||
selectHashSetStmt = prepareStatement("SELECT hash_set_id FROM hash_sets WHERE hash_set_name = ?");
|
selectHashSetStmt = prepareStatement("SELECT hash_set_id FROM hash_sets WHERE hash_set_name = ?"); //NON-NLS
|
||||||
|
|
||||||
insertHashHitStmt = prepareStatement("INSERT OR IGNORE INTO hash_set_hits (hash_set_id, obj_id) VALUES (?,?)");
|
insertHashHitStmt = prepareStatement("INSERT OR IGNORE INTO hash_set_hits (hash_set_id, obj_id) VALUES (?,?)"); //NON-NLS
|
||||||
|
|
||||||
for (Category cat : Category.values()) {
|
for (Category cat : Category.values()) {
|
||||||
insertGroup(cat.getDisplayName(), DrawableAttribute.CATEGORY);
|
insertGroup(cat.getDisplayName(), DrawableAttribute.CATEGORY);
|
||||||
@ -289,12 +289,12 @@ public final class DrawableDB {
|
|||||||
public static DrawableDB getDrawableDB(Path dbPath, ImageGalleryController controller) {
|
public static DrawableDB getDrawableDB(Path dbPath, ImageGalleryController controller) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new DrawableDB(dbPath.resolve("drawable.db"), controller);
|
return new DrawableDB(dbPath.resolve("drawable.db"), controller); //NON-NLS
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "sql error creating database connection", ex);
|
LOGGER.log(Level.SEVERE, "sql error creating database connection", ex); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
} catch (ExceptionInInitializerError | IOException ex) {
|
} catch (ExceptionInInitializerError | IOException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "error creating database connection", ex);
|
LOGGER.log(Level.SEVERE, "error creating database connection", ex); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,33 +304,33 @@ public final class DrawableDB {
|
|||||||
//this should match Sleuthkit db setupt
|
//this should match Sleuthkit db setupt
|
||||||
try (Statement statement = con.createStatement()) {
|
try (Statement statement = con.createStatement()) {
|
||||||
//reduce i/o operations, we have no OS crash recovery anyway
|
//reduce i/o operations, we have no OS crash recovery anyway
|
||||||
statement.execute("PRAGMA synchronous = OFF;");
|
statement.execute("PRAGMA synchronous = OFF;"); //NON-NLS
|
||||||
//allow to query while in transaction - no need read locks
|
//allow to query while in transaction - no need read locks
|
||||||
statement.execute("PRAGMA read_uncommitted = True;");
|
statement.execute("PRAGMA read_uncommitted = True;"); //NON-NLS
|
||||||
|
|
||||||
//TODO: do we need this?
|
//TODO: do we need this?
|
||||||
statement.execute("PRAGMA foreign_keys = ON");
|
statement.execute("PRAGMA foreign_keys = ON"); //NON-NLS
|
||||||
|
|
||||||
//TODO: test this
|
//TODO: test this
|
||||||
statement.execute("PRAGMA journal_mode = MEMORY");
|
statement.execute("PRAGMA journal_mode = MEMORY"); //NON-NLS
|
||||||
//
|
//
|
||||||
//we don't use this feature, so turn it off for minimal speed up on queries
|
//we don't use this feature, so turn it off for minimal speed up on queries
|
||||||
//this is deprecated and not recomended
|
//this is deprecated and not recomended
|
||||||
statement.execute("PRAGMA count_changes = OFF;");
|
statement.execute("PRAGMA count_changes = OFF;"); //NON-NLS
|
||||||
//this made a big difference to query speed
|
//this made a big difference to query speed
|
||||||
statement.execute("PRAGMA temp_store = MEMORY");
|
statement.execute("PRAGMA temp_store = MEMORY"); //NON-NLS
|
||||||
//this made a modest improvement in query speeds
|
//this made a modest improvement in query speeds
|
||||||
statement.execute("PRAGMA cache_size = 50000");
|
statement.execute("PRAGMA cache_size = 50000"); //NON-NLS
|
||||||
//we never delete anything so...
|
//we never delete anything so...
|
||||||
statement.execute("PRAGMA auto_vacuum = 0");
|
statement.execute("PRAGMA auto_vacuum = 0"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode",
|
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode", //NON-NLS
|
||||||
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
|
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
|
||||||
? "native" : "pure-java"));
|
? "native" : "pure-java")); //NON-NLS
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
LOGGER.log(Level.WARNING, "exception while checking sqlite-jdbc version and mode", exception);
|
LOGGER.log(Level.WARNING, "exception while checking sqlite-jdbc version and mode", exception); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -349,92 +349,92 @@ public final class DrawableDB {
|
|||||||
setPragmas();
|
setPragmas();
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "problem accessing database", ex);
|
LOGGER.log(Level.SEVERE, "problem accessing database", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists drawable_files "
|
String sql = "CREATE TABLE if not exists drawable_files " //NON-NLS
|
||||||
+ "( obj_id INTEGER PRIMARY KEY, "
|
+ "( obj_id INTEGER PRIMARY KEY, " //NON-NLS
|
||||||
+ " path VARCHAR(255), "
|
+ " path VARCHAR(255), " //NON-NLS
|
||||||
+ " name VARCHAR(255), "
|
+ " name VARCHAR(255), " //NON-NLS
|
||||||
+ " created_time integer, "
|
+ " created_time integer, " //NON-NLS
|
||||||
+ " modified_time integer, "
|
+ " modified_time integer, " //NON-NLS
|
||||||
+ " make VARCHAR(255), "
|
+ " make VARCHAR(255), " //NON-NLS
|
||||||
+ " model VARCHAR(255), "
|
+ " model VARCHAR(255), " //NON-NLS
|
||||||
+ " analyzed integer DEFAULT 0)";
|
+ " analyzed integer DEFAULT 0)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "problem creating drawable_files table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating drawable_files table", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists groups "
|
String sql = "CREATE TABLE if not exists groups " //NON-NLS
|
||||||
+ "(group_id INTEGER PRIMARY KEY, "
|
+ "(group_id INTEGER PRIMARY KEY, " //NON-NLS
|
||||||
+ " value VARCHAR(255) not null, "
|
+ " value VARCHAR(255) not null, " //NON-NLS
|
||||||
+ " attribute VARCHAR(255) not null, "
|
+ " attribute VARCHAR(255) not null, " //NON-NLS
|
||||||
+ " seen integer DEFAULT 0, "
|
+ " seen integer DEFAULT 0, " //NON-NLS
|
||||||
+ " UNIQUE(value, attribute) )";
|
+ " UNIQUE(value, attribute) )"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "problem creating groups table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating groups table", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists hash_sets "
|
String sql = "CREATE TABLE if not exists hash_sets " //NON-NLS
|
||||||
+ "( hash_set_id INTEGER primary key,"
|
+ "( hash_set_id INTEGER primary key," //NON-NLS
|
||||||
+ " hash_set_name VARCHAR(255) UNIQUE NOT NULL)";
|
+ " hash_set_name VARCHAR(255) UNIQUE NOT NULL)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "problem creating hash_sets table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating hash_sets table", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE TABLE if not exists hash_set_hits "
|
String sql = "CREATE TABLE if not exists hash_set_hits " //NON-NLS
|
||||||
+ "(hash_set_id INTEGER REFERENCES hash_sets(hash_set_id) not null, "
|
+ "(hash_set_id INTEGER REFERENCES hash_sets(hash_set_id) not null, " //NON-NLS
|
||||||
+ " obj_id INTEGER REFERENCES drawable_files(obj_id) not null, "
|
+ " obj_id INTEGER REFERENCES drawable_files(obj_id) not null, " //NON-NLS
|
||||||
+ " PRIMARY KEY (hash_set_id, obj_id))";
|
+ " PRIMARY KEY (hash_set_id, obj_id))"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "problem creating hash_set_hits table", ex);
|
LOGGER.log(Level.SEVERE, "problem creating hash_set_hits table", ex); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists path_idx ON drawable_files(path)";
|
String sql = "CREATE INDEX if not exists path_idx ON drawable_files(path)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating path_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating path_idx", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists name_idx ON drawable_files(name)";
|
String sql = "CREATE INDEX if not exists name_idx ON drawable_files(name)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating name_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating name_idx", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists make_idx ON drawable_files(make)";
|
String sql = "CREATE INDEX if not exists make_idx ON drawable_files(make)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating make_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating make_idx", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists model_idx ON drawable_files(model)";
|
String sql = "CREATE INDEX if not exists model_idx ON drawable_files(model)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating model_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating model_idx", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Statement stmt = con.createStatement()) {
|
try (Statement stmt = con.createStatement()) {
|
||||||
String sql = "CREATE INDEX if not exists analyzed_idx ON drawable_files(analyzed)";
|
String sql = "CREATE INDEX if not exists analyzed_idx ON drawable_files(analyzed)"; //NON-NLS
|
||||||
stmt.execute(sql);
|
stmt.execute(sql);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem creating analyzed_idx", ex);
|
LOGGER.log(Level.WARNING, "problem creating analyzed_idx", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -455,7 +455,7 @@ public final class DrawableDB {
|
|||||||
closeStatements();
|
closeStatements();
|
||||||
con.close();
|
con.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to close connection to drawable.db", ex);
|
LOGGER.log(Level.WARNING, "Failed to close connection to drawable.db", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
con = null;
|
con = null;
|
||||||
@ -464,10 +464,10 @@ public final class DrawableDB {
|
|||||||
public void openDBCon() {
|
public void openDBCon() {
|
||||||
try {
|
try {
|
||||||
if (con == null || con.isClosed()) {
|
if (con == null || con.isClosed()) {
|
||||||
con = DriverManager.getConnection("jdbc:sqlite:" + dbPath.toString());
|
con = DriverManager.getConnection("jdbc:sqlite:" + dbPath.toString()); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to open connection to drawable.db", ex);
|
LOGGER.log(Level.WARNING, "Failed to open connection to drawable.db", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +518,7 @@ public final class DrawableDB {
|
|||||||
names.add(rs.getString(HASH_SET_NAME));
|
names.add(rs.getString(HASH_SET_NAME));
|
||||||
}
|
}
|
||||||
} catch (SQLException sQLException) {
|
} catch (SQLException sQLException) {
|
||||||
LOGGER.log(Level.WARNING, "failed to get hash set names", sQLException);
|
LOGGER.log(Level.WARNING, "failed to get hash set names", sQLException); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -533,11 +533,11 @@ public final class DrawableDB {
|
|||||||
groupSeenQueryStmt.setString(2, groupKey.getAttribute().attrName.toString());
|
groupSeenQueryStmt.setString(2, groupKey.getAttribute().attrName.toString());
|
||||||
try (ResultSet rs = groupSeenQueryStmt.executeQuery()) {
|
try (ResultSet rs = groupSeenQueryStmt.executeQuery()) {
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
return rs.getBoolean("seen");
|
return rs.getBoolean("seen"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
String msg = String.format("Failed to get is group seen for group key %s", groupKey.getValueDisplayName());
|
String msg = String.format("Failed to get is group seen for group key %s", groupKey.getValueDisplayName()); //NON-NLS
|
||||||
LOGGER.log(Level.WARNING, msg, ex);
|
LOGGER.log(Level.WARNING, msg, ex);
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
@ -555,7 +555,7 @@ public final class DrawableDB {
|
|||||||
updateGroupStmt.setString(3, gk.getAttribute().attrName.toString());
|
updateGroupStmt.setString(3, gk.getAttribute().attrName.toString());
|
||||||
updateGroupStmt.execute();
|
updateGroupStmt.execute();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error marking group as seen", ex);
|
LOGGER.log(Level.SEVERE, "Error marking group as seen", ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbWriteUnlock();
|
dbWriteUnlock();
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ public final class DrawableDB {
|
|||||||
selectHashSetStmt.setString(1, name);
|
selectHashSetStmt.setString(1, name);
|
||||||
try (ResultSet rs = selectHashSetStmt.executeQuery()) {
|
try (ResultSet rs = selectHashSetStmt.executeQuery()) {
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
int hashsetID = rs.getInt("hash_set_id");
|
int hashsetID = rs.getInt("hash_set_id"); //NON-NLS
|
||||||
//"insert or ignore into hash_set_hits (hash_set_id, obj_id) values (?,?)";
|
//"insert or ignore into hash_set_hits (hash_set_id, obj_id) values (?,?)";
|
||||||
insertHashHitStmt.setInt(1, hashsetID);
|
insertHashHitStmt.setInt(1, hashsetID);
|
||||||
insertHashHitStmt.setLong(2, f.getId());
|
insertHashHitStmt.setLong(2, f.getId());
|
||||||
@ -633,7 +633,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "failed to insert/update hash hits for file" + f.getName(), ex);
|
LOGGER.log(Level.SEVERE, "failed to insert/update hash hits for file" + f.getName(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
//and update all groups this file is in
|
//and update all groups this file is in
|
||||||
@ -650,7 +650,7 @@ public final class DrawableDB {
|
|||||||
// This is one of the places where we get an error if the case is closed during processing,
|
// This is one of the places where we get an error if the case is closed during processing,
|
||||||
// which doesn't need to be reported here.
|
// which doesn't need to be reported here.
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
LOGGER.log(Level.SEVERE, "failed to insert/update file" + f.getName(), ex);
|
LOGGER.log(Level.SEVERE, "failed to insert/update file" + f.getName(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
@ -676,12 +676,12 @@ public final class DrawableDB {
|
|||||||
public Boolean isFileAnalyzed(long fileId) {
|
public Boolean isFileAnalyzed(long fileId) {
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try (Statement stmt = con.createStatement();
|
try (Statement stmt = con.createStatement();
|
||||||
ResultSet analyzedQuery = stmt.executeQuery("SELECT analyzed FROM drawable_files WHERE obj_id = " + fileId)) {
|
ResultSet analyzedQuery = stmt.executeQuery("SELECT analyzed FROM drawable_files WHERE obj_id = " + fileId)) { //NON-NLS
|
||||||
while (analyzedQuery.next()) {
|
while (analyzedQuery.next()) {
|
||||||
return analyzedQuery.getBoolean(ANALYZED);
|
return analyzedQuery.getBoolean(ANALYZED);
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
String msg = String.format("Failed to determine if file %s is finalized", String.valueOf(fileId));
|
String msg = String.format("Failed to determine if file %s is finalized", String.valueOf(fileId)); //NON-NLS
|
||||||
LOGGER.log(Level.WARNING, msg, ex);
|
LOGGER.log(Level.WARNING, msg, ex);
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
@ -695,12 +695,12 @@ public final class DrawableDB {
|
|||||||
dbReadLock();
|
dbReadLock();
|
||||||
try (Statement stmt = con.createStatement();
|
try (Statement stmt = con.createStatement();
|
||||||
//Can't make this a preprared statement because of the IN ( ... )
|
//Can't make this a preprared statement because of the IN ( ... )
|
||||||
ResultSet analyzedQuery = stmt.executeQuery("SELECT COUNT(analyzed) AS analyzed FROM drawable_files WHERE analyzed = 1 AND obj_id IN (" + StringUtils.join(fileIds, ", ") + ")")) {
|
ResultSet analyzedQuery = stmt.executeQuery("SELECT COUNT(analyzed) AS analyzed FROM drawable_files WHERE analyzed = 1 AND obj_id IN (" + StringUtils.join(fileIds, ", ") + ")")) { //NON-NLS
|
||||||
while (analyzedQuery.next()) {
|
while (analyzedQuery.next()) {
|
||||||
return analyzedQuery.getInt(ANALYZED) == fileIds.size();
|
return analyzedQuery.getInt(ANALYZED) == fileIds.size();
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", ex);
|
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -717,7 +717,7 @@ public final class DrawableDB {
|
|||||||
// In testing, this method appears to be a lot faster than doing one large select statement
|
// In testing, this method appears to be a lot faster than doing one large select statement
|
||||||
for (Long fileID : fileIDsInGroup) {
|
for (Long fileID : fileIDsInGroup) {
|
||||||
Statement stmt = con.createStatement();
|
Statement stmt = con.createStatement();
|
||||||
ResultSet analyzedQuery = stmt.executeQuery("SELECT analyzed FROM drawable_files WHERE obj_id = " + fileID);
|
ResultSet analyzedQuery = stmt.executeQuery("SELECT analyzed FROM drawable_files WHERE obj_id = " + fileID); //NON-NLS
|
||||||
while (analyzedQuery.next()) {
|
while (analyzedQuery.next()) {
|
||||||
if (analyzedQuery.getInt(ANALYZED) == 0) {
|
if (analyzedQuery.getInt(ANALYZED) == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -727,10 +727,10 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", ex);
|
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", tskCoreException);
|
LOGGER.log(Level.WARNING, "problem counting analyzed files: ", tskCoreException); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -756,7 +756,7 @@ public final class DrawableDB {
|
|||||||
dbReadLock();
|
dbReadLock();
|
||||||
try {
|
try {
|
||||||
statement = con.createStatement();
|
statement = con.createStatement();
|
||||||
rs = statement.executeQuery("SELECT obj_id FROM drawable_files WHERE " + sqlWhereClause);
|
rs = statement.executeQuery("SELECT obj_id FROM drawable_files WHERE " + sqlWhereClause); //NON-NLS
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
ret.add(rs.getLong(1));
|
ret.add(rs.getLong(1));
|
||||||
}
|
}
|
||||||
@ -767,14 +767,14 @@ public final class DrawableDB {
|
|||||||
try {
|
try {
|
||||||
rs.close();
|
rs.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing result set after executing findAllFileIdsWhere", ex);
|
LOGGER.log(Level.SEVERE, "Error closing result set after executing findAllFileIdsWhere", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (statement != null) {
|
if (statement != null) {
|
||||||
try {
|
try {
|
||||||
statement.close();
|
statement.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing statement after executing findAllFileIdsWhere", ex);
|
LOGGER.log(Level.SEVERE, "Error closing statement after executing findAllFileIdsWhere", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
@ -808,14 +808,14 @@ public final class DrawableDB {
|
|||||||
try {
|
try {
|
||||||
rs.close();
|
rs.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing result set after executing countFilesWhere", ex);
|
LOGGER.log(Level.SEVERE, "Error closing result set after executing countFilesWhere", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (statement != null) {
|
if (statement != null) {
|
||||||
try {
|
try {
|
||||||
statement.close();
|
statement.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing statement after executing countFilesWhere", ex);
|
LOGGER.log(Level.SEVERE, "Error closing statement after executing countFilesWhere", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
@ -845,14 +845,14 @@ public final class DrawableDB {
|
|||||||
try {
|
try {
|
||||||
rs.close();
|
rs.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing result set after executing countFiles", ex);
|
LOGGER.log(Level.SEVERE, "Error closing result set after executing countFiles", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (statement != null) {
|
if (statement != null) {
|
||||||
try {
|
try {
|
||||||
statement.close();
|
statement.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing statement after executing countFiles", ex);
|
LOGGER.log(Level.SEVERE, "Error closing statement after executing countFiles", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
@ -883,15 +883,15 @@ public final class DrawableDB {
|
|||||||
default:
|
default:
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
//TODO: convert this to prepared statement
|
//TODO: convert this to prepared statement
|
||||||
StringBuilder query = new StringBuilder("SELECT " + groupBy.attrName.toString() + ", COUNT(*) FROM drawable_files GROUP BY " + groupBy.attrName.toString());
|
StringBuilder query = new StringBuilder("SELECT " + groupBy.attrName.toString() + ", COUNT(*) FROM drawable_files GROUP BY " + groupBy.attrName.toString()); //NON-NLS
|
||||||
|
|
||||||
String orderByClause = "";
|
String orderByClause = "";
|
||||||
switch (sortBy) {
|
switch (sortBy) {
|
||||||
case GROUP_BY_VALUE:
|
case GROUP_BY_VALUE:
|
||||||
orderByClause = " ORDER BY " + groupBy.attrName.toString();
|
orderByClause = " ORDER BY " + groupBy.attrName.toString(); //NON-NLS
|
||||||
break;
|
break;
|
||||||
case FILE_COUNT:
|
case FILE_COUNT:
|
||||||
orderByClause = " ORDER BY COUNT(*)";
|
orderByClause = " ORDER BY COUNT(*)"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
// case PRIORITY:
|
// case PRIORITY:
|
||||||
@ -905,10 +905,10 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
switch (sortOrder) {
|
switch (sortOrder) {
|
||||||
case DESCENDING:
|
case DESCENDING:
|
||||||
sortOrderClause = " DESC";
|
sortOrderClause = " DESC"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
case ASCENDING:
|
case ASCENDING:
|
||||||
sortOrderClause = " ASC";
|
sortOrderClause = " ASC"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
orderByClause = "";
|
orderByClause = "";
|
||||||
@ -930,7 +930,7 @@ public final class DrawableDB {
|
|||||||
vals.add(value);
|
vals.add(value);
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Unable to get values for attribute", ex);
|
LOGGER.log(Level.WARNING, "Unable to get values for attribute", ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -951,7 +951,7 @@ public final class DrawableDB {
|
|||||||
} catch (SQLException sQLException) {
|
} catch (SQLException sQLException) {
|
||||||
// Don't need to report it if the case was closed
|
// Don't need to report it if the case was closed
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
LOGGER.log(Level.SEVERE, "Unable to insert group", sQLException);
|
LOGGER.log(Level.SEVERE, "Unable to insert group", sQLException); //NON-NLS
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
dbWriteUnlock();
|
dbWriteUnlock();
|
||||||
@ -972,7 +972,7 @@ public final class DrawableDB {
|
|||||||
AbstractFile f = tskCase.getAbstractFileById(id);
|
AbstractFile f = tskCase.getAbstractFileById(id);
|
||||||
return DrawableFile.create(f, analyzed, isVideoFile(f));
|
return DrawableFile.create(f, analyzed, isVideoFile(f));
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "there is no case open; failed to load file with id: " + id, ex);
|
LOGGER.log(Level.SEVERE, "there is no case open; failed to load file with id: " + id, ex); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -991,7 +991,7 @@ public final class DrawableDB {
|
|||||||
return DrawableFile.create(f,
|
return DrawableFile.create(f,
|
||||||
areFilesAnalyzed(Collections.singleton(id)), isVideoFile(f));
|
areFilesAnalyzed(Collections.singleton(id)), isVideoFile(f));
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "there is no case open; failed to load file with id: {0}", id);
|
LOGGER.log(Level.SEVERE, "there is no case open; failed to load file with id: {0}", id); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1020,7 +1020,7 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "failed to get file for group:" + groupKey.getAttribute() + " == " + groupKey.getValue(), ex);
|
LOGGER.log(Level.WARNING, "failed to get file for group:" + groupKey.getAttribute() + " == " + groupKey.getValue(), ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -1042,14 +1042,14 @@ public final class DrawableDB {
|
|||||||
public int countAllFiles() {
|
public int countAllFiles() {
|
||||||
int result = -1;
|
int result = -1;
|
||||||
dbReadLock();
|
dbReadLock();
|
||||||
try (ResultSet rs = con.createStatement().executeQuery("SELECT COUNT(*) AS COUNT FROM drawable_files")) {
|
try (ResultSet rs = con.createStatement().executeQuery("SELECT COUNT(*) AS COUNT FROM drawable_files")) { //NON-NLS
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
|
|
||||||
result = rs.getInt("COUNT");
|
result = rs.getInt("COUNT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error accessing SQLite database");
|
LOGGER.log(Level.SEVERE, "Error accessing SQLite database"); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -1081,7 +1081,7 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
//TODO: delete from hash_set_hits table also...
|
//TODO: delete from hash_set_hits table also...
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "failed to delete row for obj_id = " + id, ex);
|
LOGGER.log(Level.WARNING, "failed to delete row for obj_id = " + id, ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbWriteUnlock();
|
dbWriteUnlock();
|
||||||
}
|
}
|
||||||
@ -1093,7 +1093,7 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
public class MultipleTransactionException extends IllegalStateException {
|
public class MultipleTransactionException extends IllegalStateException {
|
||||||
|
|
||||||
private static final String CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO = "cannot have more than one open transaction";
|
private static final String CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO = "cannot have more than one open transaction"; //NON-NLS
|
||||||
|
|
||||||
public MultipleTransactionException() {
|
public MultipleTransactionException() {
|
||||||
super(CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO);
|
super(CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO);
|
||||||
@ -1137,12 +1137,12 @@ public final class DrawableDB {
|
|||||||
dbReadLock();
|
dbReadLock();
|
||||||
try {
|
try {
|
||||||
Statement stmt = con.createStatement();
|
Statement stmt = con.createStatement();
|
||||||
ResultSet analyzedQuery = stmt.executeQuery("select obj_id from drawable_files");
|
ResultSet analyzedQuery = stmt.executeQuery("select obj_id from drawable_files"); //NON-NLS
|
||||||
while (analyzedQuery.next()) {
|
while (analyzedQuery.next()) {
|
||||||
addImageFileToList(analyzedQuery.getLong(OBJ_ID));
|
addImageFileToList(analyzedQuery.getLong(OBJ_ID));
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem loading file IDs: ", ex);
|
LOGGER.log(Level.WARNING, "problem loading file IDs: ", ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
dbReadUnlock();
|
dbReadUnlock();
|
||||||
}
|
}
|
||||||
@ -1194,9 +1194,9 @@ public final class DrawableDB {
|
|||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Case closed while getting files");
|
LOGGER.log(Level.WARNING, "Case closed while getting files"); //NON-NLS
|
||||||
} catch (TskCoreException ex1) {
|
} catch (TskCoreException ex1) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get content tags by tag name.", ex1);
|
LOGGER.log(Level.SEVERE, "Failed to get content tags by tag name.", ex1); //NON-NLS
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1231,15 +1231,15 @@ public final class DrawableDB {
|
|||||||
|
|
||||||
//count the fileids that are in the given list and don't have a non-zero category assigned to them.
|
//count the fileids that are in the given list and don't have a non-zero category assigned to them.
|
||||||
String name =
|
String name =
|
||||||
"SELECT COUNT(obj_id) FROM tsk_files where obj_id IN " + fileIdsList
|
"SELECT COUNT(obj_id) FROM tsk_files where obj_id IN " + fileIdsList //NON-NLS
|
||||||
+ " AND obj_id NOT IN (SELECT obj_id FROM content_tags WHERE content_tags.tag_name_id IN " + catTagNameIDs + ")";
|
+ " AND obj_id NOT IN (SELECT obj_id FROM content_tags WHERE content_tags.tag_name_id IN " + catTagNameIDs + ")"; //NON-NLS
|
||||||
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(name);
|
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(name);
|
||||||
ResultSet resultSet = executeQuery.getResultSet();) {
|
ResultSet resultSet = executeQuery.getResultSet();) {
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
return resultSet.getLong("count(obj_id)");
|
return resultSet.getLong("count(obj_id)"); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (SQLException | TskCoreException ex) {
|
} catch (SQLException | TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error getting category count.", ex);
|
LOGGER.log(Level.SEVERE, "Error getting category count.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1274,7 +1274,7 @@ public final class DrawableDB {
|
|||||||
con.setAutoCommit(false);
|
con.setAutoCommit(false);
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "failed to set auto-commit to to false", ex);
|
LOGGER.log(Level.SEVERE, "failed to set auto-commit to to false", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1285,7 +1285,7 @@ public final class DrawableDB {
|
|||||||
con.rollback();
|
con.rollback();
|
||||||
updatedFiles.clear();
|
updatedFiles.clear();
|
||||||
} catch (SQLException ex1) {
|
} catch (SQLException ex1) {
|
||||||
LOGGER.log(Level.SEVERE, "Exception while attempting to rollback!!", ex1);
|
LOGGER.log(Level.SEVERE, "Exception while attempting to rollback!!", ex1); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
@ -1307,9 +1307,9 @@ public final class DrawableDB {
|
|||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
LOGGER.log(Level.SEVERE, "Error commiting drawable.db.", ex);
|
LOGGER.log(Level.SEVERE, "Error commiting drawable.db.", ex); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.WARNING, "Error commiting drawable.db - case is closed.");
|
LOGGER.log(Level.WARNING, "Error commiting drawable.db - case is closed."); //NON-NLS
|
||||||
}
|
}
|
||||||
rollback();
|
rollback();
|
||||||
}
|
}
|
||||||
@ -1322,9 +1322,9 @@ public final class DrawableDB {
|
|||||||
con.setAutoCommit(true);
|
con.setAutoCommit(true);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
LOGGER.log(Level.SEVERE, "Error setting auto-commit to true.", ex);
|
LOGGER.log(Level.SEVERE, "Error setting auto-commit to true.", ex); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.SEVERE, "Error setting auto-commit to true - case is closed");
|
LOGGER.log(Level.SEVERE, "Error setting auto-commit to true - case is closed"); //NON-NLS
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closed = true;
|
closed = true;
|
||||||
|
@ -186,9 +186,9 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
.map(Tag::getName)
|
.map(Tag::getName)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName(), ex);
|
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName(), ex); //NON-NLS
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "there is no case open; failed to look up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName());
|
Logger.getAnonymousLogger().log(Level.WARNING, "there is no case open; failed to look up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName()); //NON-NLS
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up {0}/{1}" + " " + " for {2}", new Object[]{artType.getDisplayName(), attrType.getDisplayName(), getName()});
|
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up {0}/{1}" + " " + " for {2}", new Object[]{artType.getDisplayName(), attrType.getDisplayName(), getName()}); //NON-NLS
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
.orElse(Category.ZERO)
|
.orElse(Category.ZERO)
|
||||||
);
|
);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem looking up category for file " + this.getName() + ex.getLocalizedMessage());
|
LOGGER.log(Level.WARNING, "problem looking up category for file " + this.getName() + ex.getLocalizedMessage()); //NON-NLS
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// We get here many times if the case is closed during ingest, so don't print out a ton of warnings.
|
// We get here many times if the case is closed during ingest, so don't print out a ton of warnings.
|
||||||
}
|
}
|
||||||
@ -333,7 +333,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
drawablePath = StringUtils.removeEnd(getUniquePath(), getName());
|
drawablePath = StringUtils.removeEnd(getUniquePath(), getName());
|
||||||
return drawablePath;
|
return drawablePath;
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "failed to get drawablePath from {0}", getName());
|
LOGGER.log(Level.WARNING, "failed to get drawablePath from {0}", getName()); //NON-NLS
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
try {
|
try {
|
||||||
return getHashSetNames();
|
return getHashSetNames();
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to get hash set names", ex);
|
LOGGER.log(Level.WARNING, "Failed to get hash set names", ex); //NON-NLS
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
return this.getUniquePath();
|
return this.getUniquePath();
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
String contentName = this.getName();
|
String contentName = this.getName();
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NOI18N
|
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NOI18N NON-NLS
|
||||||
return contentName;
|
return contentName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import java.util.logging.Level;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||||
@ -41,11 +42,12 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* Manages Tags, Tagging, and the relationship between Categories and Tags in
|
* Manages Tags, Tagging, and the relationship between Categories and Tags in
|
||||||
* the autopsy Db. delegates some, work to the backing {@link TagsManager}.
|
* the autopsy Db. delegates some, work to the backing {@link TagsManager}.
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"DrawableTagsManager.followUp=Follow Up"})
|
||||||
public class DrawableTagsManager {
|
public class DrawableTagsManager {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(DrawableTagsManager.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(DrawableTagsManager.class.getName());
|
||||||
|
|
||||||
private static final String FOLLOW_UP = "Follow Up";
|
private static final String FOLLOW_UP = Bundle.DrawableTagsManager_followUp();
|
||||||
|
|
||||||
final private Object autopsyTagsManagerLock = new Object();
|
final private Object autopsyTagsManagerLock = new Object();
|
||||||
private TagsManager autopsyTagsManager;
|
private TagsManager autopsyTagsManager;
|
||||||
@ -53,8 +55,8 @@ public class DrawableTagsManager {
|
|||||||
/** Used to distribute {@link TagsChangeEvent}s */
|
/** Used to distribute {@link TagsChangeEvent}s */
|
||||||
private final EventBus tagsEventBus = new AsyncEventBus(
|
private final EventBus tagsEventBus = new AsyncEventBus(
|
||||||
Executors.newSingleThreadExecutor(
|
Executors.newSingleThreadExecutor(
|
||||||
new BasicThreadFactory.Builder().namingPattern("Tags Event Bus").uncaughtExceptionHandler((Thread t, Throwable e) -> {
|
new BasicThreadFactory.Builder().namingPattern("Tags Event Bus").uncaughtExceptionHandler((Thread t, Throwable e) -> { //NON-NLS
|
||||||
LOGGER.log(Level.SEVERE, "uncaught exception in event bus handler", e);
|
LOGGER.log(Level.SEVERE, "uncaught exception in event bus handler", e); //NON-NLS
|
||||||
}).build()
|
}).build()
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ public class DrawableTagsManager {
|
|||||||
.distinct().sorted()
|
.distinct().sorted()
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} catch (TskCoreException | IllegalStateException ex) {
|
} catch (TskCoreException | IllegalStateException ex) {
|
||||||
LOGGER.log(Level.WARNING, "couldn't access case", ex);
|
LOGGER.log(Level.WARNING, "couldn't access case", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@ -183,7 +185,7 @@ public class DrawableTagsManager {
|
|||||||
throw new TskCoreException("tagame exists but wasn't found", ex);
|
throw new TskCoreException("tagame exists but wasn't found", ex);
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Case was closed out from underneath", ex);
|
LOGGER.log(Level.SEVERE, "Case was closed out from underneath", ex); //NON-NLS
|
||||||
throw new TskCoreException("Case was closed out from underneath", ex);
|
throw new TskCoreException("Case was closed out from underneath", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class HashSetManager {
|
|||||||
try {
|
try {
|
||||||
return db.getHashSetsForFile(fileID);
|
return db.getHashSetsForFile(fileID);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(HashSetManager.class.getName()).log(Level.SEVERE, "Failed to get Hash Sets for file", ex);
|
Logger.getLogger(HashSetManager.class.getName()).log(Level.SEVERE, "Failed to get Hash Sets for file", ex); //NON-NLS
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class ImageFile<T extends AbstractFile> extends DrawableFile<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getMessageTemplate(final Exception exception) {
|
String getMessageTemplate(final Exception exception) {
|
||||||
return "Failed to read image {0}: " + exception.toString();
|
return "Failed to read image {0}: " + exception.toString(); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,6 +29,7 @@ import javafx.scene.media.Media;
|
|||||||
import javafx.scene.media.MediaException;
|
import javafx.scene.media.MediaException;
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.VideoUtils;
|
import org.sleuthkit.autopsy.coreutils.VideoUtils;
|
||||||
@ -39,7 +40,7 @@ public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
|
|||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(VideoFile.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(VideoFile.class.getName());
|
||||||
|
|
||||||
private static final Image VIDEO_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png");
|
private static final Image VIDEO_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png"); //NON-NLS
|
||||||
|
|
||||||
VideoFile(T file, Boolean analyzed) {
|
VideoFile(T file, Boolean analyzed) {
|
||||||
super(file, analyzed);
|
super(file, analyzed);
|
||||||
@ -53,7 +54,7 @@ public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getMessageTemplate(final Exception exception) {
|
String getMessageTemplate(final Exception exception) {
|
||||||
return "Failed to get image preview for video {0}: " + exception.toString();
|
return "Failed to get image preview for video {0}: " + exception.toString(); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,6 +64,7 @@ public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
|
|||||||
|
|
||||||
private SoftReference<Media> mediaRef;
|
private SoftReference<Media> mediaRef;
|
||||||
|
|
||||||
|
@NbBundle.Messages({"VideoFile.getMedia.progress=writing temporary file to disk"})
|
||||||
public Media getMedia() throws IOException, MediaException {
|
public Media getMedia() throws IOException, MediaException {
|
||||||
Media media = (mediaRef != null) ? mediaRef.get() : null;
|
Media media = (mediaRef != null) ? mediaRef.get() : null;
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
|
|||||||
|
|
||||||
if (cacheFile.exists() == false || cacheFile.length() < getAbstractFile().getSize()) {
|
if (cacheFile.exists() == false || cacheFile.length() < getAbstractFile().getSize()) {
|
||||||
Files.createParentDirs(cacheFile);
|
Files.createParentDirs(cacheFile);
|
||||||
ProgressHandle progressHandle = ProgressHandleFactory.createHandle("writing temporary file to disk");
|
ProgressHandle progressHandle = ProgressHandleFactory.createHandle(Bundle.VideoFile_getMedia_progress());
|
||||||
progressHandle.start(100);
|
progressHandle.start(100);
|
||||||
ContentUtils.writeToFile(this.getAbstractFile(), cacheFile, progressHandle, null, true);
|
ContentUtils.writeToFile(this.getAbstractFile(), cacheFile, progressHandle, null, true);
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
|
@ -126,7 +126,7 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
|
|||||||
.filter(Boolean::booleanValue)
|
.filter(Boolean::booleanValue)
|
||||||
.count());
|
.count());
|
||||||
} catch (IllegalStateException | NullPointerException ex) {
|
} catch (IllegalStateException | NullPointerException ex) {
|
||||||
LOGGER.log(Level.WARNING, "could not access case during getFilesWithHashSetHitsCount()");
|
LOGGER.log(Level.WARNING, "could not access case during getFilesWithHashSetHitsCount()"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
|
|||||||
uncatCount.set(ImageGalleryController.getDefault().getDatabase().getCategoryCount(Category.ZERO, fileIDs));
|
uncatCount.set(ImageGalleryController.getDefault().getDatabase().getCategoryCount(Category.ZERO, fileIDs));
|
||||||
|
|
||||||
} catch (IllegalStateException | NullPointerException ex) {
|
} catch (IllegalStateException | NullPointerException ex) {
|
||||||
LOGGER.log(Level.WARNING, "could not access case during getFilesWithHashSetHitsCount()");
|
LOGGER.log(Level.WARNING, "could not access case during getFilesWithHashSetHitsCount()"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Grouping{ keyProp=" + groupKey + '}';
|
return "Grouping{ keyProp=" + groupKey + '}'; //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,7 +57,7 @@ public class GroupKey<T extends Comparable<T>> implements Comparable<GroupKey<T>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GroupKey: " + getAttribute().attrName + " = " + getValue();
|
return "GroupKey: " + getAttribute().attrName + " = " + getValue(); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,6 +62,7 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
|||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||||
import org.openide.util.Exceptions;
|
import org.openide.util.Exceptions;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||||
@ -195,10 +196,10 @@ public class GroupManager {
|
|||||||
DrawableFile<?> file = db.getFileFromID(fileID);
|
DrawableFile<?> file = db.getFileFromID(fileID);
|
||||||
return getGroupKeysForFile(file);
|
return getGroupKeysForFile(file);
|
||||||
} else {
|
} else {
|
||||||
Logger.getLogger(GroupManager.class.getName()).log(Level.WARNING, "Failed to load file with id: {0} from database. There is no database assigned.", fileID);
|
Logger.getLogger(GroupManager.class.getName()).log(Level.WARNING, "Failed to load file with id: {0} from database. There is no database assigned.", fileID); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(GroupManager.class.getName()).log(Level.SEVERE, "failed to load file with id: " + fileID + " from database", ex);
|
Logger.getLogger(GroupManager.class.getName()).log(Level.SEVERE, "failed to load file with id: " + fileID + " from database", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
@ -347,11 +348,11 @@ public class GroupManager {
|
|||||||
break;
|
break;
|
||||||
case MIME_TYPE:
|
case MIME_TYPE:
|
||||||
HashSet<String> types = new HashSet<>();
|
HashSet<String> types = new HashSet<>();
|
||||||
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery("select group_concat(obj_id), mime_type from tsk_files group by mime_type ");
|
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery("select group_concat(obj_id), mime_type from tsk_files group by mime_type "); //NON-NLS
|
||||||
ResultSet resultSet = executeQuery.getResultSet();) {
|
ResultSet resultSet = executeQuery.getResultSet();) {
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
final String mimeType = resultSet.getString("mime_type");
|
final String mimeType = resultSet.getString("mime_type"); //NON-NLS
|
||||||
String objIds = resultSet.getString("group_concat(obj_id)");
|
String objIds = resultSet.getString("group_concat(obj_id)"); //NON-NLS
|
||||||
|
|
||||||
Pattern.compile(",").splitAsStream(objIds)
|
Pattern.compile(",").splitAsStream(objIds)
|
||||||
.map(Long::valueOf)
|
.map(Long::valueOf)
|
||||||
@ -370,7 +371,7 @@ public class GroupManager {
|
|||||||
|
|
||||||
return values;
|
return values;
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "TSK error getting list of type {0}", groupBy.getDisplayName());
|
LOGGER.log(Level.WARNING, "TSK error getting list of type {0}", groupBy.getDisplayName()); //NON-NLS
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +417,7 @@ public class GroupManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.findAllFileIdsWhere("obj_id NOT IN (" + StringUtils.join(files, ',') + ")");
|
return db.findAllFileIdsWhere("obj_id NOT IN (" + StringUtils.join(files, ',') + ")"); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
List<ContentTag> contentTags = tagsManager.getContentTagsByTagName(tagsManager.getTagName(category));
|
List<ContentTag> contentTags = tagsManager.getContentTagsByTagName(tagsManager.getTagName(category));
|
||||||
@ -428,7 +429,7 @@ public class GroupManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "TSK error getting files in Category:" + category.getDisplayName(), ex);
|
LOGGER.log(Level.WARNING, "TSK error getting files in Category:" + category.getDisplayName(), ex); //NON-NLS
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,7 +445,7 @@ public class GroupManager {
|
|||||||
}
|
}
|
||||||
return files;
|
return files;
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "TSK error getting files with Tag:" + tagName.getDisplayName(), ex);
|
LOGGER.log(Level.WARNING, "TSK error getting files with Tag:" + tagName.getDisplayName(), ex); //NON-NLS
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +532,7 @@ public class GroupManager {
|
|||||||
/**
|
/**
|
||||||
* an executor to submit async ui related background tasks to.
|
* an executor to submit async ui related background tasks to.
|
||||||
*/
|
*/
|
||||||
final ExecutorService regroupExecutor = Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder().namingPattern("ui task -%d").build());
|
final ExecutorService regroupExecutor = Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder().namingPattern("ui task -%d").build()); //NON-NLS
|
||||||
|
|
||||||
public ReadOnlyDoubleProperty regroupProgress() {
|
public ReadOnlyDoubleProperty regroupProgress() {
|
||||||
return regroupProgress.getReadOnlyProperty();
|
return regroupProgress.getReadOnlyProperty();
|
||||||
@ -682,7 +683,7 @@ public class GroupManager {
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "failed to get files for group: " + groupKey.getAttribute().attrName.toString() + " = " + groupKey.getValue(), ex);
|
LOGGER.log(Level.SEVERE, "failed to get files for group: " + groupKey.getAttribute().attrName.toString() + " = " + groupKey.getValue(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,13 +694,13 @@ public class GroupManager {
|
|||||||
|
|
||||||
HashSet<Long> hashSet = new HashSet<>();
|
HashSet<Long> hashSet = new HashSet<>();
|
||||||
String query = (null == mimeType)
|
String query = (null == mimeType)
|
||||||
? "SELECT obj_id FROM tsk_files WHERE mime_type IS NULL"
|
? "SELECT obj_id FROM tsk_files WHERE mime_type IS NULL" //NON-NLS
|
||||||
: "SELECT obj_id FROM tsk_files WHERE mime_type = '" + mimeType + "'";
|
: "SELECT obj_id FROM tsk_files WHERE mime_type = '" + mimeType + "'"; //NON-NLS
|
||||||
|
|
||||||
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(query);
|
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(query);
|
||||||
ResultSet resultSet = executeQuery.getResultSet();) {
|
ResultSet resultSet = executeQuery.getResultSet();) {
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
final long fileID = resultSet.getLong("obj_id");
|
final long fileID = resultSet.getLong("obj_id"); //NON-NLS
|
||||||
if (db.isInDB(fileID)) {
|
if (db.isInDB(fileID)) {
|
||||||
hashSet.add(fileID);
|
hashSet.add(fileID);
|
||||||
}
|
}
|
||||||
@ -717,6 +718,13 @@ public class GroupManager {
|
|||||||
* {@link Groupings} for them
|
* {@link Groupings} for them
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@NbBundle.Messages({"# {0} - groupBy attribute Name",
|
||||||
|
"# {1} - sortBy name",
|
||||||
|
"# {2} - sort Order",
|
||||||
|
"ReGroupTask.displayTitle=regrouping files by {0} sorted by {1} in {2} order",
|
||||||
|
"# {0} - groupBy attribute Name",
|
||||||
|
"# {1} - atribute value",
|
||||||
|
"ReGroupTask.progressUpdate=regrouping files by {0} : {1}"})
|
||||||
private class ReGroupTask<A extends Comparable<A>> extends LoggedTask<Void> {
|
private class ReGroupTask<A extends Comparable<A>> extends LoggedTask<Void> {
|
||||||
|
|
||||||
private ProgressHandle groupProgress;
|
private ProgressHandle groupProgress;
|
||||||
@ -728,7 +736,7 @@ public class GroupManager {
|
|||||||
private final SortOrder sortOrder;
|
private final SortOrder sortOrder;
|
||||||
|
|
||||||
public ReGroupTask(DrawableAttribute<A> groupBy, GroupSortBy sortBy, SortOrder sortOrder) {
|
public ReGroupTask(DrawableAttribute<A> groupBy, GroupSortBy sortBy, SortOrder sortOrder) {
|
||||||
super("regrouping files by " + groupBy.attrName.toString() + " sorted by " + sortBy.name() + " in " + sortOrder.toString() + " order", true);
|
super(Bundle.ReGroupTask_displayTitle(groupBy.attrName.toString(), sortBy.name(), sortOrder.toString()), true);
|
||||||
|
|
||||||
this.groupBy = groupBy;
|
this.groupBy = groupBy;
|
||||||
this.sortBy = sortBy;
|
this.sortBy = sortBy;
|
||||||
@ -747,7 +755,7 @@ public class GroupManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
groupProgress = ProgressHandleFactory.createHandle("regrouping files by " + groupBy.attrName.toString() + " sorted by " + sortBy.name() + " in " + sortOrder.toString() + " order", this);
|
groupProgress = ProgressHandleFactory.createHandle(Bundle.ReGroupTask_displayTitle(groupBy.attrName.toString(), sortBy.name(), sortOrder.toString()), this);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
analyzedGroups.clear();
|
analyzedGroups.clear();
|
||||||
unSeenGroups.clear();
|
unSeenGroups.clear();
|
||||||
@ -765,9 +773,9 @@ public class GroupManager {
|
|||||||
return null;//abort
|
return null;//abort
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
updateMessage("regrouping files by " + groupBy.attrName.toString() + " : " + val);
|
updateMessage(Bundle.ReGroupTask_progressUpdate(groupBy.attrName.toString(), val));
|
||||||
updateProgress(p, vals.size());
|
updateProgress(p, vals.size());
|
||||||
groupProgress.progress("regrouping files by " + groupBy.attrName.toString() + " : " + val, p);
|
groupProgress.progress(Bundle.ReGroupTask_progressUpdate(groupBy.attrName.toString(), val), p);
|
||||||
popuplateIfAnalyzed(new GroupKey<A>(groupBy, val), this);
|
popuplateIfAnalyzed(new GroupKey<A>(groupBy, val), this);
|
||||||
}
|
}
|
||||||
Platform.runLater(() -> FXCollections.sort(analyzedGroups, sortBy.getGrpComparator(sortOrder)));
|
Platform.runLater(() -> FXCollections.sort(analyzedGroups, sortBy.getGrpComparator(sortOrder)));
|
||||||
|
@ -27,6 +27,7 @@ import javax.swing.SortOrder;
|
|||||||
import static javax.swing.SortOrder.ASCENDING;
|
import static javax.swing.SortOrder.ASCENDING;
|
||||||
import static javax.swing.SortOrder.DESCENDING;
|
import static javax.swing.SortOrder.DESCENDING;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
||||||
|
|
||||||
@ -35,13 +36,17 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
|||||||
* down in Toolbar as well as each enum value having the stategy
|
* down in Toolbar as well as each enum value having the stategy
|
||||||
* ({@link Comparator}) for sorting the groups
|
* ({@link Comparator}) for sorting the groups
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"GroupSortBy.groupSize=Group Size",
|
||||||
|
"GroupSortBy.groupName=Group Name",
|
||||||
|
"GroupSortBy.none=None",
|
||||||
|
"GroupSortBy.priority=Priority"})
|
||||||
public enum GroupSortBy implements ComparatorProvider {
|
public enum GroupSortBy implements ComparatorProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sort the groups by the number of files in each sort the groups by the
|
* sort the groups by the number of files in each sort the groups by the
|
||||||
* number of files in each
|
* number of files in each
|
||||||
*/
|
*/
|
||||||
FILE_COUNT("Group Size", true, "folder-open-image.png") {
|
FILE_COUNT(Bundle.GroupSortBy_groupSize(), true, "folder-open-image.png") { //NON-NLS
|
||||||
@Override
|
@Override
|
||||||
public Comparator<DrawableGroup> getGrpComparator(final SortOrder sortOrder) {
|
public Comparator<DrawableGroup> getGrpComparator(final SortOrder sortOrder) {
|
||||||
return applySortOrder(sortOrder, Comparator.comparingInt(DrawableGroup::getSize));
|
return applySortOrder(sortOrder, Comparator.comparingInt(DrawableGroup::getSize));
|
||||||
@ -56,7 +61,7 @@ public enum GroupSortBy implements ComparatorProvider {
|
|||||||
* sort the groups by the natural order of the grouping value ( eg group
|
* sort the groups by the natural order of the grouping value ( eg group
|
||||||
* them by path alphabetically )
|
* them by path alphabetically )
|
||||||
*/
|
*/
|
||||||
GROUP_BY_VALUE("Group Name", true, "folder-rename.png") {
|
GROUP_BY_VALUE(Bundle.GroupSortBy_groupName(), true, "folder-rename.png") { //NON-NLS
|
||||||
@Override
|
@Override
|
||||||
public Comparator<DrawableGroup> getGrpComparator(final SortOrder sortOrder) {
|
public Comparator<DrawableGroup> getGrpComparator(final SortOrder sortOrder) {
|
||||||
return applySortOrder(sortOrder, Comparator.comparing(t -> t.getGroupByValueDislpayName()));
|
return applySortOrder(sortOrder, Comparator.comparing(t -> t.getGroupByValueDislpayName()));
|
||||||
@ -71,7 +76,7 @@ public enum GroupSortBy implements ComparatorProvider {
|
|||||||
* don't sort the groups just use what ever order they come in (ingest
|
* don't sort the groups just use what ever order they come in (ingest
|
||||||
* order)
|
* order)
|
||||||
*/
|
*/
|
||||||
NONE("None", false, "prohibition.png") {
|
NONE(Bundle.GroupSortBy_none(), false, "prohibition.png") { //NON-NLS
|
||||||
@Override
|
@Override
|
||||||
public Comparator<DrawableGroup> getGrpComparator(SortOrder sortOrder) {
|
public Comparator<DrawableGroup> getGrpComparator(SortOrder sortOrder) {
|
||||||
return new NoOpComparator<>();
|
return new NoOpComparator<>();
|
||||||
@ -85,7 +90,7 @@ public enum GroupSortBy implements ComparatorProvider {
|
|||||||
/**
|
/**
|
||||||
* sort the groups by some priority metric to be determined and implemented
|
* sort the groups by some priority metric to be determined and implemented
|
||||||
*/
|
*/
|
||||||
PRIORITY("Priority", false, "hashset_hits.png") {
|
PRIORITY(Bundle.GroupSortBy_priority(), false, "hashset_hits.png") { //NON-NLS
|
||||||
@Override
|
@Override
|
||||||
public Comparator<DrawableGroup> getGrpComparator(SortOrder sortOrder) {
|
public Comparator<DrawableGroup> getGrpComparator(SortOrder sortOrder) {
|
||||||
return Comparator.nullsLast(Comparator.comparingDouble(DrawableGroup::getHashHitDensity).thenComparingInt(DrawableGroup::getSize).reversed());
|
return Comparator.nullsLast(Comparator.comparingDouble(DrawableGroup::getHashHitDensity).thenComparingInt(DrawableGroup::getSize).reversed());
|
||||||
@ -128,7 +133,7 @@ public enum GroupSortBy implements ComparatorProvider {
|
|||||||
public Image getIcon() {
|
public Image getIcon() {
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
if (StringUtils.isBlank(imageName) == false) {
|
if (StringUtils.isBlank(imageName) == false) {
|
||||||
this.icon = new Image("org/sleuthkit/autopsy/imagegallery/images/" + imageName, true);
|
this.icon = new Image("org/sleuthkit/autopsy/imagegallery/images/" + imageName, true); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return icon;
|
return icon;
|
||||||
|
@ -53,7 +53,7 @@ public class NoGroupsDialog extends GridPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NoGroupsDialog() {
|
private NoGroupsDialog() {
|
||||||
FXMLConstructor.construct(this, "NoGroupsDialog.fxml");
|
FXMLConstructor.construct(this, "NoGroupsDialog.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
public NoGroupsDialog(String message) {
|
public NoGroupsDialog(String message) {
|
||||||
|
@ -28,6 +28,7 @@ import javafx.scene.control.Label;
|
|||||||
import javafx.scene.control.ProgressBar;
|
import javafx.scene.control.ProgressBar;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +63,10 @@ public class StatusBar extends AnchorPane {
|
|||||||
private ProgressBar bgTaskProgressBar;
|
private ProgressBar bgTaskProgressBar;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@NbBundle.Messages({"# {0} - file update queue size",
|
||||||
|
"StatusBar.fileUpdateTaskLabel.text={0} File Update Tasks",
|
||||||
|
"StatusBar.bgTaskLabel.text=Regrouping",
|
||||||
|
"StatuBar.toolTip=Some data may be out of date. Enable Image Gallery in Tools | Options | Image /Video Gallery , after ingest is complete to update the Image Gallery data."})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert fileTaskProgresBar != null : "fx:id=\"fileTaskProgresBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert fileTaskProgresBar != null : "fx:id=\"fileTaskProgresBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
assert fileUpdateTaskLabel != null : "fx:id=\"fileUpdateTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert fileUpdateTaskLabel != null : "fx:id=\"fileUpdateTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
@ -69,7 +74,7 @@ public class StatusBar extends AnchorPane {
|
|||||||
assert bgTaskLabel != null : "fx:id=\"bgTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert bgTaskLabel != null : "fx:id=\"bgTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
assert bgTaskProgressBar != null : "fx:id=\"bgTaskProgressBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert bgTaskProgressBar != null : "fx:id=\"bgTaskProgressBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
|
|
||||||
fileUpdateTaskLabel.textProperty().bind(controller.getFileUpdateQueueSizeProperty().asString().concat(" File Update Tasks"));//;setText(newSize.toString() + " File Update Tasks");
|
fileUpdateTaskLabel.textProperty().bind(Bundle.StatusBar_fileUpdateTaskLabel_text(controller.getFileUpdateQueueSizeProperty().asString()));//;setText(newSize.toString() + " File Update Tasks");
|
||||||
fileTaskProgresBar.progressProperty().bind(controller.getFileUpdateQueueSizeProperty().negate());
|
fileTaskProgresBar.progressProperty().bind(controller.getFileUpdateQueueSizeProperty().negate());
|
||||||
// controller.getFileUpdateQueueSizeProperty().addListener((ov, oldSize, newSize) -> {
|
// controller.getFileUpdateQueueSizeProperty().addListener((ov, oldSize, newSize) -> {
|
||||||
// Platform.runLater(() -> {
|
// Platform.runLater(() -> {
|
||||||
@ -83,7 +88,7 @@ public class StatusBar extends AnchorPane {
|
|||||||
if(controller.regroupProgress().lessThan(1.0).get()){
|
if(controller.regroupProgress().lessThan(1.0).get()){
|
||||||
// Regrouping in progress
|
// Regrouping in progress
|
||||||
bgTaskProgressBar.progressProperty().setValue(-1.0);
|
bgTaskProgressBar.progressProperty().setValue(-1.0);
|
||||||
bgTaskLabel.setText("Regrouping");
|
bgTaskLabel.setText(Bundle.StatusBar_bgTaskLabel_text());
|
||||||
} else{
|
} else{
|
||||||
// Clear the progress bar
|
// Clear the progress bar
|
||||||
bgTaskProgressBar.progressProperty().setValue(0.0);
|
bgTaskProgressBar.progressProperty().setValue(0.0);
|
||||||
@ -94,14 +99,14 @@ public class StatusBar extends AnchorPane {
|
|||||||
|
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
staleLabel.setTooltip(new Tooltip("Some data may be out of date. Enable Image Gallery in Tools | Options | Image /Video Gallery , after ingest is complete to update the Image Gallery data."));
|
staleLabel.setTooltip(new Tooltip(Bundle.StatuBar_toolTip()));
|
||||||
});
|
});
|
||||||
staleLabel.visibleProperty().bind(controller.stale());
|
staleLabel.visibleProperty().bind(controller.stale());
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusBar(ImageGalleryController controller) {
|
public StatusBar(ImageGalleryController controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StatusBar.fxml"));
|
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StatusBar.fxml")); //NON-NLS
|
||||||
fxmlLoader.setRoot(this);
|
fxmlLoader.setRoot(this);
|
||||||
fxmlLoader.setController(this);
|
fxmlLoader.setController(this);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ public class SummaryTablePane extends AnchorPane {
|
|||||||
|
|
||||||
public SummaryTablePane(ImageGalleryController controller) {
|
public SummaryTablePane(ImageGalleryController controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
FXMLConstructor.construct(this, "SummaryTablePane.fxml");
|
FXMLConstructor.construct(this, "SummaryTablePane.fxml"); //NON-NLS
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ public class Toolbar extends ToolBar {
|
|||||||
try {
|
try {
|
||||||
new TagGroupAction(controller.getTagsManager().getFollowUpTagName(), controller).handle(actionEvent);
|
new TagGroupAction(controller.getTagsManager().getFollowUpTagName(), controller).handle(actionEvent);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Could create follow up tag menu item", ex);
|
LOGGER.log(Level.SEVERE, "Could create follow up tag menu item", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ public class Toolbar extends ToolBar {
|
|||||||
|
|
||||||
private Toolbar(ImageGalleryController controller) {
|
private Toolbar(ImageGalleryController controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
FXMLConstructor.construct(this, "Toolbar.fxml");
|
FXMLConstructor.construct(this, "Toolbar.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,19 +40,20 @@ import javafx.scene.media.MediaView;
|
|||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.VideoFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.VideoFile;
|
||||||
|
|
||||||
public class VideoPlayer extends BorderPane {
|
public class VideoPlayer extends BorderPane {
|
||||||
|
|
||||||
private static final Image VOLUME_HIGH = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume.png");
|
private static final Image VOLUME_HIGH = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume.png"); //NON-NLS
|
||||||
private static final Image VOLUME_LOW = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume-low.png");
|
private static final Image VOLUME_LOW = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume-low.png"); //NON-NLS
|
||||||
private static final Image VOLUME_ZERO = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume-none.png");
|
private static final Image VOLUME_ZERO = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume-none.png"); //NON-NLS
|
||||||
private static final Image VOLUME_MUTE = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume-control-mute.png");
|
private static final Image VOLUME_MUTE = new Image("/org/sleuthkit/autopsy/imagegallery/images/speaker-volume-control-mute.png"); //NON-NLS
|
||||||
|
|
||||||
private static final Image PLAY = new Image("/org/sleuthkit/autopsy/imagegallery/images/media_controls_play_small.png", true);
|
private static final Image PLAY = new Image("/org/sleuthkit/autopsy/imagegallery/images/media_controls_play_small.png", true); //NON-NLS
|
||||||
private static final Image PAUSE = new Image("/org/sleuthkit/autopsy/imagegallery/images/media_controls_pause_small.png", true);
|
private static final Image PAUSE = new Image("/org/sleuthkit/autopsy/imagegallery/images/media_controls_pause_small.png", true); //NON-NLS
|
||||||
|
|
||||||
private final MediaPlayer mp;
|
private final MediaPlayer mp;
|
||||||
|
|
||||||
@ -106,6 +107,8 @@ public class VideoPlayer extends BorderPane {
|
|||||||
private final VideoFile<?> file;
|
private final VideoFile<?> file;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@NbBundle.Messages({"# {0} - exception type",
|
||||||
|
"VideoPlayer.errNotice={0}\nSee the logs for details."})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert controlButton != null : "fx:id=\"controlButton\" was not injected: check your FXML file 'MediaControl.fxml'.";
|
assert controlButton != null : "fx:id=\"controlButton\" was not injected: check your FXML file 'MediaControl.fxml'.";
|
||||||
assert timeSlider != null : "fx:id=\"timeSlider\" was not injected: check your FXML file 'MediaControl.fxml'.";
|
assert timeSlider != null : "fx:id=\"timeSlider\" was not injected: check your FXML file 'MediaControl.fxml'.";
|
||||||
@ -114,14 +117,14 @@ public class VideoPlayer extends BorderPane {
|
|||||||
final MediaException ex = mp.getError();
|
final MediaException ex = mp.getError();
|
||||||
if (ex != null) {
|
if (ex != null) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Logger.getLogger(VideoFile.class.getName()).log(Level.WARNING, ex.getType() + " Failed to initialize MediaControl for file " + file.getName(), ex);
|
Logger.getLogger(VideoFile.class.getName()).log(Level.WARNING, ex.getType() + " Failed to initialize MediaControl for file " + file.getName(), ex); //NON-NLS
|
||||||
setCenter(new Text(ex.getType() + "\nSee the logs for details."));
|
setCenter(new Text(Bundle.VideoPlayer_errNotice(ex.getType())));
|
||||||
setBottom(null);
|
setBottom(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mp.statusProperty().addListener((observableStatus, oldStatus, newStatus) -> {
|
mp.statusProperty().addListener((observableStatus, oldStatus, newStatus) -> {
|
||||||
Logger.getAnonymousLogger().log(Level.INFO, "media player: {0}", newStatus);
|
Logger.getAnonymousLogger().log(Level.INFO, "media player: {0}", newStatus); //NON-NLS
|
||||||
});
|
});
|
||||||
mediaView.setMediaPlayer(mp);
|
mediaView.setMediaPlayer(mp);
|
||||||
mediaView.fitHeightProperty().bind(this.heightProperty().subtract(playControlBar.heightProperty()));
|
mediaView.fitHeightProperty().bind(this.heightProperty().subtract(playControlBar.heightProperty()));
|
||||||
@ -236,7 +239,7 @@ public class VideoPlayer extends BorderPane {
|
|||||||
public VideoPlayer(MediaPlayer mp, VideoFile<?> file) {
|
public VideoPlayer(MediaPlayer mp, VideoFile<?> file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.mp = mp;
|
this.mp = mp;
|
||||||
FXMLConstructor.construct(this, "MediaControl.fxml");
|
FXMLConstructor.construct(this, "MediaControl.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateTime() {
|
protected void updateTime() {
|
||||||
@ -277,10 +280,10 @@ public class VideoPlayer extends BorderPane {
|
|||||||
int elapsedSeconds = totalSeconds - elapsedMinutes * 60;
|
int elapsedSeconds = totalSeconds - elapsedMinutes * 60;
|
||||||
|
|
||||||
if (elapsedHours > 0) {
|
if (elapsedHours > 0) {
|
||||||
return String.format("%d:%02d:%02d", elapsedHours,
|
return String.format("%d:%02d:%02d", elapsedHours, //NON-NLS
|
||||||
elapsedMinutes, elapsedSeconds);
|
elapsedMinutes, elapsedSeconds);
|
||||||
} else {
|
} else {
|
||||||
return String.format("%02d:%02d", elapsedMinutes,
|
return String.format("%02d:%02d", elapsedMinutes, //NON-NLS
|
||||||
elapsedSeconds);
|
elapsedSeconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public class DrawableTile extends DrawableTileBase {
|
|||||||
try {
|
try {
|
||||||
setEffect(Objects.equals(newValue, getFileID()) ? LAST_SELECTED_EFFECT : null);
|
setEffect(Objects.equals(newValue, getFileID()) ? LAST_SELECTED_EFFECT : null);
|
||||||
} catch (java.lang.IllegalStateException ex) {
|
} catch (java.lang.IllegalStateException ex) {
|
||||||
Logger.getLogger(DrawableTile.class.getName()).log(Level.WARNING, "Error displaying tile");
|
Logger.getLogger(DrawableTile.class.getName()).log(Level.WARNING, "Error displaying tile"); //NON-NLS
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ public class DrawableTile extends DrawableTileBase {
|
|||||||
public DrawableTile(GroupPane gp, ImageGalleryController controller) {
|
public DrawableTile(GroupPane gp, ImageGalleryController controller) {
|
||||||
super(gp, controller);
|
super(gp, controller);
|
||||||
|
|
||||||
FXMLConstructor.construct(this, "DrawableTile.fxml");
|
FXMLConstructor.construct(this, "DrawableTile.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,8 +95,8 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
private static final Border SELECTED_BORDER = new Border(new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, new CornerRadii(2), new BorderWidths(3)));
|
private static final Border SELECTED_BORDER = new Border(new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, new CornerRadii(2), new BorderWidths(3)));
|
||||||
|
|
||||||
//TODO: do this in CSS? -jm
|
//TODO: do this in CSS? -jm
|
||||||
protected static final Image followUpIcon = new Image("org/sleuthkit/autopsy/imagegallery/images/flag_red.png");
|
protected static final Image followUpIcon = new Image("org/sleuthkit/autopsy/imagegallery/images/flag_red.png"); //NON-NLS
|
||||||
protected static final Image followUpGray = new Image("org/sleuthkit/autopsy/imagegallery/images/flag_gray.png");
|
protected static final Image followUpGray = new Image("org/sleuthkit/autopsy/imagegallery/images/flag_gray.png"); //NON-NLS
|
||||||
|
|
||||||
protected final FileIDSelectionModel selectionModel;
|
protected final FileIDSelectionModel selectionModel;
|
||||||
private static ContextMenu contextMenu;
|
private static ContextMenu contextMenu;
|
||||||
@ -197,6 +197,8 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
t.consume();
|
t.consume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({"DrawableTileBase.menuItem.extractFiles=Extract File(s)",
|
||||||
|
"DrawableTileBase.menuItem.showContentViewer=Show Content Viewer"})
|
||||||
private ContextMenu buildContextMenu(DrawableFile<?> file) {
|
private ContextMenu buildContextMenu(DrawableFile<?> file) {
|
||||||
final ArrayList<MenuItem> menuItems = new ArrayList<>();
|
final ArrayList<MenuItem> menuItems = new ArrayList<>();
|
||||||
|
|
||||||
@ -204,7 +206,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
|
|
||||||
menuItems.add(new AddDrawableTagAction(getController()).getPopupMenu());
|
menuItems.add(new AddDrawableTagAction(getController()).getPopupMenu());
|
||||||
|
|
||||||
final MenuItem extractMenuItem = new MenuItem("Extract File(s)");
|
final MenuItem extractMenuItem = new MenuItem(Bundle.DrawableTileBase_menuItem_extractFiles());
|
||||||
extractMenuItem.setOnAction((ActionEvent t) -> {
|
extractMenuItem.setOnAction((ActionEvent t) -> {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
TopComponent etc = WindowManager.getDefault().findTopComponent(ImageGalleryTopComponent.PREFERRED_ID);
|
TopComponent etc = WindowManager.getDefault().findTopComponent(ImageGalleryTopComponent.PREFERRED_ID);
|
||||||
@ -213,10 +215,10 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
});
|
});
|
||||||
menuItems.add(extractMenuItem);
|
menuItems.add(extractMenuItem);
|
||||||
|
|
||||||
MenuItem contentViewer = new MenuItem("Show Content Viewer");
|
MenuItem contentViewer = new MenuItem(Bundle.DrawableTileBase_menuItem_showContentViewer());
|
||||||
contentViewer.setOnAction((ActionEvent t) -> {
|
contentViewer.setOnAction((ActionEvent t) -> {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
new NewWindowViewAction("Show Content Viewer", new FileNode(file.getAbstractFile())).actionPerformed(null);
|
new NewWindowViewAction(Bundle.DrawableTileBase_menuItem_showContentViewer(), new FileNode(file.getAbstractFile())).actionPerformed(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
menuItems.add(contentViewer);
|
menuItems.add(contentViewer);
|
||||||
@ -260,7 +262,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
selectionModel.clearAndSelect(file.getId());
|
selectionModel.clearAndSelect(file.getId());
|
||||||
new AddDrawableTagAction(getController()).addTag(getController().getTagsManager().getFollowUpTagName(), "");
|
new AddDrawableTagAction(getController()).addTag(getController().getTagsManager().getFollowUpTagName(), "");
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to add Follow Up tag. Could not load TagName.", ex);
|
LOGGER.log(Level.SEVERE, "Failed to add Follow Up tag. Could not load TagName.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new DeleteFollowUpTagAction(getController(), file).handle(event);
|
new DeleteFollowUpTagAction(getController(), file).handle(event);
|
||||||
@ -276,7 +278,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
return DrawableAttribute.TAGS.getValue(getFile().get()).stream()
|
return DrawableAttribute.TAGS.getValue(getFile().get()).stream()
|
||||||
.anyMatch(followUpTagName::equals);
|
.anyMatch(followUpTagName::equals);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "failed to get follow up tag name ", ex);
|
LOGGER.log(Level.WARNING, "failed to get follow up tag name ", ex); //NON-NLS
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -363,7 +365,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get followup tag name. Unable to update follow up status for file. ", ex);
|
LOGGER.log(Level.SEVERE, "Failed to get followup tag name. Unable to update follow up status for file. ", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -380,7 +382,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
updateFollowUpIcon();
|
updateFollowUpIcon();
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get followup tag name. Unable to update follow up status for file. ", ex);
|
LOGGER.log(Level.SEVERE, "Failed to get followup tag name. Unable to update follow up status for file. ", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
try {
|
try {
|
||||||
fileOpt = Optional.ofNullable(getController().getFileFromId(fileIDOpt.get()));
|
fileOpt = Optional.ofNullable(getController().getFileFromId(fileIDOpt.get()));
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "failed to get DrawableFile for obj_id" + fileIDOpt.get(), ex);
|
Logger.getAnonymousLogger().log(Level.WARNING, "failed to get DrawableFile for obj_id" + fileIDOpt.get(), ex); //NON-NLS
|
||||||
fileOpt = Optional.empty();
|
fileOpt = Optional.empty();
|
||||||
}
|
}
|
||||||
return fileOpt;
|
return fileOpt;
|
||||||
@ -147,7 +147,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
myTask.setOnFailed(failed -> {
|
myTask.setOnFailed(failed -> {
|
||||||
Throwable exception = myTask.getException();
|
Throwable exception = myTask.getException();
|
||||||
if (exception instanceof OutOfMemoryError
|
if (exception instanceof OutOfMemoryError
|
||||||
&& exception.getMessage().contains("Java heap space")) {
|
&& exception.getMessage().contains("Java heap space")) { //NON-NLS
|
||||||
showErrorNode(Bundle.DrawableUIBase_errorLabel_OOMText(), file);
|
showErrorNode(Bundle.DrawableUIBase_errorLabel_OOMText(), file);
|
||||||
} else {
|
} else {
|
||||||
showErrorNode(Bundle.DrawableUIBase_errorLabel_text(), file);
|
showErrorNode(Bundle.DrawableUIBase_errorLabel_text(), file);
|
||||||
|
@ -92,7 +92,7 @@ public interface DrawableView {
|
|||||||
} catch (NullPointerException ex) {
|
} catch (NullPointerException ex) {
|
||||||
// I think this happens when we're in the process of removing images from the view while
|
// I think this happens when we're in the process of removing images from the view while
|
||||||
// also trying to update it?
|
// also trying to update it?
|
||||||
Logger.getLogger(DrawableView.class.getName()).log(Level.WARNING, "Error looking up hash set hits");
|
Logger.getLogger(DrawableView.class.getName()).log(Level.WARNING, "Error looking up hash set hits"); //NON-NLS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,8 @@ import javafx.scene.layout.Priority;
|
|||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
import javax.ejb.MessageDriven;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -97,6 +99,7 @@ import org.controlsfx.control.GridView;
|
|||||||
import org.controlsfx.control.SegmentedButton;
|
import org.controlsfx.control.SegmentedButton;
|
||||||
import org.controlsfx.control.action.ActionUtils;
|
import org.controlsfx.control.action.ActionUtils;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
@ -273,7 +276,7 @@ public class GroupPane extends BorderPane {
|
|||||||
undoAction = new UndoAction(controller);
|
undoAction = new UndoAction(controller);
|
||||||
redoAction = new RedoAction(controller);
|
redoAction = new RedoAction(controller);
|
||||||
|
|
||||||
FXMLConstructor.construct(this, "GroupPane.fxml");
|
FXMLConstructor.construct(this, "GroupPane.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadType.JFX)
|
@ThreadConfined(type = ThreadType.JFX)
|
||||||
@ -330,10 +333,14 @@ public class GroupPane extends BorderPane {
|
|||||||
/**
|
/**
|
||||||
* create the string to display in the group header
|
* create the string to display in the group header
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"# {0} - default group name",
|
||||||
|
"# {1} - hashset hits count",
|
||||||
|
"# {2} - group size",
|
||||||
|
"GroupPane.headerString={0} -- {1} hash set hits / {2} files"})
|
||||||
protected String getHeaderString() {
|
protected String getHeaderString() {
|
||||||
return isNull(getGroup()) ? ""
|
return isNull(getGroup()) ? ""
|
||||||
: StringUtils.defaultIfBlank(getGroup().getGroupByValueDislpayName(), DrawableGroup.getBlankGroupName()) + " -- "
|
: Bundle.GroupPane_headerString(StringUtils.defaultIfBlank(getGroup().getGroupByValueDislpayName(), DrawableGroup.getBlankGroupName()),
|
||||||
+ getGroup().getHashSetHitsCount() + " hash set hits / " + getGroup().getSize() + " files";
|
getGroup().getHashSetHitsCount(), getGroup().getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextMenu getContextMenu() {
|
ContextMenu getContextMenu() {
|
||||||
@ -451,13 +458,13 @@ public class GroupPane extends BorderPane {
|
|||||||
try {
|
try {
|
||||||
tagSelectedSplitMenu.setText(controller.getTagsManager().getFollowUpTagName().getDisplayName());
|
tagSelectedSplitMenu.setText(controller.getTagsManager().getFollowUpTagName().getDisplayName());
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
LOGGER.log(Level.WARNING, "failed to load FollowUpTagName", tskCoreException);
|
LOGGER.log(Level.WARNING, "failed to load FollowUpTagName", tskCoreException); //NON-NLS
|
||||||
}
|
}
|
||||||
tagSelectedSplitMenu.setOnAction(actionEvent -> {
|
tagSelectedSplitMenu.setOnAction(actionEvent -> {
|
||||||
try {
|
try {
|
||||||
new TagSelectedFilesAction(controller.getTagsManager().getFollowUpTagName(), controller).handle(actionEvent);
|
new TagSelectedFilesAction(controller.getTagsManager().getFollowUpTagName(), controller).handle(actionEvent);
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
LOGGER.log(Level.WARNING, "failed to load FollowUpTagName", tskCoreException);
|
LOGGER.log(Level.WARNING, "failed to load FollowUpTagName", tskCoreException); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -512,6 +519,7 @@ public class GroupPane extends BorderPane {
|
|||||||
addEventFilter(KeyEvent.KEY_PRESSED, tileKeyboardNavigationHandler);
|
addEventFilter(KeyEvent.KEY_PRESSED, tileKeyboardNavigationHandler);
|
||||||
gridView.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
|
gridView.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
|
||||||
|
|
||||||
|
@NbBundle.Messages({"GroupPane.gridViewContextMenuItem.extractFiles=Extract File(s)"})
|
||||||
private ContextMenu buildContextMenu() {
|
private ContextMenu buildContextMenu() {
|
||||||
ArrayList<MenuItem> menuItems = new ArrayList<>();
|
ArrayList<MenuItem> menuItems = new ArrayList<>();
|
||||||
|
|
||||||
@ -528,7 +536,7 @@ public class GroupPane extends BorderPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final MenuItem extractMenuItem = new MenuItem("Extract File(s)");
|
final MenuItem extractMenuItem = new MenuItem(Bundle.GroupPane_gridViewContextMenuItem_extractFiles());
|
||||||
extractMenuItem.setOnAction((ActionEvent t) -> {
|
extractMenuItem.setOnAction((ActionEvent t) -> {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
TopComponent etc = WindowManager.getDefault().findTopComponent(ImageGalleryTopComponent.PREFERRED_ID);
|
TopComponent etc = WindowManager.getDefault().findTopComponent(ImageGalleryTopComponent.PREFERRED_ID);
|
||||||
@ -730,7 +738,7 @@ public class GroupPane extends BorderPane {
|
|||||||
if (gridView == null || gridView.getSkin() == null) {
|
if (gridView == null || gridView.getSkin() == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return Optional.ofNullable((ScrollBar) gridView.getSkin().getNode().lookup(".scroll-bar"));
|
return Optional.ofNullable((ScrollBar) gridView.getSkin().getNode().lookup(".scroll-bar")); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeSelection(Boolean shiftDown, Long newFileID) {
|
void makeSelection(Boolean shiftDown, Long newFileID) {
|
||||||
|
@ -50,6 +50,7 @@ import javafx.scene.input.KeyEvent;
|
|||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.util.Pair;
|
import javafx.util.Pair;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -84,10 +85,11 @@ public class MetaDataPane extends DrawableUIBase {
|
|||||||
|
|
||||||
public MetaDataPane(ImageGalleryController controller) {
|
public MetaDataPane(ImageGalleryController controller) {
|
||||||
super(controller);
|
super(controller);
|
||||||
FXMLConstructor.construct(this, "MetaDataPane.fxml");
|
FXMLConstructor.construct(this, "MetaDataPane.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@NbBundle.Messages({"MetaDataPane.tableView.placeholder=Select a file to show its details here."})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert attributeColumn != null : "fx:id=\"attributeColumn\" was not injected: check your FXML file 'MetaDataPane.fxml'.";
|
assert attributeColumn != null : "fx:id=\"attributeColumn\" was not injected: check your FXML file 'MetaDataPane.fxml'.";
|
||||||
assert imageView != null : "fx:id=\"imageView\" was not injected: check your FXML file 'MetaDataPane.fxml'.";
|
assert imageView != null : "fx:id=\"imageView\" was not injected: check your FXML file 'MetaDataPane.fxml'.";
|
||||||
@ -116,7 +118,7 @@ public class MetaDataPane extends DrawableUIBase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
tableView.setPlaceholder(new Label("Select a file to show its details here."));
|
tableView.setPlaceholder(new Label(Bundle.MetaDataPane_tableView_placeholder()));
|
||||||
tableView.getColumns().setAll(Arrays.asList(attributeColumn, valueColumn));
|
tableView.getColumns().setAll(Arrays.asList(attributeColumn, valueColumn));
|
||||||
|
|
||||||
attributeColumn.setPrefWidth(USE_COMPUTED_SIZE);
|
attributeColumn.setPrefWidth(USE_COMPUTED_SIZE);
|
||||||
|
@ -77,7 +77,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
|
|
||||||
SlideShowView(GroupPane gp, ImageGalleryController controller) {
|
SlideShowView(GroupPane gp, ImageGalleryController controller) {
|
||||||
super(gp, controller);
|
super(gp, controller);
|
||||||
FXMLConstructor.construct(this, "SlideShowView.fxml");
|
FXMLConstructor.construct(this, "SlideShowView.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -137,7 +137,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
});
|
});
|
||||||
} catch (NullPointerException ex) {
|
} catch (NullPointerException ex) {
|
||||||
// The case has likely been closed
|
// The case has likely been closed
|
||||||
LOGGER.log(Level.WARNING, "Error accessing groupPane");
|
LOGGER.log(Level.WARNING, "Error accessing groupPane"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +278,12 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
* @return supplemental text to include in the label, specifically: "image x
|
* @return supplemental text to include in the label, specifically: "image x
|
||||||
* of y"
|
* of y"
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"# {0} - file id number",
|
||||||
|
"# {1} - number of file ids",
|
||||||
|
"SlideShowView.supplementalText={0} of {1} in group"})
|
||||||
private String getSupplementalText() {
|
private String getSupplementalText() {
|
||||||
final ObservableList<Long> fileIds = getGroupPane().getGroup().getFileIDs();
|
final ObservableList<Long> fileIds = getGroupPane().getGroup().getFileIDs();
|
||||||
return getFileID().map(fileID -> " ( " + (fileIds.indexOf(fileID) + 1) + " of " + fileIds.size() + " in group )")
|
return getFileID().map(fileID -> " ( " + Bundle.SlideShowView_supplementalText(fileIds.indexOf(fileID) + 1, fileIds.size()) + " )")
|
||||||
.orElse("");
|
.orElse("");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -324,7 +327,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
final Media media = file.getMedia();
|
final Media media = file.getMedia();
|
||||||
return new VideoPlayer(new MediaPlayer(media), file);
|
return new VideoPlayer(new MediaPlayer(media), file);
|
||||||
} catch (MediaException | IOException | OutOfMemoryError ex) {
|
} catch (MediaException | IOException | OutOfMemoryError ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to initialize VideoPlayer for {0} : " + ex.toString(), file.getContentPathSafe());
|
LOGGER.log(Level.WARNING, "Failed to initialize VideoPlayer for {0} : " + ex.toString(), file.getContentPathSafe()); //NON-NLS
|
||||||
return doReadImageTask(file);
|
return doReadImageTask(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,27 +21,34 @@ package org.sleuthkit.autopsy.imagegallery.gui.navpanel;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.DrawableGroup;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.DrawableGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"GroupComparators.uncategorizedCount=Uncategorized Count",
|
||||||
|
"GroupComparators.groupName=Group Name",
|
||||||
|
"GroupComparators.hitCount=Hit Count",
|
||||||
|
"GroupComparators.groupSize=Group Size",
|
||||||
|
"GroupComparators.hitDensity=Hit Density"})
|
||||||
final class GroupComparators<T extends Comparable<T>> implements Comparator<DrawableGroup> {
|
final class GroupComparators<T extends Comparable<T>> implements Comparator<DrawableGroup> {
|
||||||
|
|
||||||
static final GroupComparators<Long> UNCATEGORIZED_COUNT =
|
static final GroupComparators<Long> UNCATEGORIZED_COUNT =
|
||||||
new GroupComparators<>("Uncategorized Count", DrawableGroup::getUncategorizedCount, String::valueOf, false);
|
new GroupComparators<>(Bundle.GroupComparators_uncategorizedCount(), DrawableGroup::getUncategorizedCount, String::valueOf, false);
|
||||||
|
|
||||||
static final GroupComparators<String> ALPHABETICAL =
|
static final GroupComparators<String> ALPHABETICAL =
|
||||||
new GroupComparators<>("Group Name", DrawableGroup::getGroupByValueDislpayName, String::valueOf, false);
|
new GroupComparators<>(Bundle.GroupComparators_groupName(), DrawableGroup::getGroupByValueDislpayName, String::valueOf, false);
|
||||||
|
|
||||||
static final GroupComparators<Long> HIT_COUNT =
|
static final GroupComparators<Long> HIT_COUNT =
|
||||||
new GroupComparators<>("Hit Count", DrawableGroup::getHashSetHitsCount, String::valueOf, true);
|
new GroupComparators<>(Bundle.GroupComparators_hitCount(), DrawableGroup::getHashSetHitsCount, String::valueOf, true);
|
||||||
|
|
||||||
static final GroupComparators<Integer> FILE_COUNT =
|
static final GroupComparators<Integer> FILE_COUNT =
|
||||||
new GroupComparators<>("Group Size", DrawableGroup::getSize, String::valueOf, true);
|
new GroupComparators<>(Bundle.GroupComparators_groupSize(), DrawableGroup::getSize, String::valueOf, true);
|
||||||
|
|
||||||
static final GroupComparators<Double> HIT_FILE_RATIO =
|
static final GroupComparators<Double> HIT_FILE_RATIO =
|
||||||
new GroupComparators<>("Hit Density", DrawableGroup::getHashHitDensity, density -> String.format("%.2f", density) + "%", true);
|
new GroupComparators<>(Bundle.GroupComparators_hitDensity(), DrawableGroup::getHashHitDensity, density -> String.format("%.2f", density) + "%", true); //NON-NLS
|
||||||
|
|
||||||
private final static ImmutableList<GroupComparators<?>> values = ImmutableList.of(UNCATEGORIZED_COUNT, ALPHABETICAL, HIT_COUNT, FILE_COUNT, HIT_FILE_RATIO);
|
private final static ImmutableList<GroupComparators<?>> values = ImmutableList.of(UNCATEGORIZED_COUNT, ALPHABETICAL, HIT_COUNT, FILE_COUNT, HIT_FILE_RATIO);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class GroupListCell extends ListCell<DrawableGroup> {
|
|||||||
* folder(with no DrawableFiles) in the file system hierarchy.
|
* folder(with no DrawableFiles) in the file system hierarchy.
|
||||||
*/
|
*/
|
||||||
private static final Image EMPTY_FOLDER_ICON =
|
private static final Image EMPTY_FOLDER_ICON =
|
||||||
new Image(GroupTreeCell.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/folder.png"));
|
new Image(GroupTreeCell.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/folder.png")); //NON-NLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reference to group files listener that allows us to remove it from a
|
* reference to group files listener that allows us to remove it from a
|
||||||
@ -70,8 +70,8 @@ class GroupListCell extends ListCell<DrawableGroup> {
|
|||||||
GroupListCell(ReadOnlyObjectProperty<GroupComparators<?>> sortOrderProperty) {
|
GroupListCell(ReadOnlyObjectProperty<GroupComparators<?>> sortOrderProperty) {
|
||||||
|
|
||||||
this.sortOrder = sortOrderProperty;
|
this.sortOrder = sortOrderProperty;
|
||||||
getStylesheets().add(GroupTreeCell.class.getResource("GroupTreeCell.css").toExternalForm());
|
getStylesheets().add(GroupTreeCell.class.getResource("GroupTreeCell.css").toExternalForm()); //NON-NLS
|
||||||
getStyleClass().add("groupTreeCell"); //reduce indent to 5, default is 10 which uses up a lot of space.
|
getStyleClass().add("groupTreeCell"); //reduce indent to 5, default is 10 which uses up a lot of space. NON-NLS
|
||||||
|
|
||||||
//since end of path is probably more interesting put ellipsis at front
|
//since end of path is probably more interesting put ellipsis at front
|
||||||
setTextOverrun(OverrunStyle.LEADING_ELLIPSIS);
|
setTextOverrun(OverrunStyle.LEADING_ELLIPSIS);
|
||||||
@ -145,7 +145,7 @@ class GroupListCell extends ListCell<DrawableGroup> {
|
|||||||
private String getSeenStyleClass() {
|
private String getSeenStyleClass() {
|
||||||
return Optional.ofNullable(getItem())
|
return Optional.ofNullable(getItem())
|
||||||
.map(DrawableGroup::isSeen)
|
.map(DrawableGroup::isSeen)
|
||||||
.map(seen -> seen ? "" : "-fx-font-weight:bold;")
|
.map(seen -> seen ? "" : "-fx-font-weight:bold;") //NON-NLS
|
||||||
.orElse(""); //if item is null or group is null
|
.orElse(""); //if item is null or group is null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ import javafx.scene.control.TreeItem;
|
|||||||
import javafx.scene.control.TreeView;
|
import javafx.scene.control.TreeView;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
@ -53,15 +55,16 @@ final public class GroupTree extends NavPanel<TreeItem<GroupTreeNode>> {
|
|||||||
|
|
||||||
public GroupTree(ImageGalleryController controller) {
|
public GroupTree(ImageGalleryController controller) {
|
||||||
super(controller);
|
super(controller);
|
||||||
FXMLConstructor.construct(this, "NavPanel.fxml");
|
FXMLConstructor.construct(this, "NavPanel.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@Override
|
@Override
|
||||||
|
@NbBundle.Messages({"GroupTree.displayName.allGroups=All Groups"})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
setText("All Groups");
|
setText(Bundle.GroupTree_displayName_allGroups());
|
||||||
setGraphic(new ImageView("org/sleuthkit/autopsy/imagegallery/images/Folder-icon.png"));
|
setGraphic(new ImageView("org/sleuthkit/autopsy/imagegallery/images/Folder-icon.png")); //NON-NLS
|
||||||
|
|
||||||
getBorderPane().setCenter(groupTree);
|
getBorderPane().setCenter(groupTree);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class GroupTreeCell extends TreeCell<GroupTreeNode> {
|
|||||||
* folder(with no DrawableFiles) in the file system hierarchy.
|
* folder(with no DrawableFiles) in the file system hierarchy.
|
||||||
*/
|
*/
|
||||||
private static final Image EMPTY_FOLDER_ICON =
|
private static final Image EMPTY_FOLDER_ICON =
|
||||||
new Image(GroupTreeCell.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/folder.png"));
|
new Image(GroupTreeCell.class.getResourceAsStream("/org/sleuthkit/autopsy/imagegallery/images/folder.png")); //NON-NLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reference to group files listener that allows us to remove it from a
|
* reference to group files listener that allows us to remove it from a
|
||||||
@ -75,8 +75,8 @@ class GroupTreeCell extends TreeCell<GroupTreeNode> {
|
|||||||
|
|
||||||
GroupTreeCell(ReadOnlyObjectProperty<GroupComparators<?>> sortOrderProperty) {
|
GroupTreeCell(ReadOnlyObjectProperty<GroupComparators<?>> sortOrderProperty) {
|
||||||
this.sortOrder = sortOrderProperty;
|
this.sortOrder = sortOrderProperty;
|
||||||
getStylesheets().add(GroupTreeCell.class.getResource("GroupTreeCell.css").toExternalForm());
|
getStylesheets().add(GroupTreeCell.class.getResource("GroupTreeCell.css").toExternalForm()); //NON-NLS
|
||||||
getStyleClass().add("groupTreeCell"); //reduce indent to 5, default is 10 which uses up a lot of space.
|
getStyleClass().add("groupTreeCell"); //reduce indent to 5, default is 10 which uses up a lot of space. NON-NLS
|
||||||
|
|
||||||
//since end of path is probably more interesting put ellipsis at front
|
//since end of path is probably more interesting put ellipsis at front
|
||||||
setTextOverrun(OverrunStyle.LEADING_ELLIPSIS);
|
setTextOverrun(OverrunStyle.LEADING_ELLIPSIS);
|
||||||
@ -161,7 +161,7 @@ class GroupTreeCell extends TreeCell<GroupTreeNode> {
|
|||||||
return Optional.ofNullable(getItem())
|
return Optional.ofNullable(getItem())
|
||||||
.map(GroupTreeNode::getGroup)
|
.map(GroupTreeNode::getGroup)
|
||||||
.map(DrawableGroup::isSeen)
|
.map(DrawableGroup::isSeen)
|
||||||
.map(seen -> seen ? "" : "-fx-font-weight:bold;")
|
.map(seen -> seen ? "" : "-fx-font-weight:bold;") //NON-NLS
|
||||||
.orElse(""); //if item is null or group is null
|
.orElse(""); //if item is null or group is null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import javafx.fxml.FXML;
|
|||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.scene.control.SelectionModel;
|
import javafx.scene.control.SelectionModel;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
@ -47,7 +48,7 @@ final public class HashHitGroupList extends NavPanel<DrawableGroup> {
|
|||||||
|
|
||||||
public HashHitGroupList(ImageGalleryController controller) {
|
public HashHitGroupList(ImageGalleryController controller) {
|
||||||
super(controller);
|
super(controller);
|
||||||
FXMLConstructor.construct(this, "NavPanel.fxml");
|
FXMLConstructor.construct(this, "NavPanel.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
@ -68,11 +69,12 @@ final public class HashHitGroupList extends NavPanel<DrawableGroup> {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@Override
|
@Override
|
||||||
|
@NbBundle.Messages({"HashHitGroupList.displayName.onlyHashHits=Only Hash Hits"})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
|
|
||||||
setText("Only Hash Hits");
|
setText(Bundle.HashHitGroupList_displayName_onlyHashHits());
|
||||||
setGraphic(new ImageView("org/sleuthkit/autopsy/imagegallery/images/hashset_hits.png"));
|
setGraphic(new ImageView("org/sleuthkit/autopsy/imagegallery/images/hashset_hits.png")); //NON-NLS
|
||||||
|
|
||||||
getBorderPane().setCenter(groupList);
|
getBorderPane().setCenter(groupList);
|
||||||
sorted = getController().getGroupManager().getAnalyzedGroups().filtered((DrawableGroup t) -> t.getHashSetHitsCount() > 0).sorted(getDefaultComparator());
|
sorted = getController().getGroupManager().getAnalyzedGroups().filtered((DrawableGroup t) -> t.getHashSetHitsCount() > 0).sorted(getDefaultComparator());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user