From a60dd923849505aba58bbd08265d63c0d9fcff62 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Thu, 6 Oct 2016 10:06:21 -0400 Subject: [PATCH] Rows initially colored, does not update upon tag addition or reordering --- .../corecomponents/DataResultViewerTable.java | 42 ++++++++++++++++++- .../datamodel/AbstractAbstractFileNode.java | 16 +++++++ .../datamodel/AbstractFsContentNode.java | 5 ++- .../datamodel/BlackboardArtifactNode.java | 18 ++++++++ .../autopsy/datamodel/Bundle.properties | 5 +++ .../autopsy/datamodel/LayoutFileNode.java | 5 ++- .../autopsy/datamodel/LocalFileNode.java | 4 +- 7 files changed, 90 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 8ea3846945..fb7f8acefb 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.corecomponents; +import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.FontMetrics; @@ -41,6 +42,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableColumnModelEvent; import javax.swing.event.TableColumnModelListener; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import org.netbeans.swing.outline.DefaultOutlineModel; import org.openide.explorer.ExplorerManager; @@ -55,6 +57,7 @@ import org.openide.nodes.NodeListener; import org.openide.nodes.NodeMemberEvent; import org.openide.nodes.NodeReorderEvent; import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; @@ -413,7 +416,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { for (int column = 0; column < ov.getOutline().getModel().getColumnCount(); column++) { int firstColumnPadding = (column == 0) ? 32 : 0; - int columnWidthLimit = (column == 0) ? 250 : 350; + int columnWidthLimit = (column == 0) ? 250 : 300; int valuesWidth = 0; // find the maximum width needed to fit the values for the first 30 rows, at most @@ -439,9 +442,44 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); } } + // Node[] childrenNodes = currentRoot.getChildren().getNodes(); + final TableCellRenderer DEFAULT_RENDERER = ov.getOutline().getDefaultRenderer(Object.class); + final Color TAGGED_COLOR = new Color(230, 235, 240); + final Color SELECTED_COLOR = new Color(51, 153, 255); + + + class CustomRenderer extends DefaultTableCellRenderer { + private static final long serialVersionUID = 1L; + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, int row, int col) { + Component component = DEFAULT_RENDERER.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + + if (col != 0) { + try { + int tag_col = ov.getOutline().getColumnModel().getColumnIndex("Tags"); + Property cellProp = (Property)(table.getModel().getValueAt(row, tag_col)); + if (cellProp != null) { + String valueString = cellProp.getValue().toString();//((Property) value).getValue().toString(); + if (!valueString.equals("")) { + component.setBackground(TAGGED_COLOR); + if (isSelected) { + component.setBackground(SELECTED_COLOR); + } + } + } + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { + } + + } + return component; + } + } + ov.getOutline().setDefaultRenderer(Object.class, new CustomRenderer()); + } } - + /** * Store the current column order into a preference file. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 0458ec9a59..f8865898da 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -20,10 +20,13 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.List; import org.openide.nodes.Children; import java.util.Map; import java.util.logging.Level; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; @@ -31,6 +34,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -278,6 +282,18 @@ public abstract class AbstractAbstractFileNode extends A map.put(AbstractFilePropertyType.MIMETYPE.toString(), content.getMIMEType() == null ? "" : content.getMIMEType()); } + static void addTagProperty(Sheet.Set ss, Content content) { + final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); + try { + List tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); + ss.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.name"), + NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); + } + } + static String getContentDisplayName(AbstractFile file) { String name = file.getName(); switch (name) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 5beca1dbc4..82de781b50 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -84,7 +84,10 @@ public abstract class AbstractFsContentNode extends Abst ss.put(new NodeProperty<>(HIDE_PARENT, HIDE_PARENT, HIDE_PARENT, HIDE_PARENT)); } + // add tags property to the sheet + AbstractAbstractFileNode.addTagProperty(ss, content); + return s; } - + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index bee4cba0a8..81c263980f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -25,6 +25,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; +import java.util.stream.Collectors; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Children; @@ -40,9 +41,12 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; +import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.ContentTag; +import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -209,6 +213,20 @@ public class BlackboardArtifactNode extends DisplayableItemNode { ss.put(np); } } + + // add properties for tags + try { + List artifactTags = Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact); + List contentTags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated); + List tags = new ArrayList<>(artifactTags); + tags.addAll(contentTags); + ss.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.name"), + NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + } + final int artifactTypeId = artifact.getArtifactTypeID(); // If mismatch, add props for extension and file type diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties index ffe0797410..3134bd563d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties @@ -281,3 +281,8 @@ DeleteReportAction.actionDisplayName.multipleReports=Delete Reports DeleteReportAction.actionPerformed.showConfirmDialog.title=Confirm Deletion DeleteReportAction.actionPerformed.showConfirmDialog.single.msg=Do you want to delete 1 report from the case? DeleteReportAction.actionPerformed.showConfirmDialog.multiple.msg=Do you want to delete {0} reports from the case? +AbstractAbstractFileNode.addFileProperty.desc=no description +AbstractAbstractFileNode.addFileProperty.tags.name=Tags +AbstractAbstractFileNode.addFileProperty.tags.displayName=Tags +BlackboardArtifactNode.createSheet.tags.name=Tags +BlackboardArtifactNode.createSheet.tags.displayName=Tags \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index 0e97757401..878f0809aa 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.TskData; public class LayoutFileNode extends AbstractAbstractFileNode { public static enum LayoutContentPropertyType { - + PARTS { @Override public String toString() { @@ -86,6 +86,9 @@ public class LayoutFileNode extends AbstractAbstractFileNode { ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } + // add tags property to the sheet + AbstractAbstractFileNode.addTagProperty(ss, content); + return s; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index e2f701d044..9e3c40b595 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -74,7 +74,9 @@ public class LocalFileNode extends AbstractAbstractFileNode { for (Map.Entry entry : map.entrySet()) { ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } - // @@@ add more properties here... + + // add tags property to the sheet + AbstractAbstractFileNode.addTagProperty(ss, content); return s; }