diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/CommunicationArtifactViewerHelper.java b/Core/src/org/sleuthkit/autopsy/contentviewers/CommunicationArtifactViewerHelper.java
index e6b59f093d..64f9799266 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/CommunicationArtifactViewerHelper.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/CommunicationArtifactViewerHelper.java
@@ -182,7 +182,7 @@ public final class CommunicationArtifactViewerHelper {
* @param gridbagLayout Layout to use.
* @param constraints Constrains to use.
*/
- private static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
+ static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
constraints.gridy++;
constraints.gridx = 0;
@@ -194,25 +194,44 @@ public final class CommunicationArtifactViewerHelper {
}
/**
- * Adds a label/key to the panel.
+ * Adds a label/key to the panel at col 0.
*
* @param panel Panel to update.
* @param gridbagLayout Layout to use.
* @param constraints Constrains to use.
* @param keyString Key name to display.
+ *
+ * @return Label added.
*/
- static void addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) {
-
+ static JLabel addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) {
+ return addKeyAtCol(panel, gridbagLayout, constraints, keyString, 0 );
+ }
+
+ /**
+ * Adds a label/key to the panel at specified column.
+ *
+ * @param panel Panel to update.
+ * @param gridbagLayout Layout to use.
+ * @param constraints Constrains to use.
+ * @param keyString Key name to display.
+ * @param gridx column index, must be less than MAX_COLS - 1.
+ *
+ * @return Label added.
+ */
+ static JLabel addKeyAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString, int gridx ) {
+
+ // create label
+ javax.swing.JLabel keyLabel = new javax.swing.JLabel();
+
constraints.gridy++;
- constraints.gridx = 0;
+ constraints.gridx = gridx < MAX_COLS - 1? gridx : MAX_COLS - 2;
Insets savedInsets = constraints.insets;
// Set inset to indent in
constraints.insets = new java.awt.Insets(0, LEFT_INDENT, 0, 0);
- // create label,
- javax.swing.JLabel keyLabel = new javax.swing.JLabel();
+ // set text
keyLabel.setText(keyString + ": ");
// add to panel
@@ -221,27 +240,47 @@ public final class CommunicationArtifactViewerHelper {
// restore inset
constraints.insets = savedInsets;
+
+ return keyLabel;
}
/**
- * Adds a value string to the panel.
+ * Adds a value string to the panel at col 1.
*
* @param panel Panel to update.
* @param gridbagLayout Layout to use.
* @param constraints Constrains to use.
* @param keyString Value string to display.
+ *
+ * @return Label added.
*/
- static void addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) {
-
- constraints.gridx = 1;
+ static JLabel addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) {
+ return addValueAtCol(panel, gridbagLayout, constraints, valueString, 1);
+ }
+
+ /**
+ * Adds a value string to the panel at col 1.
+ *
+ * @param panel Panel to update.
+ * @param gridbagLayout Layout to use.
+ * @param constraints Constrains to use.
+ * @param keyString Value string to display.
+ * @param gridx Column index, must be less than MAX_COLS;
+ *
+ * @return Label added.
+ */
+ static JLabel addValueAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString, int gridx) {
+ // create label,
+ javax.swing.JLabel valueField = new javax.swing.JLabel();
+
+ constraints.gridx = gridx < MAX_COLS ? gridx : MAX_COLS - 1 ;
int savedGridwidth = constraints.gridwidth;
// let the value span 2 cols
constraints.gridwidth = 2;
- // create label,
- javax.swing.JLabel valueField = new javax.swing.JLabel();
+ // set text
valueField.setText(valueString);
// attach a right click menu with Copy option
@@ -261,6 +300,8 @@ public final class CommunicationArtifactViewerHelper {
// end the line
addLineEndGlue(panel, gridbagLayout, constraints);
+
+ return valueField;
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewer.java
index 0e7f47e7a4..7d67dfc5e0 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewer.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewer.java
@@ -541,11 +541,11 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
}
@NbBundle.Messages({
- "ContactArtifactViewer_persona_label=Persona ",
- "ContactArtifactViewer_persona_text_none=None found",
- "ContactArtifactViewer_persona_button_view=View",
- "ContactArtifactViewer_persona_button_new=Create",
- "ContactArtifactViewer_missing_account_label=Missing Account: "
+ //"ContactArtifactViewer_persona_label=Persona ",
+ //"ContactArtifactViewer_persona_text_none=None found",
+ //"ContactArtifactViewer_persona_button_view=View",
+ //"ContactArtifactViewer_persona_button_new=Create",
+ //"ContactArtifactViewer_missing_account_label=Missing Account: "
})
/**
@@ -827,7 +827,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
}
@NbBundle.Messages({
- "ContactArtifactViewer_persona_account_justification=Account found in Contact artifact"
+ // "ContactArtifactViewer_persona_account_justification=Account found in Contact artifact"
})
@Override
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.form b/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.form
index 806a0e3de5..0a86676ba7 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.form
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.form
@@ -18,4 +18,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.java b/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.java
index ccf0755f5c..cedf42544e 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/ContactArtifactViewerNew.java
@@ -1,13 +1,28 @@
/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2020 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.contentviewers;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -23,8 +38,8 @@ import java.util.logging.Level;
import java.util.stream.Collectors;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
+import javax.swing.JButton;
import javax.swing.JLabel;
-import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;
import org.apache.commons.lang.StringUtils;
@@ -35,6 +50,10 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
+import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
+import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
+import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
+import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
@@ -43,23 +62,28 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
/**
- *
- * @author raman
+ * This class displays the TSK_CONTACT artifact.
*/
@ServiceProvider(service = ArtifactContentViewer.class)
public class ContactArtifactViewerNew extends javax.swing.JPanel implements ArtifactContentViewer {
private final static Logger logger = Logger.getLogger(ContactArtifactViewer.class.getName());
private static final long serialVersionUID = 1L;
-
- private GridBagLayout m_gridBagLayout = new GridBagLayout();
- private GridBagConstraints m_constraints = new GridBagConstraints();
-
- // contact name, if available.
- private String contactName; // TBD: is this really needed as class member?
-
- //private javax.swing.JLabel contactImage; // TBD: is this really needed as class member?
-
+
+ private final static int LEFT_INSET = 12;
+
+ //private GridBagLayout m_gridBagLayout = new GridBagLayout();
+ //private GridBagConstraints m_constraints = new GridBagConstraints();
+ private BlackboardArtifact contactArtifact;
+ private String contactName;
+ private String datasourceName;
+
+ private List phoneNumList = new ArrayList<>();
+ private List emailList = new ArrayList<>();
+ private List nameList = new ArrayList<>();
+ private List otherList = new ArrayList<>();
+ private List accountAttributesList = new ArrayList<>();
+
private final static String DEFAULT_IMAGE_PATH = "/org/sleuthkit/autopsy/images/defaultContact.png";
private final ImageIcon defaultImage;
@@ -70,14 +94,14 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
// account identifier attributes of the Contact artifact.
private final Map> contactUniquePersonasMap = new HashMap<>();
- privbate ContactPersonaSearcherTask personaSearchTask;
-
+ private ContactPersonaSearcherTask personaSearchTask;
+
/**
- * Creates new form ContactArtifactViewerNew
+ * Creates new form ContactArtifactViewer
*/
public ContactArtifactViewerNew() {
initComponents();
-
+
defaultImage = new ImageIcon(ContactArtifactViewer.class.getResource(DEFAULT_IMAGE_PATH));
}
@@ -89,9 +113,45 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
@SuppressWarnings("unchecked")
// //GEN-BEGIN:initComponents
private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ contactDetailsPanel = new javax.swing.JPanel();
+ personasPanel = new javax.swing.JPanel();
+ sourcePanel = new javax.swing.JPanel();
+ filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
setToolTipText(""); // NOI18N
setLayout(new java.awt.GridBagLayout());
+
+ contactDetailsPanel.setLayout(new java.awt.GridBagLayout());
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ add(contactDetailsPanel, gridBagConstraints);
+
+ personasPanel.setLayout(new java.awt.GridBagLayout());
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ add(personasPanel, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ add(sourcePanel, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(filler1, gridBagConstraints);
}// //GEN-END:initComponents
@Override
@@ -103,55 +163,15 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
return;
}
- List phoneNumList = new ArrayList<>();
- List emailList = new ArrayList<>();
- List nameList = new ArrayList<>();
- List otherList = new ArrayList<>();
- List accountAttributesList = new ArrayList<>();
- String datasourceName;
-
try {
- // Get all the attributes and group them by the section panels they go in
- for (BlackboardAttribute bba : artifact.getAttributes()) {
- if (bba.getAttributeType().getTypeName().startsWith("TSK_PHONE")) {
- phoneNumList.add(bba);
- accountAttributesList.add(bba);
- } else if (bba.getAttributeType().getTypeName().startsWith("TSK_EMAIL")) {
- emailList.add(bba);
- accountAttributesList.add(bba);
- } else if (bba.getAttributeType().getTypeName().startsWith("TSK_NAME")) {
- nameList.add(bba);
- } else {
- otherList.add(bba);
- if (bba.getAttributeType().getTypeName().equalsIgnoreCase("TSK_ID")) {
- accountAttributesList.add(bba);
- }
- }
- }
-
- datasourceName = artifact.getDataSource().getName();
+ extractArtifactData(artifact);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
return;
}
-
-
- updateContactImage(artifact);
-
- // update name section
- updateContactName(nameList);
- // update contact attributes sections
- updateSection(phoneNumList, "Phones");
- updateSection(emailList, "Emails");
- updateSection(otherList, "Others");
-
- updateSource(datasourceName);
-
- CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
-
- // repaint
- this.setLayout(m_gridBagLayout);
+ updateView();
+
this.revalidate();
this.repaint();
}
@@ -167,85 +187,199 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
return artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID();
}
-
+ /**
+ * Extracts data from the artifact to be displayed in the panel.
+ *
+ * @param artifact Artifact to show.
+ * @throws TskCoreException
+ */
+ private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException {
+
+ this.contactArtifact = artifact;
+
+ phoneNumList = new ArrayList<>();
+ emailList = new ArrayList<>();
+ nameList = new ArrayList<>();
+ otherList = new ArrayList<>();
+ accountAttributesList = new ArrayList<>();
+
+ // Get all the attributes and group them by the section panels they go in
+ for (BlackboardAttribute bba : contactArtifact.getAttributes()) {
+ if (bba.getAttributeType().getTypeName().startsWith("TSK_PHONE")) {
+ phoneNumList.add(bba);
+ accountAttributesList.add(bba);
+ } else if (bba.getAttributeType().getTypeName().startsWith("TSK_EMAIL")) {
+ emailList.add(bba);
+ accountAttributesList.add(bba);
+ } else if (bba.getAttributeType().getTypeName().startsWith("TSK_NAME")) {
+ nameList.add(bba);
+ } else {
+ otherList.add(bba);
+ if (bba.getAttributeType().getTypeName().equalsIgnoreCase("TSK_ID")) {
+ accountAttributesList.add(bba);
+ }
+ }
+ }
+
+ datasourceName = contactArtifact.getDataSource().getName();
+ }
+
+ /**
+ * Updates the view with the data extracted from the artifact.
+ */
+ private void updateView() {
+
+ // Update contact name, image, phone numbers
+ updateContactDetails();
+
+ // show a empty Personas panel and kick off a serch for personas
+ initiatePersonasSearch();
+
+ // update artifact source panel
+ updateSource();
+ }
+
+ /**
+ * Updates the view with contact's details.
+ */
+ @NbBundle.Messages({
+ "ContactArtifactViewer_phones_header=Phone",
+ "ContactArtifactViewer_eamils_header=Email",
+ "ContactArtifactViewer_others_header=Other",})
+ private void updateContactDetails() {
+ GridBagLayout contactPanelLayout = new GridBagLayout();
+ GridBagConstraints contactPanelConstraints = new GridBagConstraints();
+
+ contactPanelConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
+ contactPanelConstraints.gridy = 0;
+ contactPanelConstraints.gridx = 0;
+ contactPanelConstraints.weighty = 0.05;
+ contactPanelConstraints.weightx = 0.05;
+ contactPanelConstraints.insets = new java.awt.Insets(0, 0, 0, 0);
+ contactPanelConstraints.fill = GridBagConstraints.NONE;
+
+ updateContactImage(contactPanelLayout, contactPanelConstraints);
+
+ // update name section
+ updateContactName(contactPanelLayout, contactPanelConstraints);
+
+ // update contact attributes sections
+ updateContactMethodSection(phoneNumList, Bundle.ContactArtifactViewer_phones_header(), contactPanelLayout, contactPanelConstraints);
+ updateContactMethodSection(emailList, Bundle.ContactArtifactViewer_eamils_header(), contactPanelLayout, contactPanelConstraints);
+ updateContactMethodSection(otherList, Bundle.ContactArtifactViewer_others_header(), contactPanelLayout, contactPanelConstraints);
+
+ CommunicationArtifactViewerHelper.addBlankLine(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints);
+
+ contactDetailsPanel.setLayout(contactPanelLayout);
+ contactDetailsPanel.revalidate();
+ contactDetailsPanel.repaint();
+ }
+
/**
* Updates the contact image in the view.
*
* @param artifact
*/
@NbBundle.Messages({
- "ContactArtifactViewer.contactImage.text=",
- })
- private void updateContactImage(BlackboardArtifact artifact) {
-
+ "ContactArtifactViewer.contactImage.text=",})
+ private void updateContactImage(GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
+
+ contactPanelConstraints.gridy = 0;
+ contactPanelConstraints.gridx = 0;
+
javax.swing.JLabel contactImage = new javax.swing.JLabel();
-
- contactImage.setIcon(getImageFromArtifact(artifact));
-
+
+ contactImage.setIcon(getImageFromArtifact(contactArtifact));
+
contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text());
-
+
// add image to top left corner of the page.
- CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, this.m_constraints, contactImage);
- m_constraints.gridy++;
+ CommunicationArtifactViewerHelper.addComponent(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints, contactImage);
+ contactPanelConstraints.gridy++;
}
-
+
/**
* Updates the contact name in the view from the list of attributes.
*
- * @param attributesList List of attributes that might have the contact name.
+ * @param attributesList List of attributes that might have the contact
+ * name.
*/
@NbBundle.Messages({
- "ContactArtifactViewer_contactname_unknown=Unknown",
- })
- private void updateContactName(List nameAttributesList) {
+ "ContactArtifactViewer_contactname_unknown=Unknown",})
+ private void updateContactName(GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
+
boolean foundName = false;
- for (BlackboardAttribute bba : nameAttributesList) {
+ for (BlackboardAttribute bba : this.nameList) {
if (StringUtils.isEmpty(bba.getValueString()) == false) {
contactName = bba.getDisplayString();
-
- // TBD: need to increase the font size of the page header by 2
- CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, contactName);
- foundName = true;
+
+ CommunicationArtifactViewerHelper.addHeader(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints, contactName);
+ foundName = true;
break;
}
}
- if (foundName== false) {
- CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.ContactArtifactViewer_contactname_unknown());
+ if (foundName == false) {
+ CommunicationArtifactViewerHelper.addHeader(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints, Bundle.ContactArtifactViewer_contactname_unknown());
}
}
-
- /**
+
+ /**
* Updates the view by displaying the given list of attributes in the given
* section panel.
*
* @param sectionAttributesList list of attributes to display.
- * @param sectionLabel section name label.
+ * @param sectionLabel section name label.
*/
- private void updateSection(List sectionAttributesList, String sectionHeader) {
+ @NbBundle.Messages({
+ "ContactArtifactViewer_plural_suffix=s",})
+ private void updateContactMethodSection(List sectionAttributesList, String sectionHeader, GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
// If there are no attributes for this section, do nothing
if (sectionAttributesList.isEmpty()) {
return;
}
- CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, sectionHeader);
+ String sectionHeaderString = sectionHeader;
+ if (sectionAttributesList.size() > 1) {
+ sectionHeaderString = sectionHeaderString.concat(Bundle.ContactArtifactViewer_plural_suffix());
+ }
+ CommunicationArtifactViewerHelper.addHeader(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints, sectionHeaderString);
for (BlackboardAttribute bba : sectionAttributesList) {
- CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, bba.getAttributeType().getDisplayName());
- CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, bba.getDisplayString());
+ CommunicationArtifactViewerHelper.addKey(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName());
+ CommunicationArtifactViewerHelper.addValue(this.contactDetailsPanel, contactPanelLayout, contactPanelConstraints, bba.getDisplayString());
}
}
-
+
+ /**
+ * Updates the source section.
+ */
@NbBundle.Messages({
"ContactArtifactViewer_heading_Source=Source",
"ContactArtifactViewer_label_datasource=Data Source",})
- private void updateSource(String datasourceName) {
- CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.ContactArtifactViewer_heading_Source());
- CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.ContactArtifactViewer_label_datasource());
- CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, datasourceName);
+ private void updateSource() {
+
+ GridBagLayout sourcePanelLayout = new GridBagLayout();
+ GridBagConstraints sourcePanelConstraints = new GridBagConstraints();
+
+ sourcePanelConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
+ sourcePanelConstraints.gridy = 0;
+ sourcePanelConstraints.gridx = 0;
+ sourcePanelConstraints.weighty = 0.05;
+ sourcePanelConstraints.weightx = 0.05;
+ sourcePanelConstraints.insets = new java.awt.Insets(0, 0, 0, 0);
+ sourcePanelConstraints.fill = GridBagConstraints.NONE;
+
+ CommunicationArtifactViewerHelper.addHeader(this.sourcePanel, sourcePanelLayout, sourcePanelConstraints, Bundle.ContactArtifactViewer_heading_Source());
+ CommunicationArtifactViewerHelper.addKey(this.sourcePanel, sourcePanelLayout, sourcePanelConstraints, Bundle.ContactArtifactViewer_label_datasource());
+ CommunicationArtifactViewerHelper.addValue(this.sourcePanel, sourcePanelLayout, sourcePanelConstraints, datasourceName);
+
+ sourcePanel.setLayout(sourcePanelLayout);
+ sourcePanel.revalidate();
+ sourcePanel.repaint();
}
-
- /**
+
+ /**
* Kicks off a search for personas, based in the given list of attributes.
*
* @param accountAttributesList a list of account identifying attributes.
@@ -253,59 +387,77 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
* @throws CentralRepoException
*/
@NbBundle.Messages({
- "ContactArtifactViewer_persona_searching= Persona",
- "ContactArtifactViewer_persona_searching= Searching...",
- "ContactArtifactViewer_persona_unknown=Unknown"
+ "ContactArtifactViewer_persona_header=Persona", //"ContactArtifactViewer_persona_searching = Searching...",
+ //"ContactArtifactViewer_persona_unknown=Unknown"
})
- private void initiatePersonasSearch(List accountAttributesList) throws CentralRepoException {
- JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.ContactArtifactViewer_persona_searching());
-
- //CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.ContactArtifactViewer_label_datasource());
-
-
- personasLabel.setVisible(true);
+ private void initiatePersonasSearch() {
- String personaStatusLabelText = CentralRepository.isEnabled()
- ? Bundle.ContactArtifactViewer_persona_searching()
+ GridBagLayout personasPanelLayout = new GridBagLayout();
+ GridBagConstraints personasPanelConstraints = new GridBagConstraints();
+
+ personasPanelConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
+ personasPanelConstraints.gridy = 0;
+ personasPanelConstraints.gridx = 0;
+ personasPanelConstraints.weighty = 0.05;
+ personasPanelConstraints.weightx = 0.05;
+ personasPanelConstraints.insets = new java.awt.Insets(0, 0, 0, 0);
+ personasPanelConstraints.fill = GridBagConstraints.NONE;
+
+ // add a section header
+ JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this.personasPanel, personasPanelLayout, personasPanelConstraints, Bundle.ContactArtifactViewer_persona_header());
+
+ personasPanelConstraints.gridy++;
+
+ // add a status label
+ String personaStatusLabelText = CentralRepository.isEnabled()
+ ? Bundle.ContactArtifactViewer_persona_searching()
: Bundle.ContactArtifactViewer_persona_unknown();
-
-
-
+ javax.swing.JLabel statusLabel = new javax.swing.JLabel();
+ statusLabel.setText(personaStatusLabelText);
-
- if (CentralRepository.isEnabled() ) {
-
-
+ CommunicationArtifactViewerHelper.addComponent(this.personasPanel, personasPanelLayout, personasPanelConstraints, statusLabel);
+
+ // End of panel, add a blank line
+ CommunicationArtifactViewerHelper.addBlankLine(this.personasPanel, personasPanelLayout, personasPanelConstraints);
+
+ if (CentralRepository.isEnabled()) {
// Kick off a background task to serach for personas for the contact
- ContactPersonaSearcherTask personaSearchTask = new ContactPersonaSearcherTask(accountAttributesList);
+ personaSearchTask = new ContactPersonaSearcherTask(accountAttributesList);
personaSearchTask.execute();
} else {
personaHeader.setEnabled(false);
-
- // RAMAN TBD: add a Unknown diabled label at gridx=1;
+ statusLabel.setEnabled(false);
}
-
+ personasPanel.setLayout(personasPanelLayout);
+ personasPanel.revalidate();
+ personasPanel.repaint();
+
}
-
+
/**
* Updates the Persona panel with the gathered persona information.
*/
- private void updatePersonasPanel() {
+ private void updatePersonas() {
// Clear out the panel
personasPanel.removeAll();
- GridBagLayout gridBagLayout = new GridBagLayout();
- GridBagConstraints constraints = new GridBagConstraints();
- constraints.anchor = GridBagConstraints.FIRST_LINE_START;
- constraints.gridx = 0;
- constraints.gridy = 0;
- constraints.insets = new java.awt.Insets(TOP_INSET, LEFT_INSET, 0, 0);
+ GridBagLayout personasPanelLayout = new GridBagLayout();
+ GridBagConstraints personasPanelConstraints = new GridBagConstraints();
+ personasPanelConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
+ personasPanelConstraints.gridx = 0;
+ personasPanelConstraints.gridy = 0;
+ personasPanelConstraints.insets = new java.awt.Insets(0, 0, 0, 0);
+
+ // add a section header
+ CommunicationArtifactViewerHelper.addHeader(this.personasPanel, personasPanelLayout, personasPanelConstraints, Bundle.ContactArtifactViewer_persona_header());
+
+ personasPanelConstraints.gridy++;
if (contactUniquePersonasMap.isEmpty()) {
- showPersona(null, Collections.emptyList(), gridBagLayout, constraints);
+ showPersona(null, Collections.emptyList(), personasPanelLayout, personasPanelConstraints);
} else {
for (Map.Entry> entry : contactUniquePersonasMap.entrySet()) {
List missingAccounts = new ArrayList<>();
@@ -318,56 +470,151 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
}
}
- showPersona(entry.getKey(), missingAccounts, gridBagLayout, constraints);
-
- constraints.gridy += 2;
+ showPersona(entry.getKey(), missingAccounts, personasPanelLayout, personasPanelConstraints);
+ personasPanelConstraints.gridy += 2;
}
}
- personasPanel.setLayout(gridBagLayout);
+ CommunicationArtifactViewerHelper.addBlankLine(this.personasPanel, personasPanelLayout, personasPanelConstraints);
+
+ personasPanel.setLayout(personasPanelLayout);
personasPanel.setSize(personasPanel.getPreferredSize());
personasPanel.revalidate();
personasPanel.repaint();
}
-
+
+ /**
+ * Displays the given persona in the persona panel.
+ *
+ * @param persona Persona to display.
+ * @param missingAccountsList List of contact accounts this persona may be
+ * missing.
+ * @param gridBagLayout Layout to use.
+ * @param constraints layout constraints.
+ *
+ * @throws CentralRepoException
+ */
+ @NbBundle.Messages({
+ "ContactArtifactViewer_persona_label=Persona ",
+ "ContactArtifactViewer_persona_name_unknown=Unknown",
+ "ContactArtifactViewer_persona_button_view=View",
+ "ContactArtifactViewer_persona_button_new=Create",
+ "ContactArtifactViewer_missing_account_label=Contact account not in persona",
+ "ContactArtifactViewer_found_all_accounts_label=All contact accounts are in persona"
+ })
+ private void showPersona(Persona persona, List missingAccountsList, GridBagLayout gridBagLayout, GridBagConstraints constraints) {
+
+ Insets savedInsets = constraints.insets;
+
+ Insets labelInsets = new java.awt.Insets(0, LEFT_INSET, 0, 0);
+
+ //constraints.fill = GridBagConstraints.NONE;
+ //constraints.weightx = 0;
+ //constraints.gridx = 0;
+ //javax.swing.Box.Filler filler1 = createFiller(5, 0);
+ // gridBagLayout.setConstraints(filler1, constraints);
+ //personasPanel.add(filler1);
+ // Add a "Persona" label
+ //constraints.gridx++;
+// javax.swing.JLabel personaLabel = new javax.swing.JLabel();
+// personaLabel.setText(Bundle.ContactArtifactViewer_persona_label());
+// personaLabel.setFont(personaLabel.getFont().deriveFont(Font.BOLD, personaLabel.getFont().getSize()));
+// gridBagLayout.setConstraints(personaLabel, constraints);
+// personasPanel.add(personaLabel);
+ javax.swing.JLabel personaNameLabel = new javax.swing.JLabel();
+ javax.swing.JButton personaButton = new javax.swing.JButton();
+
+ String personaName;
+ String personaButtonText;
+ ActionListener personaButtonListener;
+
+ if (persona != null) {
+ personaName = persona.getName();
+ personaButtonText = Bundle.ContactArtifactViewer_persona_button_view();
+ personaButtonListener = new ViewPersonaButtonListener(this, persona);
+ } else {
+ personaName = Bundle.ContactArtifactViewer_persona_name_unknown();
+ personaButtonText = Bundle.ContactArtifactViewer_persona_button_new();
+ personaButtonListener = new CreatePersonaButtonListener(this, new PersonaUIComponents(personaNameLabel, personaButton));
+ }
+
+ // Add the label for persona name,
+ constraints.insets = labelInsets;
+ constraints.gridx = 0;
+ constraints.gridwidth = 2; // TBD: this may not be needed if we use single panel
+ personaNameLabel.setText(personaName);
+ gridBagLayout.setConstraints(personaNameLabel, constraints);
+ personasPanel.add(personaNameLabel);
+
+ // Add a Persona action button
+ constraints.gridx += 2;
+ constraints.gridwidth = 1;
+ personaButton.setText(personaButtonText);
+ personaButton.addActionListener(personaButtonListener);
+
+ constraints.insets = new java.awt.Insets(0, LEFT_INSET, 0, 0);
+ gridBagLayout.setConstraints(personaButton, constraints);
+ personasPanel.add(personaButton);
+
+ constraints.insets = labelInsets;
+
+ // if we have a persona, indicate if any of the contact's accounts are missing from it.
+ if (persona != null) {
+ if (missingAccountsList.isEmpty()) {
+ constraints.gridy++;
+ CommunicationArtifactViewerHelper.addKeyAtCol(personasPanel, gridBagLayout, constraints, Bundle.ContactArtifactViewer_found_all_accounts_label(), 2);
+ } else {
+ // show missing accounts.
+ for (CentralRepoAccount missingAccount : missingAccountsList) {
+ constraints.weightx = 0;
+ constraints.gridx = 0;
+ constraints.gridy++;
+
+ CommunicationArtifactViewerHelper.addKeyAtCol(personasPanel, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 2);
+ CommunicationArtifactViewerHelper.addValueAtCol(personasPanel, gridBagLayout, constraints, missingAccount.getIdentifier(), 3);
+ }
+ }
+ }
+
+ // restore insets
+ constraints.insets = savedInsets;
+ }
+
/**
* Resets all artifact specific state.
*/
private void resetComponent() {
+ contactArtifact = null;
contactName = null;
+ datasourceName = null;
+
contactUniqueAccountsList.clear();
contactUniquePersonasMap.clear();
-
+
+ phoneNumList.clear();
+ emailList.clear();
+ nameList.clear();
+ otherList.clear();
+ accountAttributesList.clear();
+
if (personaSearchTask != null) {
- personaSearchTask.cancel();
+ personaSearchTask.cancel(Boolean.TRUE);
+ personaSearchTask = null;
}
-
- personaSearchTask - mull;
-
- // clear the panel
- this.removeAll();
- this.setLayout(null);
- m_gridBagLayout = new GridBagLayout();
- m_constraints = new GridBagConstraints();
-
- m_constraints.anchor = GridBagConstraints.FIRST_LINE_START;
- m_constraints.gridy = 0;
- m_constraints.gridx = 0;
- m_constraints.weighty = 0.05;
- m_constraints.weightx = 0.05;
- m_constraints.insets = new java.awt.Insets(0, 0, 0, 0);
- m_constraints.fill = GridBagConstraints.NONE;
+ this.contactDetailsPanel.removeAll();
+ this.personasPanel.removeAll();
+ this.sourcePanel.removeAll();
}
-
+
/**
* Gets an image from a TSK_CONTACT artifact.
*
* @param artifact
*
* @return Image from a TSK_CONTACT artifact or default image if none was
- * found or the artifact is not a TSK_CONTACT
+ * found or the artifact is not a TSK_CONTACT
*/
private ImageIcon getImageFromArtifact(BlackboardArtifact artifact) {
ImageIcon imageIcon = defaultImage;
@@ -404,7 +651,6 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
return imageIcon;
}
-
/**
* Thread to search for a personas for all account identifier attributes for
* a contact.
@@ -418,7 +664,7 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
* Creates a persona searcher task.
*
* @param accountAttributesList List of attributes that may map to
- * accounts.
+ * accounts.
*/
ContactPersonaSearcherTask(List accountAttributesList) {
this.accountAttributesList = accountAttributesList;
@@ -429,6 +675,7 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
Map> uniquePersonas = new HashMap<>();
+ // TBD: this search needs to change to use the new method CommunicationsManager.getAccountsRelatedToArtifact
for (BlackboardAttribute bba : accountAttributesList) {
// Get account, add to accounts list
@@ -462,7 +709,6 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
}
}
}
-
}
return uniquePersonas;
@@ -484,10 +730,7 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
contactUniqueAccountsList.clear();
contactUniqueAccountsList.addAll(uniqueAccountsList);
- updatePersonasSection();
-
- // also update the source section now
-
+ updatePersonas();
} catch (CancellationException ex) {
logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS
@@ -499,7 +742,171 @@ public class ContactArtifactViewerNew extends javax.swing.JPanel implements Arti
}
}
-
+
+ /**
+ * A wrapper class that bags the UI components that need to be updated when
+ * a persona search task or a create dialog returns.
+ */
+ private class PersonaUIComponents {
+
+ private final JLabel personaNameLabel;
+ private final JButton personaActionButton;
+
+ /**
+ * Constructor.
+ *
+ * @param personaNameLabel Persona name label.
+ * @param personaActionButton Persona action button.
+ */
+ PersonaUIComponents(JLabel personaNameLabel, JButton personaActionButton) {
+ this.personaNameLabel = personaNameLabel;
+ this.personaActionButton = personaActionButton;
+ }
+
+ /**
+ * Returns persona name label.
+ *
+ * @return Persona name label.
+ */
+ public JLabel getPersonaNameLabel() {
+ return personaNameLabel;
+ }
+
+ /**
+ * Returns persona action button.
+ *
+ * @return Persona action button.
+ */
+ public JButton getPersonaActionButton() {
+ return personaActionButton;
+ }
+ }
+
+ /**
+ * Action listener for Create persona button.
+ */
+ private class CreatePersonaButtonListener implements ActionListener {
+
+ private final Component parentComponent;
+ private final PersonaUIComponents personaUIComponents;
+
+ /**
+ * Constructs a listener for Create persona button..
+ *
+ * @param personaUIComponents UI components.
+ */
+ CreatePersonaButtonListener(Component parentComponent, PersonaUIComponents personaUIComponents) {
+ this.personaUIComponents = personaUIComponents;
+ this.parentComponent = parentComponent;
+ }
+
+ @NbBundle.Messages({
+ "ContactArtifactViewer_persona_account_justification=Account found in Contact artifact"
+ })
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ // Launch the Persona Create dialog - do not display immediately
+ PersonaDetailsDialog createPersonaDialog = new PersonaDetailsDialog(parentComponent,
+ PersonaDetailsMode.CREATE, null, new PersonaCreateCallbackImpl(parentComponent, personaUIComponents), false);
+
+ // Pre populate the persona name and accounts if we have them.
+ PersonaDetailsPanel personaPanel = createPersonaDialog.getDetailsPanel();
+
+ if (contactName != null) {
+ personaPanel.setPersonaName(contactName);
+ }
+
+ // pass the list of accounts to the dialog
+ for (CentralRepoAccount account : contactUniqueAccountsList) {
+ personaPanel.addAccount(account, Bundle.ContactArtifactViewer_persona_account_justification(), Persona.Confidence.HIGH);
+ }
+
+ // display the dialog now
+ createPersonaDialog.display();
+ }
+ }
+
+ /**
+ * Action listener for View persona button.
+ */
+ private class ViewPersonaButtonListener implements ActionListener {
+
+ private final Persona persona;
+ private final Component parentComponent;
+
+ /**
+ * Creates listener for View persona button.
+ *
+ * @param persona
+ */
+ ViewPersonaButtonListener(Component parentComponent, Persona persona) {
+ this.persona = persona;
+ this.parentComponent = parentComponent;
+ }
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ new PersonaDetailsDialog(parentComponent,
+ PersonaDetailsMode.VIEW, persona, new PersonaViewCallbackImpl());
+ }
+ }
+
+ /**
+ * Callback method for the create mode of the PersonaDetailsDialog
+ */
+ class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback {
+
+ private final Component parentComponent;
+ private final PersonaUIComponents personaUIComponents;
+
+ /**
+ * Creates a callback to handle new persona creation.
+ *
+ * @param personaUIComponents UI Components.
+ */
+ PersonaCreateCallbackImpl(Component parentComponent, PersonaUIComponents personaUIComponents) {
+ this.parentComponent = parentComponent;
+ this.personaUIComponents = personaUIComponents;
+ }
+
+ @Override
+ public void callback(Persona persona) {
+ JButton personaButton = personaUIComponents.getPersonaActionButton();
+ if (persona != null) {
+ // update the persona name label with newly created persona,
+ // and change the button to a "View" button
+ personaUIComponents.getPersonaNameLabel().setText(persona.getName());
+ personaUIComponents.getPersonaActionButton().setText(Bundle.ContactArtifactViewer_persona_button_view());
+
+ // replace action listener with a View button listener
+ for (ActionListener act : personaButton.getActionListeners()) {
+ personaButton.removeActionListener(act);
+ }
+ personaButton.addActionListener(new ViewPersonaButtonListener(parentComponent, persona));
+
+ }
+
+ personaButton.getParent().revalidate();
+ personaButton.getParent().repaint();
+ }
+ }
+
+ /**
+ * Callback method for the view mode of the PersonaDetailsDialog
+ */
+ class PersonaViewCallbackImpl implements PersonaDetailsDialogCallback {
+
+ @Override
+ public void callback(Persona persona) {
+ // nothing to do
+ }
+ }
+
// Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel contactDetailsPanel;
+ private javax.swing.Box.Filler filler1;
+ private javax.swing.JPanel personasPanel;
+ private javax.swing.JPanel sourcePanel;
// End of variables declaration//GEN-END:variables
}
diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
index 5f60aed634..f4d5248a8b 100644
--- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
+++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
@@ -1,5 +1,5 @@
#Updated by build script
-#Fri, 12 Jun 2020 14:50:38 -0400
+#Fri, 19 Jun 2020 10:14:47 -0400
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314
SPLASH_WIDTH=538
diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
index 6160c1ec95..52d17e0e96 100644
--- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
+++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
@@ -1,4 +1,4 @@
#Updated by build script
-#Fri, 12 Jun 2020 14:50:38 -0400
+#Fri, 19 Jun 2020 10:14:47 -0400
CTL_MainWindow_Title=Autopsy 4.15.0
CTL_MainWindow_Title_No_Project=Autopsy 4.15.0