diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED index b9082dd82e..f82411bf9d 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle.properties-MERGED @@ -27,6 +27,7 @@ MessageViewer_columnHeader_To=To MessageViewer_no_messages= MessageViewer_tabTitle=Messages MessageViewer_viewMessage_all=All +MessageViewer_viewMessage_calllogs=Call Logs MessageViewer_viewMessage_selected=Selected MessageViewer_viewMessage_unthreaded=Unthreaded SummaryViewer.countsPanel.border.title=Counts diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java index cc67e10fbd..d34bc084da 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java @@ -48,6 +48,7 @@ import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; class MessageNode extends BlackboardArtifactNode { public static final String UNTHREADED_ID = ""; + public static final String CALL_LOG_ID = ""; private static final Logger logger = Logger.getLogger(MessageNode.class.getName()); @@ -87,9 +88,14 @@ class MessageNode extends BlackboardArtifactNode { sheetSet.put(new NodeProperty<>("Type", Bundle.MessageNode_Node_Property_Type(), "", getDisplayName())); //NON-NLS - sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",threadID == null ? UNTHREADED_ID : threadID)); //NON-NLS + final BlackboardArtifact artifact = getArtifact(); + if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) { + sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",CALL_LOG_ID)); //NON-NLS + } else { + sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",threadID == null ? UNTHREADED_ID : threadID)); //NON-NLS + } BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID()); if (null != fromID) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java index ad8d5eb7b3..4c7be60e80 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java @@ -82,7 +82,8 @@ public class MessageViewer extends JPanel implements RelationshipsViewer { "MessageViewer_no_messages=", "MessageViewer_viewMessage_all=All", "MessageViewer_viewMessage_selected=Selected", - "MessageViewer_viewMessage_unthreaded=Unthreaded",}) + "MessageViewer_viewMessage_unthreaded=Unthreaded", + "MessageViewer_viewMessage_calllogs=Call Logs"}) /** * Creates new form MessageViewer @@ -228,7 +229,11 @@ public class MessageViewer extends JPanel implements RelationshipsViewer { if (!subject.isEmpty()) { threadNameLabel.setText(subject); } else { - threadNameLabel.setText(Bundle.MessageViewer_viewMessage_unthreaded()); + if (threadIDList.contains(MessageNode.CALL_LOG_ID)) { + threadNameLabel.setText(Bundle.MessageViewer_viewMessage_calllogs()); + } else { + threadNameLabel.setText(Bundle.MessageViewer_viewMessage_unthreaded()); + } } showMessagesPane(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessagesChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessagesChildNodeFactory.java index bd2e9e0713..5039ce225e 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessagesChildNodeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessagesChildNodeFactory.java @@ -98,10 +98,16 @@ public class MessagesChildNodeFactory extends ChildFactory{ continue; } - // We want all artifacts that do not have "threadIDs" to appear as one thread in the UI + // We want email and message artifacts that do not have "threadIDs" to appear as one thread in the UI // To achive this assign any artifact that does not have a threadID // the "UNTHREADED_ID" - String artifactThreadID = MessageNode.UNTHREADED_ID; + // All call logs will default to a single call logs thread + String artifactThreadID; + if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG) { + artifactThreadID = MessageNode.CALL_LOG_ID; + } else { + artifactThreadID = MessageNode.UNTHREADED_ID; + } BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID)); if(attribute != null) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadChildNodeFactory.java index 0fb6433ca7..1cf987d132 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadChildNodeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadChildNodeFactory.java @@ -123,10 +123,16 @@ final class ThreadChildNodeFactory extends ChildFactory { || fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG || fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) { - // We want all artifacts that do not have "threadIDs" to appear as one thread in the UI + // We want email and message artifacts that do not have "threadIDs" to appear as one thread in the UI // To achive this assign any artifact that does not have a threadID // the "UNTHREADED_ID" - String threadID = MessageNode.UNTHREADED_ID; + // All call logs will default to a single call logs thread + String threadID; + if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG) { + threadID = MessageNode.CALL_LOG_ID; + } else { + threadID = MessageNode.UNTHREADED_ID; + } BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID)); if(attribute != null) { @@ -170,13 +176,46 @@ final class ThreadChildNodeFactory extends ChildFactory { if (attribute != null) { return new ThreadNode(bba, attribute.getValueString(), preferredAction); } else { - // Only one of these should occur. - return new UnthreadedNode(); + if (bba.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) { + return new CallLogNode(); + } else { + // Only one of these should occur. + return new UnthreadedNode(); + } } } /** - * An this node represents the "unthreaded" thread. + * This node represents the "call log" thread. + */ + final class CallLogNode extends AbstractNode { + /** + * Construct an instance of a CallLogNode. + */ + CallLogNode() { + super(Children.LEAF); + setDisplayName("Call Logs"); + this.setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/unthreaded.png" ); + } + + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + if (sheetSet == null) { + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + // Give this node a threadID of "CALL_LOG_ID" + sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",MessageNode.CALL_LOG_ID)); + + return sheet; + } + } + + /** + * This node represents the "unthreaded" thread. */ final class UnthreadedNode extends AbstractNode { /** diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadNode.java index f398b94757..013730a097 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadNode.java @@ -25,7 +25,7 @@ import org.openide.nodes.Sheet; import org.sleuthkit.datamodel.BlackboardArtifact; /** - * An AbstractNode subclass which wraps a MessagNode object. Doing this allows + * An AbstractNode subclass which wraps a MessageNode object. Doing this allows * for the reuse of the createSheet and other function from MessageNode, but * also some customizing of how a ThreadNode is shown. */