Merge branch 'master' of github.com:sleuthkit/autopsy

This commit is contained in:
Brian Carrier 2013-09-03 13:37:52 -04:00
commit e643c32ee5
5 changed files with 130 additions and 31 deletions

View File

@ -59,7 +59,7 @@ import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
public class Case implements SleuthkitCase.ErrorObserver { public class Case implements SleuthkitCase.ErrorObserver {
private static final String autopsyVer = Version.getVersion(); // current version of autopsy. Change it when the version is changed private static final String autopsyVer = Version.getVersion(); // current version of autopsy. Change it when the version is changed
private static final String appName = Version.getName() + " " + autopsyVer; private static String appName = null;
/** /**
* Property name that indicates the name of the current case has changed. * Property name that indicates the name of the current case has changed.
* Fired with the case is renamed, and when the current case is * Fired with the case is renamed, and when the current case is
@ -507,6 +507,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
* @return appName * @return appName
*/ */
public static String getAppName() { public static String getAppName() {
if ((appName == null ) || appName.equals("")) {
appName = WindowManager.getDefault().getMainWindow().getTitle();
}
return appName; return appName;
} }

View File

@ -39,6 +39,8 @@
<Component id="imagesLabel" min="-2" max="-2" attributes="0"/> <Component id="imagesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="imagesRangeLabel" min="-2" pref="91" max="-2" attributes="0"/> <Component id="imagesRangeLabel" min="-2" pref="91" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="thumbnailSizeComboBox" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
@ -61,6 +63,7 @@
<Component id="imagesRangeLabel" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="imagesRangeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="goToPageLabel" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="goToPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="goToPageField" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="goToPageField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="thumbnailSizeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/> <EmptySpace min="0" pref="0" max="-2" attributes="0"/>
@ -196,5 +199,20 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="goToPageFieldActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="goToPageFieldActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JComboBox" name="thumbnailSizeComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="3">
<StringItem index="0" value="Small Thumbnails"/>
<StringItem index="1" value="Medium Thumbnails"/>
<StringItem index="2" value="Large Thumbnails"/>
</StringArray>
</Property>
<Property name="selectedIndex" type="int" value="1"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="thumbnailSizeComboBoxActionPerformed"/>
</Events>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -22,6 +22,7 @@ import java.awt.Color;
import java.awt.Cursor; import java.awt.Cursor;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.Arrays;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@ -61,6 +62,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
private int curPage; private int curPage;
private int totalPages; private int totalPages;
private int curPageImages; private int curPageImages;
private int iconSize = ThumbnailViewNode.ICON_SIZE_MEDIUM;
private final PageUpdater pageUpdater = new PageUpdater(); private final PageUpdater pageUpdater = new PageUpdater();
/** /**
@ -111,6 +113,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
filePathLabel = new javax.swing.JLabel(); filePathLabel = new javax.swing.JLabel();
goToPageLabel = new javax.swing.JLabel(); goToPageLabel = new javax.swing.JLabel();
goToPageField = new javax.swing.JTextField(); goToPageField = new javax.swing.JTextField();
thumbnailSizeComboBox = new javax.swing.JComboBox();
thumbnailScrollPanel.setPreferredSize(new java.awt.Dimension(582, 348)); thumbnailScrollPanel.setPreferredSize(new java.awt.Dimension(582, 348));
@ -160,6 +163,14 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
} }
}); });
thumbnailSizeComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Small Thumbnails", "Medium Thumbnails", "Large Thumbnails" }));
thumbnailSizeComboBox.setSelectedIndex(1);
thumbnailSizeComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
thumbnailSizeComboBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
@ -186,8 +197,10 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
.addGap(12, 12, 12) .addGap(12, 12, 12)
.addComponent(imagesLabel) .addComponent(imagesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(imagesRangeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(imagesRangeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap()) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(thumbnailSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -203,7 +216,8 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
.addComponent(imagesLabel) .addComponent(imagesLabel)
.addComponent(imagesRangeLabel) .addComponent(imagesRangeLabel)
.addComponent(goToPageLabel) .addComponent(goToPageLabel)
.addComponent(goToPageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(goToPageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(thumbnailSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 0, 0) .addGap(0, 0, 0)
.addComponent(thumbnailScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(thumbnailScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -223,6 +237,38 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
goToPage(goToPageField.getText()); goToPage(goToPageField.getText());
}//GEN-LAST:event_goToPageFieldActionPerformed }//GEN-LAST:event_goToPageFieldActionPerformed
private void thumbnailSizeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_thumbnailSizeComboBoxActionPerformed
iconSize = ThumbnailViewNode.ICON_SIZE_MEDIUM; //default size
switch(thumbnailSizeComboBox.getSelectedIndex()) {
case 0:
iconSize = ThumbnailViewNode.ICON_SIZE_SMALL;
break;
case 2:
iconSize = ThumbnailViewNode.ICON_SIZE_LARGE;
break;
}
Node root = em.getRootContext();
for (Children c : Arrays.asList(root.getChildren()) ) {
((ThumbnailViewChildren)c).setIconSize(iconSize);
}
for (Node page : root.getChildren().getNodes()) {
for (Node node : page.getChildren().getNodes()) {
((ThumbnailViewNode)node).setIconSize(iconSize);
}
}
// Temporarily set the explored context to the root, instead of a child node.
// This is a workaround hack to convince org.openide.explorer.ExplorerManager to
// update even though the new and old Node values are identical. This in turn
// will cause the entire view to update completely. After this we
// immediately set the node back to the current child by calling switchPage().
em.setExploredContext(root);
switchPage();
}//GEN-LAST:event_thumbnailSizeComboBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel filePathLabel; private javax.swing.JLabel filePathLabel;
private javax.swing.JTextField goToPageField; private javax.swing.JTextField goToPageField;
@ -235,6 +281,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
private javax.swing.JButton pagePrevButton; private javax.swing.JButton pagePrevButton;
private javax.swing.JLabel pagesLabel; private javax.swing.JLabel pagesLabel;
private javax.swing.JScrollPane thumbnailScrollPanel; private javax.swing.JScrollPane thumbnailScrollPanel;
private javax.swing.JComboBox thumbnailSizeComboBox;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@Override @Override
@ -260,7 +307,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try { try {
if (givenNode != null) { if (givenNode != null) {
ThumbnailViewChildren childNode = new ThumbnailViewChildren(givenNode); ThumbnailViewChildren childNode = new ThumbnailViewChildren(givenNode, iconSize);
final Node root = new AbstractNode(childNode); final Node root = new AbstractNode(childNode);
pageUpdater.setRoot(root); pageUpdater.setRoot(root);
@ -401,7 +448,6 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
progress.finish(); progress.finish();
setCursor(null); setCursor(null);
updateControls(); updateControls();
} }
}.execute(); }.execute();

View File

@ -52,15 +52,17 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
private final HashMap<Integer, List<Node>> pages = new HashMap<Integer, List<Node>>(); private final HashMap<Integer, List<Node>> pages = new HashMap<Integer, List<Node>>();
private int totalImages = 0; private int totalImages = 0;
private int totalPages = 0; private int totalPages = 0;
private int iconSize = ThumbnailViewNode.ICON_SIZE_MEDIUM;
private static final Logger logger = Logger.getLogger(ThumbnailViewChildren.class.getName()); private static final Logger logger = Logger.getLogger(ThumbnailViewChildren.class.getName());
/** /**
* the constructor * the constructor
*/ */
ThumbnailViewChildren(Node arg) { ThumbnailViewChildren(Node arg, int iconSize) {
super(true); //support lazy loading super(true); //support lazy loading
this.parent = arg; this.parent = arg;
this.iconSize = iconSize;
// //
} }
@ -153,6 +155,10 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
return false; return false;
} }
public void setIconSize(int iconSize) {
this.iconSize = iconSize;
}
private static class IsSupportedContentVisitor extends ContentVisitor.Default<Boolean> { private static class IsSupportedContentVisitor extends ContentVisitor.Default<Boolean> {
private final List<String> SUPP_EXTENSIONS; private final List<String> SUPP_EXTENSIONS;
@ -255,7 +261,7 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
@Override @Override
protected Node[] createNodes(Node wrapped) { protected Node[] createNodes(Node wrapped) {
if (wrapped != null) { if (wrapped != null) {
final ThumbnailViewNode thumb = new ThumbnailViewNode(wrapped); final ThumbnailViewNode thumb = new ThumbnailViewNode(wrapped, iconSize);
return new Node[]{thumb}; return new Node[]{thumb};
} else { } else {
return new Node[]{}; return new Node[]{};

View File

@ -49,16 +49,21 @@ import org.sleuthkit.datamodel.TskException;
*/ */
class ThumbnailViewNode extends FilterNode { class ThumbnailViewNode extends FilterNode {
private SoftReference<Image> iconCache; private SoftReference<Image> iconCache = null;
private static final Image defaultIcon = new ImageIcon("/org/sleuthkit/autopsy/images/file-icon.png").getImage(); private static final Image defaultIcon = new ImageIcon("/org/sleuthkit/autopsy/images/file-icon.png").getImage();
private static final Logger logger = Logger.getLogger(ThumbnailViewNode.class.getName()); private static final Logger logger = Logger.getLogger(ThumbnailViewNode.class.getName());
static final int ICON_SIZE_SMALL = 50;
static final int ICON_SIZE_MEDIUM = 100;
static final int ICON_SIZE_LARGE = 200;
private int iconSize = ICON_SIZE_MEDIUM;
//private final BufferedImage defaultIconBI; //private final BufferedImage defaultIconBI;
/** /**
* the constructor * the constructor
*/ */
ThumbnailViewNode(Node arg) { ThumbnailViewNode(Node arg, int iconSize) {
super(arg, Children.LEAF); super(arg, Children.LEAF);
this.iconSize = iconSize;
} }
@Override @Override
@ -78,31 +83,26 @@ class ThumbnailViewNode extends FilterNode {
icon = iconCache.get(); icon = iconCache.get();
} }
if (icon == null) { if (icon == null) {
Content content = this.getLookup().lookup(Content.class); Content content = this.getLookup().lookup(Content.class);
if (content != null) { if (content != null) {
// If a thumbnail file is already saved locally
if (getFile(content.getId()).exists()) { if (getFile(content.getId()).exists()) {
try { try {
icon = ImageIO.read(getFile(content.getId())); BufferedImage bicon = ImageIO.read(getFile(content.getId()));
if (icon == null) { if (bicon == null) {
icon = ThumbnailViewNode.defaultIcon; icon = ThumbnailViewNode.defaultIcon;
} else if (bicon.getWidth() != iconSize) {
icon = generateAndSaveIcon(content);
} else {
icon = bicon;
} }
} catch (IOException ex) { } catch (IOException ex) {
icon = ThumbnailViewNode.defaultIcon; icon = ThumbnailViewNode.defaultIcon;
} }
} else { } else { // Make a new icon
try { icon = generateAndSaveIcon(content);
icon = generateIcon(content);
if (icon == null) {
icon = ThumbnailViewNode.defaultIcon;
} else {
ImageIO.write((BufferedImage) icon, "jpg", getFile(content.getId()));
}
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex);
}
} }
} else { } else {
icon = ThumbnailViewNode.defaultIcon; icon = ThumbnailViewNode.defaultIcon;
@ -114,10 +114,29 @@ class ThumbnailViewNode extends FilterNode {
return icon; return icon;
} }
private Image generateAndSaveIcon(Content content) {
Image icon = null;
try {
icon = generateIcon(content);
if (icon == null) {
icon = ThumbnailViewNode.defaultIcon;
} else {
File f = getFile(content.getId());
if (f.exists()) {
f.delete();
}
ImageIO.write((BufferedImage) icon, "jpg", getFile(content.getId()));
}
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex);
}
return icon;
}
/* /*
* Generate a scaled image * Generate a scaled image
*/ */
static private BufferedImage generateIcon(Content content) { private BufferedImage generateIcon(Content content) {
InputStream inputStream = null; InputStream inputStream = null;
try { try {
@ -127,7 +146,8 @@ class ThumbnailViewNode extends FilterNode {
logger.log(Level.WARNING, "No image reader for file: " + content.getName()); logger.log(Level.WARNING, "No image reader for file: " + content.getName());
return null; return null;
} }
BufferedImage biScaled = ScalrWrapper.resizeFast(bi, 100, 100); BufferedImage biScaled = ScalrWrapper.resizeFast(bi, iconSize);
return biScaled; return biScaled;
}catch (OutOfMemoryError e) { }catch (OutOfMemoryError e) {
logger.log(Level.WARNING, "Could not scale image (too large): " + content.getName(), e); logger.log(Level.WARNING, "Could not scale image (too large): " + content.getName(), e);
@ -151,4 +171,10 @@ class ThumbnailViewNode extends FilterNode {
private static File getFile(long id) { private static File getFile(long id) {
return new File(Case.getCurrentCase().getCacheDirectory() + File.separator + id + ".jpg"); return new File(Case.getCurrentCase().getCacheDirectory() + File.separator + id + ".jpg");
} }
public void setIconSize(int iconSize) {
this.iconSize = iconSize;
iconCache = null;
}
} }