Merge pull request #5372 from wschaeferB/5677-DisplayVisualStatusIndicators

5677 display visual status indicators
This commit is contained in:
Richard Cordovano 2019-11-13 12:33:59 -05:00 committed by GitHub
commit d8a408709c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 444 additions and 39 deletions

View File

@ -1113,7 +1113,10 @@ public class Case {
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(false);
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(false);
DiscoveryTopComponent.getTopComponent().resetTopComponent();
DiscoveryTopComponent discoveryTopComp = DiscoveryTopComponent.getTopComponent();
if (discoveryTopComp != null){
discoveryTopComp.resetTopComponent();
}
/*
* Clear the notifications in the notfier component in the lower
* right hand corner of the main application window.

View File

@ -119,8 +119,13 @@ FileSorter.SortingMethod.keywordlist.displayName=By keyword list names
FileSorter.SortingMethod.parent.displayName=By parent path
# {0} - numberOfInstances
ImageThumbnailPanel.countLabel.text=Number of Instances: {0}
ImageThumbnailPanel.isDeleted.text=All instances of file are deleted.
# {0} - fileSize
ImageThumbnailPanel.sizeLabel.text=Size: {0} bytes
ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.
ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.
ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag.
ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.
ResultsDialog.dialogTitle.text=File search results
ResultsDialog.exitButton.text=Exit
ResultsDialog.searchButton.text=Run another search
@ -177,5 +182,6 @@ ResultsPanel.viewFileInDir.name=View File in Directory
SearchNode.getName.text=Search Result
# {0} - numberOfInstances
VideoThumbnailPanel.countLabel.text=Number of Instances: {0}
VideoThumbnailPanel.deleted.text=All instances of file are deleted.
# {0} - fileSize
VideoThumbnailPanel.sizeLabel.text=Size: {0} bytes

View File

@ -144,7 +144,7 @@ class FileSearch {
*
* @throws FileSearchException
*/
static LinkedHashMap<GroupKey, Integer> getGroupSizes(String userName,
static Map<GroupKey, Integer> getGroupSizes(String userName,
List<FileSearchFiltering.FileFilter> filters,
AttributeType groupAttributeType,
FileGroup.GroupSortingAlgorithm groupSortingType,

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@ -17,13 +20,21 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="thumbnailPanel" max="32767" attributes="0"/>
<Component id="countLabel" alignment="0" pref="201" max="32767" attributes="0"/>
<Component id="thumbnailPanel" pref="201" max="32767" attributes="0"/>
<Component id="fileSizeLabel" alignment="0" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="countLabel" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="isDeletedLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="scoreLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -35,7 +46,11 @@
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="fileSizeLabel" min="-2" pref="16" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="countLabel" min="-2" pref="12" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="scoreLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="isDeletedLabel" min="-2" max="-2" attributes="0"/>
<Component id="countLabel" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@ -43,6 +58,9 @@
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="thumbnailPanel">
<Properties>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
@ -60,8 +78,57 @@
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="fileSizeLabel">
<Properties>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="countLabel">
<Properties>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[159, 12]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[159, 12]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[159, 12]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="isDeletedLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="scoreLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/red-circle-exclamation.png"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -20,9 +20,14 @@ package org.sleuthkit.autopsy.filequery;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
/**
@ -32,6 +37,13 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR
private static final long serialVersionUID = 1L;
private static final Color SELECTION_COLOR = new Color(0, 120, 215);
private static final int ICON_SIZE = 16;
private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png";
private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png";
private static final String DELETE_ICON_PATH = "/org/sleuthkit/autopsy/images/file-icon-deleted.png";
private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false));
private static final ImageIcon NOTABLE_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false));
private static final ImageIcon DELETED_ICON = new ImageIcon(ImageUtilities.loadImage(DELETE_ICON_PATH, false));
/**
* Creates new form ImageThumbnailPanel
@ -53,20 +65,50 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR
thumbnailLabel = new javax.swing.JLabel();
fileSizeLabel = new javax.swing.JLabel();
countLabel = new javax.swing.JLabel();
isDeletedLabel = new javax.swing.JLabel();
scoreLabel = new javax.swing.JLabel();
setToolTipText("");
thumbnailPanel.setToolTipText("");
thumbnailPanel.setLayout(new java.awt.GridBagLayout());
thumbnailPanel.add(thumbnailLabel, new java.awt.GridBagConstraints());
fileSizeLabel.setToolTipText("");
countLabel.setToolTipText("");
countLabel.setMaximumSize(new java.awt.Dimension(159, 12));
countLabel.setMinimumSize(new java.awt.Dimension(159, 12));
countLabel.setPreferredSize(new java.awt.Dimension(159, 12));
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
isDeletedLabel.setToolTipText("");
isDeletedLabel.setMaximumSize(new Dimension(ICON_SIZE,ICON_SIZE));
isDeletedLabel.setMinimumSize(new Dimension(ICON_SIZE,ICON_SIZE));
isDeletedLabel.setPreferredSize(new Dimension(ICON_SIZE,ICON_SIZE));
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
scoreLabel.setToolTipText("");
scoreLabel.setMaximumSize(new Dimension(ICON_SIZE,ICON_SIZE));
scoreLabel.setMinimumSize(new Dimension(ICON_SIZE,ICON_SIZE));
scoreLabel.setPreferredSize(new Dimension(ICON_SIZE,ICON_SIZE));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(thumbnailPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(countLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addComponent(thumbnailPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(countLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
layout.setVerticalGroup(
@ -77,7 +119,10 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(countLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(countLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
@ -86,20 +131,75 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel countLabel;
private javax.swing.JLabel fileSizeLabel;
private javax.swing.JLabel isDeletedLabel;
private javax.swing.JLabel scoreLabel;
private javax.swing.JLabel thumbnailLabel;
// End of variables declaration//GEN-END:variables
@NbBundle.Messages({"# {0} - fileSize",
"ImageThumbnailPanel.sizeLabel.text=Size: {0} bytes",
"# {0} - numberOfInstances",
"ImageThumbnailPanel.countLabel.text=Number of Instances: {0}"})
"ImageThumbnailPanel.countLabel.text=Number of Instances: {0}",
"ImageThumbnailPanel.isDeleted.text=All instances of file are deleted."})
@Override
public Component getListCellRendererComponent(JList<? extends ImageThumbnailWrapper> list, ImageThumbnailWrapper value, int index, boolean isSelected, boolean cellHasFocus) {
fileSizeLabel.setText(Bundle.ImageThumbnailPanel_sizeLabel_text(value.getResultFile().getFirstInstance().getSize()));
countLabel.setText(Bundle.ImageThumbnailPanel_countLabel_text(value.getResultFile().getAllInstances().size()));
thumbnailLabel.setIcon(new ImageIcon(value.getThumbnail()));
if (value.getResultFile().isDeleted()) {
isDeletedLabel.setIcon(DELETED_ICON);
isDeletedLabel.setToolTipText(Bundle.ImageThumbnailPanel_isDeleted_text());
} else {
isDeletedLabel.setIcon(null);
isDeletedLabel.setToolTipText(null);
}
switch (value.getResultFile().getScore()) {
case NOTABLE_SCORE:
scoreLabel.setIcon(NOTABLE_SCORE_ICON);
break;
case INTERESTING_SCORE:
scoreLabel.setIcon(INTERESTING_SCORE_ICON);
break;
case NO_SCORE:
default:
scoreLabel.setIcon(null);
break;
}
scoreLabel.setToolTipText(value.getResultFile().getScoreDescription());
setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
return this;
}
@Override
public String getToolTipText(MouseEvent event) {
if (event != null) {
//gets tooltip of internal panel item mouse is over
Point point = event.getPoint();
for (Component comp : getComponents()) {
if (isPointOnIcon(comp, point)) {
String toolTip = ((JComponent) comp).getToolTipText();
if (toolTip == null || toolTip.isEmpty()) {
return null;
} else {
return toolTip;
}
}
}
}
return null;
}
/**
* Helper method to see if point is on the icon.
*
* @param comp The component to check if the cursor is over the icon of
* @param point The point the cursor is at.
*
* @return True if the point is over the icon, false otherwise.
*/
private boolean isPointOnIcon(Component comp, Point point) {
return comp instanceof JComponent && point.x >= comp.getX() && point.x <= comp.getX() + ICON_SIZE && point.y >= comp.getY() && point.y <= comp.getY() + ICON_SIZE;
}
}

View File

@ -39,6 +39,7 @@ public class ImageThumbnailViewer extends javax.swing.JPanel {
*/
public ImageThumbnailViewer() {
initComponents();
}
/**
@ -83,8 +84,8 @@ public class ImageThumbnailViewer extends javax.swing.JPanel {
* Get the list of AbstractFiles which are represented by the selected image
* thumbnail.
*
* @return The list of AbstractFiles which are represented by the selected image
* thumbnail.
* @return The list of AbstractFiles which are represented by the selected
* image thumbnail.
*/
List<AbstractFile> getInstancesForSelected() {
synchronized (this) {

View File

@ -23,13 +23,25 @@ import org.sleuthkit.datamodel.AbstractFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Container for files that holds all necessary data for grouping and sorting
*/
class ResultFile {
private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
private FileSearchData.Frequency frequency;
private final List<String> keywordListNames;
private final List<String> hashSetNames;
@ -37,7 +49,9 @@ class ResultFile {
private final List<String> interestingSetNames;
private final List<String> objectDetectedNames;
private final List<AbstractFile> instances = new ArrayList<>();
;
private DataResultViewerTable.Score currentScore = DataResultViewerTable.Score.NO_SCORE;
private String scoreDescription = null;
private boolean deleted = false;
private FileType fileType;
/**
@ -48,6 +62,10 @@ class ResultFile {
ResultFile(AbstractFile abstractFile) {
//store the file the ResultFile was created for as the first value in the instances list
instances.add(abstractFile);
if (abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
deleted = true;
}
updateScoreAndDescription(abstractFile);
this.frequency = FileSearchData.Frequency.UNKNOWN;
keywordListNames = new ArrayList<>();
hashSetNames = new ArrayList<>();
@ -82,9 +100,42 @@ class ResultFile {
* @param duplicate The abstract file to add as a duplicate.
*/
void addDuplicate(AbstractFile duplicate) {
if (deleted && !duplicate.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
deleted = false;
}
updateScoreAndDescription(duplicate);
instances.add(duplicate);
}
/**
* Get the aggregate score of this ResultFile. Calculated as the highest
* score among all instances it represents.
*
* @return The score of this ResultFile.
*/
DataResultViewerTable.Score getScore() {
return currentScore;
}
/**
* Get the description for the score assigned to this item.
*
* @return The score description of this ResultFile.
*/
String getScoreDescription() {
return scoreDescription;
}
/**
* Get the aggregate deleted status of this ResultFile. A file is identified
* as deleted if all instances of it are deleted.
*
* @return The deleted status of this ResultFile.
*/
boolean isDeleted() {
return deleted;
}
/**
* Get the list of AbstractFiles which have been identified as instances of
* this file.
@ -271,4 +322,56 @@ class ResultFile {
return this.getFirstInstance().getMd5Hash().equals(((ResultFile) obj).getFirstInstance().getMd5Hash());
}
}
/**
* Get all tags from the case database that are associated with the file
*
* @return a list of tags that are associated with the file
*/
private List<ContentTag> getContentTagsFromDatabase(AbstractFile file) {
List<ContentTag> tags = new ArrayList<>();
try {
tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(file));
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Failed to get tags for file " + file.getName(), ex);
}
return tags;
}
@NbBundle.Messages({
"ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.",
"ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.",
"ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.",
"ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag."})
private void updateScoreAndDescription(AbstractFile file) {
if (currentScore == DataResultViewerTable.Score.NOTABLE_SCORE) {
//already notable can return
return;
}
if (file.getKnown() == TskData.FileKnown.BAD) {
currentScore = DataResultViewerTable.Score.NOTABLE_SCORE;
scoreDescription = Bundle.ResultFile_score_notableFile_description();
return;
}
try {
if (currentScore == DataResultViewerTable.Score.NO_SCORE && !file.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT).isEmpty()) {
currentScore = DataResultViewerTable.Score.INTERESTING_SCORE;
scoreDescription = Bundle.ResultFile_score_interestingResult_description();
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error getting artifacts for file: " + file.getName(), ex);
}
List<ContentTag> tags = getContentTagsFromDatabase(file);
if (!tags.isEmpty()) {
currentScore = DataResultViewerTable.Score.INTERESTING_SCORE;
scoreDescription = Bundle.ResultFile_score_taggedFile_description();
for (Tag tag : tags) {
if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
currentScore = DataResultViewerTable.Score.NOTABLE_SCORE;
scoreDescription = Bundle.ResultFile_score_notableTaggedFile_description();
return;
}
}
}
}
}

View File

@ -24,16 +24,20 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="imagePanel" pref="776" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="imagePanel" alignment="0" pref="776" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="fileSizeLabel" min="-2" pref="248" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="countLabel" min="-2" pref="204" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="countLabel" min="-2" pref="124" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="deletedLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="scoreLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -41,13 +45,17 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="imagePanel" min="-2" pref="220" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="fileSizeLabel" pref="19" max="32767" attributes="0"/>
<Component id="countLabel" max="32767" attributes="0"/>
<Component id="imagePanel" min="-2" pref="140" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="fileSizeLabel" min="-2" pref="19" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="deletedLabel" min="-2" max="-2" attributes="0"/>
<Component id="scoreLabel" min="-2" max="-2" attributes="0"/>
<Component id="countLabel" alignment="1" min="-2" pref="19" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -61,5 +69,37 @@
</Component>
<Component class="javax.swing.JLabel" name="countLabel">
</Component>
<Component class="javax.swing.JLabel" name="scoreLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/red-circle-exclamation.png"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="deletedLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(ICON_SIZE,ICON_SIZE)" type="code"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -20,13 +20,18 @@ package org.sleuthkit.autopsy.filequery;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.GridBagConstraints;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.concurrent.TimeUnit;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle.Messages;
/**
@ -36,6 +41,13 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
private static final int GAP_SIZE = 4;
private static final Color SELECTION_COLOR = new Color(0, 120, 215);
private static final int ICON_SIZE = 16;
private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png";
private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png";
private static final String DELETE_ICON_PATH = "/org/sleuthkit/autopsy/images/file-icon-deleted.png";
private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false));
private static final ImageIcon NOTABLE_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false));
private static final ImageIcon DELETED_ICON = new ImageIcon(ImageUtilities.loadImage(DELETE_ICON_PATH, false));
private static final long serialVersionUID = 1L;
/**
@ -96,11 +108,23 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
imagePanel = new javax.swing.JPanel();
fileSizeLabel = new javax.swing.JLabel();
countLabel = new javax.swing.JLabel();
scoreLabel = new javax.swing.JLabel();
deletedLabel = new javax.swing.JLabel();
setBorder(javax.swing.BorderFactory.createEtchedBorder());
imagePanel.setLayout(new java.awt.GridBagLayout());
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
scoreLabel.setMaximumSize(new Dimension(ICON_SIZE,ICON_SIZE));
scoreLabel.setMinimumSize(new Dimension(ICON_SIZE,ICON_SIZE));
scoreLabel.setPreferredSize(new Dimension(ICON_SIZE,ICON_SIZE));
deletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
deletedLabel.setMaximumSize(new Dimension(ICON_SIZE,ICON_SIZE));
deletedLabel.setMinimumSize(new Dimension(ICON_SIZE,ICON_SIZE));
deletedLabel.setPreferredSize(new Dimension(ICON_SIZE,ICON_SIZE));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@ -112,40 +136,101 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
.addGroup(layout.createSequentialGroup()
.addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 248, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(countLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 204, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(countLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(deletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(imagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(imagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
.addComponent(countLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(deletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(countLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel countLabel;
private javax.swing.JLabel deletedLabel;
private javax.swing.JLabel fileSizeLabel;
private javax.swing.JPanel imagePanel;
private javax.swing.JLabel scoreLabel;
// End of variables declaration//GEN-END:variables
@Messages({"# {0} - fileSize",
"VideoThumbnailPanel.sizeLabel.text=Size: {0} bytes",
"# {0} - numberOfInstances",
"VideoThumbnailPanel.countLabel.text=Number of Instances: {0}"})
"VideoThumbnailPanel.countLabel.text=Number of Instances: {0}",
"VideoThumbnailPanel.deleted.text=All instances of file are deleted."})
@Override
public Component getListCellRendererComponent(JList<? extends VideoThumbnailsWrapper> list, VideoThumbnailsWrapper value, int index, boolean isSelected, boolean cellHasFocus) {
fileSizeLabel.setText(Bundle.VideoThumbnailPanel_sizeLabel_text(value.getResultFile().getFirstInstance().getSize()));
countLabel.setText(Bundle.VideoThumbnailPanel_countLabel_text(value.getResultFile().getAllInstances().size()));
addThumbnails(value);
imagePanel.setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
if (value.getResultFile().isDeleted()) {
deletedLabel.setIcon(DELETED_ICON);
deletedLabel.setToolTipText(Bundle.VideoThumbnailPanel_deleted_text());
} else {
deletedLabel.setIcon(null);
deletedLabel.setToolTipText("");
}
switch (value.getResultFile().getScore()) {
case NOTABLE_SCORE:
scoreLabel.setIcon(NOTABLE_SCORE_ICON);
break;
case INTERESTING_SCORE:
scoreLabel.setIcon(INTERESTING_SCORE_ICON);
break;
case NO_SCORE:
default:
scoreLabel.setIcon(null);
break;
}
scoreLabel.setToolTipText(value.getResultFile().getScoreDescription());
setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
return this;
}
@Override
public String getToolTipText(MouseEvent event) {
if (event != null) {
//gets tooltip of internal panel item mouse is over
Point point = event.getPoint();
for (Component comp : getComponents()) {
if (isPointOnIcon(comp, point)) {
String toolTip = ((JComponent) comp).getToolTipText();
if (toolTip == null || toolTip.isEmpty()) {
return null;
} else {
return toolTip;
}
}
}
}
return null;
}
/**
* Helper method to see if point is on the icon.
*
* @param comp The component to check if the cursor is over the icon of
* @param point The point the cursor is at.
*
* @return True if the point is over the icon, false otherwise.
*/
private boolean isPointOnIcon(Component comp, Point point) {
return comp instanceof JComponent && point.x >= comp.getX() && point.x <= comp.getX() + ICON_SIZE && point.y >= comp.getY() && point.y <= comp.getY() + ICON_SIZE;
}
}