diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 70fb3bc757..6665c2e958 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -39,4 +39,3 @@ VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic VisualizationPanel.hierarchyLayoutButton.text=Hierarchical VisualizationPanel.clearVizButton.text_1=Clear Viz. VisualizationPanel.snapshotButton.text_1=Snapshot Report -ContactsViewer.testLabel.text=No Value Set diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties-MERGED index e5f00998a6..1716b3c7e8 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties-MERGED @@ -89,7 +89,6 @@ VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic VisualizationPanel.hierarchyLayoutButton.text=Hierarchical VisualizationPanel.clearVizButton.text_1=Clear Viz. VisualizationPanel.snapshotButton.text_1=Snapshot Report -ContactsViewer.testLabel.text=No Value Set VisualizationPanel_action_dialogs_title=Communications VisualizationPanel_action_name_text=Snapshot Report VisualizationPanel_module_name=Communications diff --git a/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.form b/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.form index 81e1e314ef..e7e306cf63 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.form +++ b/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.form @@ -16,30 +16,13 @@ - - - - - + - - - - - + - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.java b/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.java index 1808c8bb62..0473ba0e13 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/ContactsViewer.java @@ -59,30 +59,19 @@ public class ContactsViewer extends JPanel implements RelationshipsViewer{ // //GEN-BEGIN:initComponents private void initComponents() { - testLabel = new javax.swing.JLabel(); - - org.openide.awt.Mnemonics.setLocalizedText(testLabel, org.openide.util.NbBundle.getMessage(ContactsViewer.class, "ContactsViewer.testLabel.text")); // NOI18N - 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() - .addComponent(testLabel) - .addContainerGap(294, Short.MAX_VALUE)) + .addGap(0, 692, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(testLabel) - .addContainerGap(264, Short.MAX_VALUE)) + .addGap(0, 573, Short.MAX_VALUE) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel testLabel; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageNode.java b/Core/src/org/sleuthkit/autopsy/communications/MessageNode.java index ff64185d25..d5cacb403f 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageNode.java @@ -18,15 +18,16 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.List; import java.util.TimeZone; import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.openide.util.NbBundle.Messages; -import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -39,37 +40,22 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHO import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT; import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME; +import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TimeUtilities; import org.sleuthkit.datamodel.TskCoreException; /** * Wraps a BlackboardArtifact as an AbstractNode for use in an OutlookView */ -final class MessageNode extends AbstractNode { +final class MessageNode extends BlackboardArtifactNode { private static final Logger logger = Logger.getLogger(RelationshipNode.class.getName()); - private final BlackboardArtifact artifact; - MessageNode(BlackboardArtifact artifact) { - super(Children.LEAF, Lookups.fixed(artifact)); - this.artifact = artifact; + super(artifact); final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); // NON-NLS String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); // NON-NLS setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase); - - int typeID = artifact.getArtifactTypeID(); - - String filePath = "org/sleuthkit/autopsy/images/"; //NON-NLS - if( typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { - filePath = filePath + "mail-icon-16.png"; //NON-NLS - } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { - filePath = filePath + "message.png"; //NON-NLS - } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) { - filePath = filePath + "calllog.png"; //NON-NLS - } - - setIconBaseWithExtension(filePath); } @Messages({ @@ -84,6 +70,7 @@ final class MessageNode extends AbstractNode { @Override protected Sheet createSheet() { Sheet sheet = new Sheet(); + List tags = getAllTagsFromDatabase(); Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); if (sheetSet == null) { sheetSet = Sheet.createPropertiesSet(); @@ -92,6 +79,19 @@ final class MessageNode extends AbstractNode { sheetSet.put(new NodeProperty<>("Type", Bundle.MessageNode_Node_Property_Type(), "", getDisplayName())); //NON-NLS + addScoreProperty(sheetSet, tags); + + CorrelationAttributeInstance correlationAttribute = null; + if (UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) { + addCountProperty(sheetSet, correlationAttribute); + } + final BlackboardArtifact artifact = getArtifact(); + BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID()); if (null != fromID) { //Consider refactoring this to reduce boilerplate @@ -170,4 +170,15 @@ final class MessageNode extends AbstractNode { return ""; } } + + /** + * Circumvent DataResultFilterNode's slightly odd delegation to + * BlackboardArtifactNode.getSourceName(). + * + * @return the displayName of this Node, which is the type. + */ + @Override + public String getSourceName() { + return getDisplayName(); + } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.form b/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.form index a8a0606f8f..7368b264e5 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.form +++ b/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.form @@ -16,14 +16,16 @@ - + + - - + + + @@ -31,5 +33,10 @@ + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.java b/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.java index b5b5159aa3..e58bf3a39c 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessagesViewer.java @@ -18,28 +18,36 @@ */ package org.sleuthkit.autopsy.communications; +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import javax.swing.JPanel; import javax.swing.ListSelectionModel; +import static javax.swing.SwingUtilities.isDescendingFrom; import org.netbeans.swing.outline.DefaultOutlineModel; import org.netbeans.swing.outline.Outline; import org.openide.explorer.ExplorerManager; -import org.openide.explorer.ExplorerUtils; +import static org.openide.explorer.ExplorerUtils.createLookup; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; +import org.openide.nodes.Node; import org.openide.util.Lookup; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; /** * Visualation for the messages of the currently selected accounts. */ -@ServiceProvider(service=RelationshipsViewer.class) -public class MessagesViewer extends JPanel implements RelationshipsViewer, ExplorerManager.Provider, Lookup.Provider { +@ServiceProvider(service = RelationshipsViewer.class) +public class MessagesViewer extends JPanel implements RelationshipsViewer, ExplorerManager.Provider, Lookup.Provider{ - private final ExplorerManager tableEM = new ExplorerManager(); - private final Lookup lookup; + private final ExplorerManager tableEM; private final Outline outline; - + private final ModifiableProxyLookup proxyLookup; + private final PropertyChangeListener focusPropertyListener; + @Messages({ "MessageViewer_tabTitle=Messages", "MessageViewer_columnHeader_From=From", @@ -48,13 +56,36 @@ public class MessagesViewer extends JPanel implements RelationshipsViewer, Explo "MessageViewer_columnHeader_Subject=Subject", "MessageViewer_columnHeader_Attms=Attachments" }) - + /** * Creates new form MessagesViewer */ public MessagesViewer() { + tableEM = new ExplorerManager(); + proxyLookup = new ModifiableProxyLookup(createLookup(tableEM, getActionMap())); + + // See org.sleuthkit.autopsy.timeline.TimeLineTopComponent for a detailed + // explaination of focusPropertyListener + focusPropertyListener = (final PropertyChangeEvent focusEvent) -> { + if (focusEvent.getPropertyName().equalsIgnoreCase("focusOwner")) { + final Component newFocusOwner = (Component) focusEvent.getNewValue(); + + if (newFocusOwner == null) { + return; + } + if (isDescendingFrom(newFocusOwner, contentViewer)) { + //if the focus owner is within the MessageContentViewer (the attachments table) + proxyLookup.setNewLookups(createLookup(((MessageDataContent) contentViewer).getExplorerManager(), getActionMap())); + } else if (isDescendingFrom(newFocusOwner, MessagesViewer.this)) { + //... or if it is within the Results table. + proxyLookup.setNewLookups(createLookup(tableEM, getActionMap())); + + } + } + } ; + initComponents(); - + outline = outlineView.getOutline(); outlineView.setPropertyColumns( "From", Bundle.MessageViewer_columnHeader_From(), @@ -62,38 +93,60 @@ public class MessagesViewer extends JPanel implements RelationshipsViewer, Explo "Date", Bundle.MessageViewer_columnHeader_Date(), "Subject", Bundle.MessageViewer_columnHeader_Subject(), "Attms", Bundle.MessageViewer_columnHeader_Attms() - ); outline.setRootVisible(false); outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.AccountNode_accountName()); - - lookup = ExplorerUtils.createLookup(tableEM, getActionMap()); + + tableEM.addPropertyChangeListener((PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { + final Node[] nodes = tableEM.getSelectedNodes(); + + if (nodes != null && nodes.length > 0) { + contentViewer.setNode(nodes[0]); + } + } + }); } - + @Override public String getDisplayName() { return Bundle.MessageViewer_tabTitle(); } - + @Override public JPanel getPanel() { return this; } - + @Override public void setSelectionInfo(SelectionInfo info) { - tableEM.setRootContext(new AbstractNode(Children.create(new MessagesChildNodeFactory(info), true))); + tableEM.setRootContext(new DataResultFilterNode(new AbstractNode(Children.create(new MessagesChildNodeFactory(info), true)), getExplorerManager())); } - - @Override + + @Override public ExplorerManager getExplorerManager() { return tableEM; } - + @Override public Lookup getLookup() { - return lookup; + return proxyLookup; + } + + @Override + public void addNotify() { + super.addNotify(); + //add listener that maintains correct selection in the Global Actions Context + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .addPropertyChangeListener("focusOwner", focusPropertyListener); + } + + @Override + public void removeNotify() { + super.removeNotify(); + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .removePropertyChangeListener("focusOwner", focusPropertyListener); } /** @@ -106,23 +159,27 @@ public class MessagesViewer extends JPanel implements RelationshipsViewer, Explo private void initComponents() { outlineView = new org.openide.explorer.view.OutlineView(); + contentViewer = new MessageDataContent(); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 480, Short.MAX_VALUE) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(contentViewer, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(outlineView, javax.swing.GroupLayout.PREFERRED_SIZE, 475, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 16, Short.MAX_VALUE)) + .addComponent(outlineView, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(contentViewer, javax.swing.GroupLayout.DEFAULT_SIZE, 778, Short.MAX_VALUE)) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables + private org.sleuthkit.autopsy.contentviewers.MessageContentViewer contentViewer; private org.openide.explorer.view.OutlineView outlineView; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelaionshipSetNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/RelaionshipSetNodeFactory.java deleted file mode 100644 index ac2e5d1c54..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/RelaionshipSetNodeFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2017-2019 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.communications; - -import java.util.Collection; -import java.util.List; -import org.openide.nodes.ChildFactory; -import org.openide.nodes.Node; -import org.sleuthkit.datamodel.BlackboardArtifact; - -/** - * - */ -public class RelaionshipSetNodeFactory extends ChildFactory { - - private final Collection artifacts; - - public RelaionshipSetNodeFactory(Collection artifacts) { - this.artifacts = artifacts; - } - - @Override - protected boolean createKeys(List list) { - list.addAll(artifacts); - return true; - } - - @Override - protected Node createNodeForKey(BlackboardArtifact key) { - return new RelationshipNode(key); - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.form index 7b6fa1d18f..a664317372 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.form +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.form @@ -27,6 +27,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.java index c934ebade9..6f60981278 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationshipBrowser.java @@ -27,6 +27,8 @@ import org.openide.util.Lookup; */ public class RelationshipBrowser extends JPanel { + private SelectionInfo currentSelection; + /** * Creates new form RelationshipBrowser */ @@ -38,11 +40,15 @@ public class RelationshipBrowser extends JPanel { }); } + /** + * Sets the value of currentSelection and passes the SelectionInfo onto + * the currently selected\visible tab. + * + * @param info Currently selected account nodes + */ public void setSelectionInfo(SelectionInfo info) { + currentSelection = info; ((RelationshipsViewer)tabPane.getSelectedComponent()).setSelectionInfo(info); - - // TODO If we only pass the info to the currently selected tab, we - // need to do something when the tab changes } /** @@ -56,6 +62,12 @@ public class RelationshipBrowser extends JPanel { tabPane = new javax.swing.JTabbedPane(); + tabPane.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + tabPaneStateChanged(evt); + } + }); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -68,6 +80,10 @@ public class RelationshipBrowser extends JPanel { ); }// //GEN-END:initComponents + private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged + ((RelationshipsViewer)tabPane.getSelectedComponent()).setSelectionInfo(currentSelection); + }//GEN-LAST:event_tabPaneStateChanged + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTabbedPane tabPane;