From 964679ad9a4d0f52c99c896a150672317ca8327b Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 23 Jun 2015 10:37:31 -0400 Subject: [PATCH 1/3] only prompt that the events db is out of date, when the timeline window is open --- .../autopsy/timeline/TimeLineController.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index e57dddb509..2ebaba9d93 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014 Basis Technology Corp. + * Copyright 2014-15 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -257,7 +257,7 @@ public class TimeLineController { LOGGER.log(Level.INFO, "Beginning generation of timeline"); // NON-NLS try { SwingUtilities.invokeLater(() -> { - if (mainFrame != null) { + if (isWindowOpen()) { mainFrame.close(); } }); @@ -311,7 +311,8 @@ public class TimeLineController { } } - /** show the timeline window and prompt for rebuilding database */ + /** show the timeline window and prompt for rebuilding database if + * necessary. */ synchronized void openTimeLine() { // listen for case changes (specifically images being added, and case changes). @@ -636,12 +637,21 @@ public class TimeLineController { /** * prompt the user to rebuild and then rebuild if the user chooses to */ - synchronized public boolean outOfDatePromptAndRebuild() { + synchronized private boolean outOfDatePromptAndRebuild() { return showOutOfDateConfirmation() == JOptionPane.YES_OPTION ? rebuildRepo() : false; } + /** + * is the timeline window open. + * + * @return true if the timeline window is open + */ + synchronized private boolean isWindowOpen() { + return mainFrame != null && mainFrame.isOpened() && mainFrame.isVisible(); + } + synchronized int showLastPopulatedWhileIngestingConfirmation() { return JOptionPane.showConfirmDialog(mainFrame, DO_REPOPULATE_MESSAGE, @@ -703,7 +713,9 @@ public class TimeLineController { case CANCELLED: case COMPLETED: //if we are doing incremental updates, drop this - outOfDatePromptAndRebuild(); + if (isWindowOpen()) { + outOfDatePromptAndRebuild(); + } break; } } @@ -718,7 +730,9 @@ public class TimeLineController { case DATA_SOURCE_ADDED: // Content content = (Content) evt.getNewValue(); //if we are doing incremental updates, drop this - outOfDatePromptAndRebuild(); + if (isWindowOpen()) { + outOfDatePromptAndRebuild(); + } break; case CURRENT_CASE: OpenTimelineAction.invalidateController(); From dac18bf6da9f8dce69a4c357758fa1490f116052 Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 23 Jun 2015 13:17:53 -0400 Subject: [PATCH 2/3] fix npe by optionalizing getCachefile --- .../autopsy/imagegallery/ThumbnailCache.java | 71 +++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ThumbnailCache.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ThumbnailCache.java index a9d3042e5b..2d60cc819e 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ThumbnailCache.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ThumbnailCache.java @@ -119,28 +119,29 @@ public enum ThumbnailCache { /** * load a thumbnail from the disk based cache for the given file, or - * generate and save a new thumnbail if one doesn't already exist + * generate and save a new thumbnail if one doesn't already exist * - * @param file the file to load a thumbnail of + * @param file the DrawableFile to load a thumbnail of * - * @return an optional containing a thumbnail, or null if a thumbnail - * couldn't be loaded or generated + * @return an (possibly empty) optional containing a thumbnail */ private Optional load(DrawableFile file) { - Image thumbnail = null; - File cacheFile; - try {// try to load the thumbnail from disk - cacheFile = getCacheFile(file.getId()); + Image thumbnail; - if (cacheFile.exists()) { - // If a thumbnail file is already saved locally, load it - try { - int dim = iconSize.get(); - thumbnail = new Image(Utilities.toURI(cacheFile).toURL().toString(), dim, dim, true, false, true); - } catch (MalformedURLException ex) { - Exceptions.printStackTrace(ex); + try { + thumbnail = getCacheFile(file.getId()).map((File cachFile) -> { + if (cachFile.exists()) { + // If a thumbnail file is already saved locally, load it + try { + int dim = iconSize.get(); + return new Image(Utilities.toURI(cachFile).toURL().toString(), dim, dim, true, false, true); + } catch (MalformedURLException ex) { + LOGGER.log(Level.WARNING, "Unable to parse cache file path.."); + } } - } + return null; + }).orElse(null); + } catch (IllegalStateException e) { LOGGER.log(Level.WARNING, "can't load icon when no case is open"); return Optional.empty(); @@ -153,9 +154,23 @@ public enum ThumbnailCache { return Optional.ofNullable(thumbnail); //return icon, or null if generation failed } - private static File getCacheFile(long id) { - // @@@ should use ImageUtils.getFile(); - return new File(Case.getCurrentCase().getCacheDirectory() + File.separator + id + ".png"); + /** + * get a File to store the cached icon in. + * + * @param id the obj id of the file to get a cache file for + * + * @return a Optional containing a File to store the cahced icon in or an + * empty optional if there was a + * problem. + */ + private static Optional getCacheFile(long id) { + try { + // @@@ should use ImageUtils.getFile(); + return Optional.of(new File(Case.getCurrentCase().getCacheDirectory() + File.separator + id + ".png")); + } catch (IllegalStateException e) { + LOGGER.log(Level.WARNING, "Failed to create cache file.{0}", e.getLocalizedMessage()); + return Optional.empty(); + } } /** @@ -255,15 +270,15 @@ public enum ThumbnailCache { * @param bi the thumbnail to save for the given DrawableFile */ private void saveIcon(final DrawableFile file, final Image bi) { - try { - if (bi != null) { - File f = getCacheFile(file.getId()); - //convert back to swing to save - ImageIO.write(SwingFXUtils.fromFXImage(bi, null), FORMAT, f); - } - } catch (IllegalArgumentException | IOException ex) { - //LOGGER.log(Level.WARNING, "failed to save generated icon ", ex); - LOGGER.log(Level.WARNING, "failed to save generated icon"); + if (bi != null) { + getCacheFile(file.getId()).ifPresent((File cacheFile) -> { + try { + //convert back to swing to save + ImageIO.write(SwingFXUtils.fromFXImage(bi, null), FORMAT, cacheFile); + } catch (IllegalArgumentException | IOException ex) { + LOGGER.log(Level.WARNING, "failed to save generated icon"); + } + }); } } } From 4db34a412ae404a37de3be5b5ad871648a2a70b2 Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 23 Jun 2015 14:19:55 -0400 Subject: [PATCH 3/3] use SwingUtilities.invokeLater rather than invokeandWait so that showing the swing dialog does not block hiding the fx menu. --- .../imagegallery/actions/AddTagAction.java | 44 +++++++------------ 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/actions/AddTagAction.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/actions/AddTagAction.java index 85894cc661..42cd0ecfd1 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/actions/AddTagAction.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/actions/AddTagAction.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.imagegallery.actions; -import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Set; import java.util.logging.Level; @@ -26,7 +25,6 @@ import javafx.event.ActionEvent; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javax.swing.SwingUtilities; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog; import org.sleuthkit.autopsy.actions.GetTagNameDialog; import org.sleuthkit.autopsy.casemodule.Case; @@ -130,17 +128,13 @@ abstract class AddTagAction { // or select a tag name and adds a tag with the resulting name. MenuItem newTagMenuItem = new MenuItem("New Tag..."); newTagMenuItem.setOnAction((ActionEvent t) -> { - try { - SwingUtilities.invokeAndWait(() -> { - TagName tagName = GetTagNameDialog.doDialog(); - if (tagName != null) { - addTag(tagName, NO_COMMENT); - refreshDirectoryTree(); - } - }); - } catch (InterruptedException | InvocationTargetException ex) { - Exceptions.printStackTrace(ex); - } + SwingUtilities.invokeLater(() -> { + TagName tagName = GetTagNameDialog.doDialog(); + if (tagName != null) { + addTag(tagName, NO_COMMENT); + refreshDirectoryTree(); + } + }); }); quickTagMenu.getItems().add(newTagMenuItem); @@ -149,21 +143,17 @@ abstract class AddTagAction { // optional comment and adds a tag with the resulting name. MenuItem tagAndCommentItem = new MenuItem("Tag and Comment..."); tagAndCommentItem.setOnAction((ActionEvent t) -> { - try { - SwingUtilities.invokeAndWait(() -> { - GetTagNameAndCommentDialog.TagNameAndComment tagNameAndComment = GetTagNameAndCommentDialog.doDialog(); - if (null != tagNameAndComment) { - if (tagNameAndComment.getTagName().getDisplayName().startsWith(Category.CATEGORY_PREFIX)) { - new CategorizeAction().addTag(tagNameAndComment.getTagName(), tagNameAndComment.getComment()); - } else { - AddDrawableTagAction.getInstance().addTag(tagNameAndComment.getTagName(), tagNameAndComment.getComment()); - } - refreshDirectoryTree(); + SwingUtilities.invokeLater(() -> { + GetTagNameAndCommentDialog.TagNameAndComment tagNameAndComment = GetTagNameAndCommentDialog.doDialog(); + if (null != tagNameAndComment) { + if (tagNameAndComment.getTagName().getDisplayName().startsWith(Category.CATEGORY_PREFIX)) { + new CategorizeAction().addTag(tagNameAndComment.getTagName(), tagNameAndComment.getComment()); + } else { + AddDrawableTagAction.getInstance().addTag(tagNameAndComment.getTagName(), tagNameAndComment.getComment()); } - }); - } catch (InterruptedException | InvocationTargetException ex) { - Exceptions.printStackTrace(ex); - } + refreshDirectoryTree(); + } + }); }); getItems().add(tagAndCommentItem); }