Merge pull request #6006 from raman-bt/6464-redo-contactviewer

6464 redo contactviewer
This commit is contained in:
Richard Cordovano 2020-06-23 14:50:17 -04:00 committed by GitHub
commit 7adf2e63ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 545 additions and 669 deletions

View File

@ -981,4 +981,3 @@ CallLogArtifactViewer.localAccountPersonaNameLabel.text=jLabel1
CallLogArtifactViewer.localAccountPersonaButton.text=jButton1 CallLogArtifactViewer.localAccountPersonaButton.text=jButton1
ContactArtifactViewer.personasLabel.text=Personas ContactArtifactViewer.personasLabel.text=Personas
MessageArtifactViewer.accountsTab.TabConstraints.tabTitle=Accounts MessageArtifactViewer.accountsTab.TabConstraints.tabTitle=Accounts
ContactArtifactViewer.contactImage.text=

View File

@ -35,6 +35,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -92,6 +93,10 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
public void setArtifact(BlackboardArtifact artifact) { public void setArtifact(BlackboardArtifact artifact) {
resetComponent(); resetComponent();
if (artifact == null) {
return;
}
CallLogViewData callLogViewData = null; CallLogViewData callLogViewData = null;
try { try {
callLogViewData = getCallLogViewData(artifact); callLogViewData = getCallLogViewData(artifact);
@ -335,8 +340,15 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
} }
updateMetadataView(callLogViewData); updateMetadataView(callLogViewData);
updateOtherAttributesView(callLogViewData);
updateSourceView(callLogViewData); updateSourceView(callLogViewData);
if (CentralRepository.isEnabled() == false) {
showCRDisabledMessage();
}
CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints); CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
this.setLayout(m_gridBagLayout); this.setLayout(m_gridBagLayout);
@ -394,6 +406,37 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName()); CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
} }
/**
* Update the other attributes section.
*
* @param callLogViewData Call log data.
*/
@NbBundle.Messages({
"CallLogArtifactViewer_heading_others=Other Attributes"
})
private void updateOtherAttributesView(CallLogViewData callLogViewData) {
if (callLogViewData.getOtherAttributes().isEmpty()) {
return;
}
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_others());
for (Map.Entry<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, entry.getKey());
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, entry.getValue());
}
}
@NbBundle.Messages({
"CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
})
private void showCRDisabledMessage() {
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
m_constraints.gridy++;
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
m_constraints.gridy++;
}
/** /**
* Returns display string for a account. Checks if the given account is the * Returns display string for a account. Checks if the given account is the
* local account, if it is known. If it is, it appends a "(Local)" suffix to * local account, if it is known. If it is, it appends a "(Local)" suffix to
@ -421,7 +464,9 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
@Override @Override
public boolean isSupported(BlackboardArtifact artifact) { public boolean isSupported(BlackboardArtifact artifact) {
return artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID();
return (artifact != null)
&& (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID());
} }
/** /**
@ -445,9 +490,9 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
m_constraints.anchor = GridBagConstraints.FIRST_LINE_START; m_constraints.anchor = GridBagConstraints.FIRST_LINE_START;
m_constraints.gridy = 0; m_constraints.gridy = 0;
m_constraints.gridx = 0; m_constraints.gridx = 0;
m_constraints.weighty = 0.05; m_constraints.weighty = 0.0;
m_constraints.weightx = 0.05; m_constraints.weightx = 0.0; // keep components fixed horizontally.
m_constraints.insets = new java.awt.Insets(0, 0, 0, 0); m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
m_constraints.fill = GridBagConstraints.NONE; m_constraints.fill = GridBagConstraints.NONE;
} }

View File

@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@ -42,12 +43,12 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
* A class to help display a communication artifact in a panel using a * A class to help display a communication artifact in a panel using a
* gridbaglayout. * gridbaglayout.
*/ */
public final class CommunicationArtifactViewerHelper { final class CommunicationArtifactViewerHelper {
// Number of columns in the gridbag layout. // Number of columns in the gridbag layout.
private final static int MAX_COLS = 4; private final static int MAX_COLS = 4;
private final static int LEFT_INDENT = 12; final static int LEFT_INSET = 12;
/** /**
* Empty private constructor * Empty private constructor
@ -63,8 +64,15 @@ public final class CommunicationArtifactViewerHelper {
* @param gridbagLayout Layout to use. * @param gridbagLayout Layout to use.
* @param constraints Constrains to use. * @param constraints Constrains to use.
* @param headerString Heading string to display. * @param headerString Heading string to display.
*
* @return JLabel Heading label added.
*/ */
static void addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) { static JLabel addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) {
Insets savedInsets = constraints.insets;
// create label for heading
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
// add a blank line before the start of new section, unless it's // add a blank line before the start of new section, unless it's
// the first section // the first section
@ -76,9 +84,9 @@ public final class CommunicationArtifactViewerHelper {
// let the header span all of the row // let the header span all of the row
constraints.gridwidth = MAX_COLS; constraints.gridwidth = MAX_COLS;
constraints.insets = new Insets(0, 0, 0, 0); // No inset for header
// create label for heading // set text
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
headingLabel.setText(headerString); headingLabel.setText(headerString);
// make it large and bold // make it large and bold
@ -93,6 +101,28 @@ public final class CommunicationArtifactViewerHelper {
// add line end glue // add line end glue
addLineEndGlue(panel, gridbagLayout, constraints); addLineEndGlue(panel, gridbagLayout, constraints);
//restore insets
constraints.insets = savedInsets;
return headingLabel;
}
/**
* Adds the given component to the panel.
*
* Caller must know what it's doing and set up all the constraints properly.
*
* @param panel Panel to update.
* @param gridbagLayout Layout to use.
* @param constraints Constrains to use.
* @param component Component to add.
*/
static void addComponent(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, JComponent component) {
// add to panel
gridbagLayout.setConstraints(component, constraints);
panel.add(component);
} }
/** /**
@ -103,7 +133,7 @@ public final class CommunicationArtifactViewerHelper {
* @param gridbagLayout Layout to use. * @param gridbagLayout Layout to use.
* @param constraints Constrains to use. * @param constraints Constrains to use.
*/ */
private static void addLineEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) { static void addLineEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
// Place the filler just past the last column. // Place the filler just past the last column.
constraints.gridx = MAX_COLS; constraints.gridx = MAX_COLS;
@ -156,7 +186,7 @@ public final class CommunicationArtifactViewerHelper {
* @param gridbagLayout Layout to use. * @param gridbagLayout Layout to use.
* @param constraints Constrains 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.gridy++;
constraints.gridx = 0; constraints.gridx = 0;
@ -168,54 +198,85 @@ 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 panel Panel to update.
* @param gridbagLayout Layout to use. * @param gridbagLayout Layout to use.
* @param constraints Constrains to use. * @param constraints Constrains to use.
* @param keyString Key name to display. * @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.gridy++;
constraints.gridx = 0; constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
Insets savedInsets = constraints.insets; // set text
// 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();
keyLabel.setText(keyString + ": "); keyLabel.setText(keyString + ": ");
// add to panel // add to panel
gridbagLayout.setConstraints(keyLabel, constraints); gridbagLayout.setConstraints(keyLabel, constraints);
panel.add(keyLabel); panel.add(keyLabel);
// restore inset return keyLabel;
constraints.insets = savedInsets;
} }
/** /**
* Adds a value string to the panel. * Adds a value string to the panel at col 1.
* *
* @param panel Panel to update. * @param panel Panel to update.
* @param gridbagLayout Layout to use. * @param gridbagLayout Layout to use.
* @param constraints Constrains to use. * @param constraints Constrains to use.
* @param keyString Value string to display. * @param keyString Value string to display.
*
* @return Label added.
*/ */
static void addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) { static JLabel addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) {
return addValueAtCol(panel, gridbagLayout, constraints, valueString, 1);
}
constraints.gridx = 1; /**
* Adds a value string to the panel at specified column.
*
* @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; int savedGridwidth = constraints.gridwidth;
// let the value span 2 cols // let the value span 2 cols
constraints.gridwidth = 2; constraints.gridwidth = 2;
// create label, // set text
javax.swing.JLabel valueField = new javax.swing.JLabel();
valueField.setText(valueString); valueField.setText(valueString);
// attach a right click menu with Copy option // attach a right click menu with Copy option
@ -235,6 +296,63 @@ public final class CommunicationArtifactViewerHelper {
// end the line // end the line
addLineEndGlue(panel, gridbagLayout, constraints); addLineEndGlue(panel, gridbagLayout, constraints);
return valueField;
}
/**
* Displays a message string, starting at column 0, and spanning the entire
* row.
*
* @param panel Panel to show.
* @param gridbagLayout Layout to use.
* @param constraints Constraints to use.
*
* @param messageString Message to display.
*
* @return Label for message added.
*/
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString) {
return addMessageRow(panel, gridbagLayout, constraints, messageString, 0);
}
/**
* Displays a message string, starting at specified column, and spanning the
* entire row.
*
* @param panel Panel to show.
* @param gridbagLayout Layout to use.
* @param constraints Constraints to use.
*
* @param messageString Message to display.
*
* @return Label for message added.
*/
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString, int gridx) {
// create label
javax.swing.JLabel messageLabel = new javax.swing.JLabel();
constraints.gridy++;
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
int savedGridwidth = constraints.gridwidth;
constraints.gridwidth = 3;
// set text
messageLabel.setText(messageString);
// add to panel
gridbagLayout.setConstraints(messageLabel, constraints);
panel.add(messageLabel);
addLineEndGlue(panel, gridbagLayout, constraints);
// restore constraints
constraints.gridwidth = savedGridwidth;
return messageLabel;
} }
/** /**
@ -269,8 +387,8 @@ public final class CommunicationArtifactViewerHelper {
Insets savedInsets = constraints.insets; Insets savedInsets = constraints.insets;
// Indent in // extra Indent in
constraints.insets = new java.awt.Insets(0, LEFT_INDENT, 0, 0); constraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0);
// create label // create label
javax.swing.JLabel personaLabel = new javax.swing.JLabel(); javax.swing.JLabel personaLabel = new javax.swing.JLabel();
@ -293,9 +411,9 @@ public final class CommunicationArtifactViewerHelper {
// Place a button as place holder. It will be enabled when persona is available. // Place a button as place holder. It will be enabled when persona is available.
javax.swing.JButton personaButton = new javax.swing.JButton(); javax.swing.JButton personaButton = new javax.swing.JButton();
personaButton.setText(Bundle.CommunicationArtifactViewerHelper_persona_button_view()); personaButton.setText(Bundle.CommunicationArtifactViewerHelper_persona_button_view());
personaButton.setMargin(new Insets(0, 5, 0, 5));
personaButton.setEnabled(false); personaButton.setEnabled(false);
gridbagLayout.setConstraints(personaButton, constraints); gridbagLayout.setConstraints(personaButton, constraints);
panel.add(personaButton); panel.add(personaButton);

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="toolTipText" type="java.lang.String" value="" noResource="true"/>
</Properties>
<AuxValues> <AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@ -11,217 +14,8 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-57,0,0,2,31"/> <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues> </AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="namePanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="5" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="contactNameLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="contactNameLabel" italic="true" property="font" relativeSize="true" size="6"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.contactNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="111" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="phonesLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="phonesLabel" property="font" relativeSize="true" size="2"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.phonesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="phoneNumbersPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="3" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
</Container>
<Component class="javax.swing.JLabel" name="emailsLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="emailsLabel" property="font" relativeSize="true" size="2"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.emailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="4" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="emailsPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="5" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
</Container>
<Component class="javax.swing.JLabel" name="othersLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="othersLabel" property="font" relativeSize="true" size="2"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.othersLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="otherAttrsPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="7" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
</Container>
<Component class="javax.swing.Box$Filler" name="interPanelfiller">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="8" gridWidth="1" gridHeight="2" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.1"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="personasLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="personasLabel" property="font" relativeSize="true" size="2"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.personasLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[90, 19]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[90, 19]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[90, 19]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="9" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="personasPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="10" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
</Container>
<Component class="javax.swing.Box$Filler" name="bottomFiller">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="11" gridWidth="4" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.Box$Filler" name="rightFiller">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 0]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalGlue"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="4" gridY="3" gridWidth="1" gridHeight="8" fill="1" ipadX="2" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="contactImage">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/defaultContact.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.contactImage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Form> </Form>

View File

@ -19,9 +19,9 @@
package org.sleuthkit.autopsy.contentviewers; package org.sleuthkit.autopsy.contentviewers;
import java.awt.Component; import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
@ -40,11 +40,11 @@ import javax.imageio.ImageIO;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import org.openide.util.lookup.ServiceProvider;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
@ -70,11 +70,23 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
private final static Logger logger = Logger.getLogger(ContactArtifactViewer.class.getName()); private final static Logger logger = Logger.getLogger(ContactArtifactViewer.class.getName());
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final int TOP_INSET = 4; private GridBagLayout m_gridBagLayout = new GridBagLayout();
private static final int LEFT_INSET = 12; private GridBagConstraints m_constraints = new GridBagConstraints();
// contact name, if available. private JLabel personaSearchStatusLabel;
private BlackboardArtifact contactArtifact;
private String contactName; private String contactName;
private String datasourceName;
private List<BlackboardAttribute> phoneNumList = new ArrayList<>();
private List<BlackboardAttribute> emailList = new ArrayList<>();
private List<BlackboardAttribute> nameList = new ArrayList<>();
private List<BlackboardAttribute> otherList = new ArrayList<>();
private List<BlackboardAttribute> accountAttributesList = new ArrayList<>();
private final static String DEFAULT_IMAGE_PATH = "/org/sleuthkit/autopsy/images/defaultContact.png";
private final ImageIcon defaultImage;
// A list of unique accounts matching the attributes of the contact artifact. // A list of unique accounts matching the attributes of the contact artifact.
private final List<CentralRepoAccount> contactUniqueAccountsList = new ArrayList<>(); private final List<CentralRepoAccount> contactUniqueAccountsList = new ArrayList<>();
@ -83,11 +95,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
// account identifier attributes of the Contact artifact. // account identifier attributes of the Contact artifact.
private final Map<Persona, ArrayList<CentralRepoAccount>> contactUniquePersonasMap = new HashMap<>(); private final Map<Persona, ArrayList<CentralRepoAccount>> contactUniquePersonasMap = new HashMap<>();
private final static String DEFAULT_IMAGE_PATH = "/org/sleuthkit/autopsy/images/defaultContact.png"; private ContactPersonaSearcherTask personaSearchTask;
private final ImageIcon defaultImage;
/** /**
* Creates new form for ContactArtifactViewer * Creates new form ContactArtifactViewer
*/ */
public ContactArtifactViewer() { public ContactArtifactViewer() {
initComponents(); initComponents();
@ -103,164 +114,13 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
namePanel = new javax.swing.JPanel();
contactNameLabel = new javax.swing.JLabel();
phonesLabel = new javax.swing.JLabel();
phoneNumbersPanel = new javax.swing.JPanel();
emailsLabel = new javax.swing.JLabel();
emailsPanel = new javax.swing.JPanel();
othersLabel = new javax.swing.JLabel();
otherAttrsPanel = new javax.swing.JPanel();
javax.swing.Box.Filler interPanelfiller = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
personasLabel = new javax.swing.JLabel();
personasPanel = new javax.swing.JPanel();
javax.swing.Box.Filler bottomFiller = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
javax.swing.Box.Filler rightFiller = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
contactImage = new javax.swing.JLabel();
setToolTipText(""); // NOI18N
setLayout(new java.awt.GridBagLayout()); setLayout(new java.awt.GridBagLayout());
namePanel.setLayout(new java.awt.GridBagLayout());
contactNameLabel.setFont(contactNameLabel.getFont().deriveFont((contactNameLabel.getFont().getStyle() | java.awt.Font.ITALIC) | java.awt.Font.BOLD, contactNameLabel.getFont().getSize()+6));
org.openide.awt.Mnemonics.setLocalizedText(contactNameLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.contactNameLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.ipadx = 111;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
namePanel.add(contactNameLabel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 5;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(namePanel, gridBagConstraints);
phonesLabel.setFont(phonesLabel.getFont().deriveFont(phonesLabel.getFont().getStyle() | java.awt.Font.BOLD, phonesLabel.getFont().getSize()+2));
org.openide.awt.Mnemonics.setLocalizedText(phonesLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.phonesLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.gridwidth = 3;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(phonesLabel, gridBagConstraints);
phoneNumbersPanel.setLayout(new java.awt.GridBagLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(phoneNumbersPanel, gridBagConstraints);
emailsLabel.setFont(emailsLabel.getFont().deriveFont(emailsLabel.getFont().getStyle() | java.awt.Font.BOLD, emailsLabel.getFont().getSize()+2));
org.openide.awt.Mnemonics.setLocalizedText(emailsLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.emailsLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 4;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(emailsLabel, gridBagConstraints);
emailsPanel.setLayout(new java.awt.GridBagLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 5;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(emailsPanel, gridBagConstraints);
othersLabel.setFont(othersLabel.getFont().deriveFont(othersLabel.getFont().getStyle() | java.awt.Font.BOLD, othersLabel.getFont().getSize()+2));
org.openide.awt.Mnemonics.setLocalizedText(othersLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.othersLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 6;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(othersLabel, gridBagConstraints);
otherAttrsPanel.setLayout(new java.awt.GridBagLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 7;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(otherAttrsPanel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 8;
gridBagConstraints.gridheight = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
gridBagConstraints.weighty = 0.1;
add(interPanelfiller, gridBagConstraints);
personasLabel.setFont(personasLabel.getFont().deriveFont(personasLabel.getFont().getStyle() | java.awt.Font.BOLD, personasLabel.getFont().getSize()+2));
org.openide.awt.Mnemonics.setLocalizedText(personasLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.personasLabel.text")); // NOI18N
personasLabel.setMaximumSize(new java.awt.Dimension(90, 19));
personasLabel.setMinimumSize(new java.awt.Dimension(90, 19));
personasLabel.setPreferredSize(new java.awt.Dimension(90, 19));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 9;
gridBagConstraints.gridwidth = 3;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(personasLabel, gridBagConstraints);
personasPanel.setLayout(new java.awt.GridBagLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 10;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(personasPanel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 11;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weighty = 1.0;
add(bottomFiller, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 4;
gridBagConstraints.gridy = 3;
gridBagConstraints.gridheight = 8;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.ipadx = 2;
gridBagConstraints.weightx = 1.0;
add(rightFiller, gridBagConstraints);
contactImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/defaultContact.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(contactImage, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.contactImage.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
add(contactImage, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@Override @Override
public void setArtifact(BlackboardArtifact artifact) { public void setArtifact(BlackboardArtifact artifact) {
// Reset the panel. // Reset the panel.
resetComponent(); resetComponent();
@ -268,15 +128,50 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
return; return;
} }
List<BlackboardAttribute> phoneNumList = new ArrayList<>();
List<BlackboardAttribute> emailList = new ArrayList<>();
List<BlackboardAttribute> nameList = new ArrayList<>();
List<BlackboardAttribute> otherList = new ArrayList<>();
List<BlackboardAttribute> accountAttributesList = new ArrayList<>();
try { try {
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;
}
updateView();
this.setLayout(this.m_gridBagLayout);
this.revalidate();
this.repaint();
}
@Override
public Component getComponent() {
// Slap a vertical scrollbar on the panel.
return new JScrollPane(this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
@Override
public boolean isSupported(BlackboardArtifact artifact) {
return (artifact != null)
&& (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 // Get all the attributes and group them by the section panels they go in
for (BlackboardAttribute bba : artifact.getAttributes()) { for (BlackboardAttribute bba : contactArtifact.getAttributes()) {
if (bba.getAttributeType().getTypeName().startsWith("TSK_PHONE")) { if (bba.getAttributeType().getTypeName().startsWith("TSK_PHONE")) {
phoneNumList.add(bba); phoneNumList.add(bba);
accountAttributesList.add(bba); accountAttributesList.add(bba);
@ -292,234 +187,215 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
} }
} }
} }
} 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); datasourceName = contactArtifact.getDataSource().getName();
} }
// update name section
updateNamePanel(nameList); /**
* Updates the view with the data extracted from the artifact.
*/
private void updateView() {
// Update contact name, image, phone numbers
updateContactDetails();
// update artifact source panel
updateSource();
// show a empty Personas panel and kick off a serch for personas
initiatePersonasSearch();
}
/**
* Updates the view with contact's details.
*/
@NbBundle.Messages({
"ContactArtifactViewer_phones_header=Phone",
"ContactArtifactViewer_emails_header=Email",
"ContactArtifactViewer_others_header=Other",})
private void updateContactDetails() {
// update image and name.
updateContactImage(m_gridBagLayout, m_constraints);
updateContactName(m_gridBagLayout, m_constraints);
// update contact attributes sections // update contact attributes sections
updateSection(phoneNumList, this.phonesLabel, this.phoneNumbersPanel); updateContactMethodSection(phoneNumList, Bundle.ContactArtifactViewer_phones_header(), m_gridBagLayout, m_constraints);
updateSection(emailList, this.emailsLabel, this.emailsPanel); updateContactMethodSection(emailList, Bundle.ContactArtifactViewer_emails_header(), m_gridBagLayout, m_constraints);
updateSection(otherList, this.othersLabel, this.otherAttrsPanel); updateContactMethodSection(otherList, Bundle.ContactArtifactViewer_others_header(), m_gridBagLayout, m_constraints);
try {
initiatePersonasSearch(accountAttributesList);
} catch (CentralRepoException ex) {
logger.log(Level.SEVERE, String.format("Error getting Personas for Contact artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
}
contactImage.setIcon(getImageFromArtifact(artifact));
// repaint
this.revalidate();
this.repaint();
}
@Override
public Component getComponent() {
// Slap a vertical scrollbar on the panel.
return new JScrollPane(this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
} }
/** /**
* Checks if the given artifact is supported by this viewer. This viewer * Updates the contact image in the view.
* supports TSK_CONTACT artifacts.
* *
* @param artifact artifact to check. * @param contactPanelLayout Panel layout.
* @param contactPanelConstraints Layout constraints.
* *
* @return True if the artifact is supported, false otherwise.
*/ */
@Override @NbBundle.Messages({
public boolean isSupported(BlackboardArtifact artifact) { "ContactArtifactViewer.contactImage.text=",})
return artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID(); private void updateContactImage(GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
} // place the image on the top right corner
Insets savedInsets = contactPanelConstraints.insets;
contactPanelConstraints.gridy = 0;
contactPanelConstraints.gridx = 0;
contactPanelConstraints.insets = new Insets(0, 0, 0, 0);
/** javax.swing.JLabel contactImage = new javax.swing.JLabel();
* Clears all artifact specific state. contactImage.setIcon(getImageFromArtifact(contactArtifact));
*/ contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text());
private void resetComponent() {
contactNameLabel.setVisible(false);
emailsLabel.setVisible(false);
emailsPanel.removeAll();
//namePanel.removeAll(); // this is not dynamically populated, do not remove.
otherAttrsPanel.removeAll();
othersLabel.setVisible(false);
personasLabel.setVisible(false);
personasPanel.removeAll();
phoneNumbersPanel.removeAll();
phonesLabel.setVisible(false);
contactName = null; // add image to top left corner of the page.
contactUniqueAccountsList.clear(); CommunicationArtifactViewerHelper.addComponent(this, contactPanelLayout, contactPanelConstraints, contactImage);
contactUniquePersonasMap.clear(); CommunicationArtifactViewerHelper.addLineEndGlue(this, contactPanelLayout, contactPanelConstraints);
contactImage.setIcon(defaultImage); contactPanelConstraints.gridy++;
contactPanelConstraints.insets = savedInsets;
} }
/** /**
* Updates the contact name in the view. * Updates the contact name in the view.
* *
* @param attributesList * @param contactPanelLayout Panel layout.
* @param contactPanelConstraints Layout constraints.
*
*/ */
private void updateNamePanel(List<BlackboardAttribute> attributesList) { @NbBundle.Messages({
for (BlackboardAttribute bba : attributesList) { "ContactArtifactViewer_contactname_unknown=Unknown",})
if (bba.getAttributeType().getTypeName().startsWith("TSK_NAME")) { private void updateContactName(GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
boolean foundName = false;
for (BlackboardAttribute bba : this.nameList) {
if (StringUtils.isEmpty(bba.getValueString()) == false) {
contactName = bba.getDisplayString(); contactName = bba.getDisplayString();
contactNameLabel.setText(contactName);
contactNameLabel.setVisible(true); CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, contactName);
foundName = true;
break; break;
} }
} }
if (foundName == false) {
contactNameLabel.revalidate(); CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, Bundle.ContactArtifactViewer_contactname_unknown());
}
} }
/** /**
* Updates the view by displaying the given list of attributes in the given * Updates the view by displaying the given list of attributes in the given
* section panel. * section panel.
* *
* @param sectionAttributesList list of attributes to display. * @param sectionAttributesList List of attributes to display.
* @param sectionLabel section name label. * @param sectionLabel Section name label.
* @param sectionPanel section panel to display the attributes in. * @param contactPanelLayout Panel layout.
* @param contactPanelConstraints Layout constraints.
*
*/ */
private void updateSection(List<BlackboardAttribute> sectionAttributesList, JLabel sectionLabel, JPanel sectionPanel) { @NbBundle.Messages({
"ContactArtifactViewer_plural_suffix=s",})
private void updateContactMethodSection(List<BlackboardAttribute> sectionAttributesList, String sectionHeader, GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
// If there are no attributes for tis section, hide the section panel and the section label // If there are no attributes for this section, do nothing
if (sectionAttributesList.isEmpty()) { if (sectionAttributesList.isEmpty()) {
sectionLabel.setVisible(false);
sectionPanel.setVisible(false);
return; return;
} }
// create a gridbag layout to show each attribute on one line String sectionHeaderString = sectionHeader;
GridBagLayout gridBagLayout = new GridBagLayout(); if (sectionAttributesList.size() > 1) {
GridBagConstraints constraints = new GridBagConstraints(); sectionHeaderString = sectionHeaderString.concat(Bundle.ContactArtifactViewer_plural_suffix());
constraints.anchor = GridBagConstraints.FIRST_LINE_START; }
constraints.gridy = 0; CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, sectionHeaderString);
constraints.insets = new java.awt.Insets(TOP_INSET, LEFT_INSET, 0, 0); for (BlackboardAttribute bba : sectionAttributesList) {
for (BlackboardAttribute bba : sectionAttributesList) { CommunicationArtifactViewerHelper.addKey(this, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName());
constraints.fill = GridBagConstraints.NONE; CommunicationArtifactViewerHelper.addValue(this, contactPanelLayout, contactPanelConstraints, bba.getDisplayString());
constraints.weightx = 0;
constraints.gridx = 0;
// Add a label for attribute type
javax.swing.JLabel attrTypeLabel = new javax.swing.JLabel();
String attrLabel = bba.getAttributeType().getDisplayName();
attrTypeLabel.setText(attrLabel);
// make type label bold - uncomment if needed.
//attrTypeLabel.setFont(attrTypeLabel.getFont().deriveFont(Font.BOLD, attrTypeLabel.getFont().getSize() ));
gridBagLayout.setConstraints(attrTypeLabel, constraints);
sectionPanel.add(attrTypeLabel);
// Add the attribute value
constraints.gridx++;
javax.swing.JLabel attrValueLabel = new javax.swing.JLabel();
attrValueLabel.setText(bba.getValueString());
gridBagLayout.setConstraints(attrValueLabel, constraints);
sectionPanel.add(attrValueLabel);
// add a filler to take up rest of the space
constraints.gridx++;
constraints.weightx = 1.0;
constraints.fill = GridBagConstraints.HORIZONTAL;
sectionPanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)));
constraints.gridy++;
} }
sectionLabel.setVisible(true);
sectionPanel.setVisible(true);
sectionPanel.setLayout(gridBagLayout);
sectionPanel.revalidate();
sectionPanel.repaint();
} }
/** /**
* Kicks off a search for personas, based in the list of attributes. * Updates the source section.
*/
@NbBundle.Messages({
"ContactArtifactViewer_heading_Source=Source",
"ContactArtifactViewer_label_datasource=Data Source",})
private void updateSource() {
CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_heading_Source());
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_datasource());
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName);
}
/**
* Kicks off a search for personas, based in the given list of attributes.
* *
* @param accountAttributesList a list of account identifying attributes. * @param accountAttributesList a list of account identifying attributes.
* *
* @throws CentralRepoException * @throws CentralRepoException
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"ContactArtifactViewer_persona_header=Persona",
"ContactArtifactViewer_persona_searching=Searching...", "ContactArtifactViewer_persona_searching=Searching...",
"ContactArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas.",
"ContactArtifactViewer_persona_unknown=Unknown" "ContactArtifactViewer_persona_unknown=Unknown"
}) })
private void initiatePersonasSearch(List<BlackboardAttribute> accountAttributesList) throws CentralRepoException {
personasLabel.setVisible(true); /**
* Initiates a search for Personas for the accounts associated with the
* Contact.
*
*/
private void initiatePersonasSearch() {
// add a section header
JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_persona_header());
m_constraints.gridy++;
// add a status label
String personaStatusLabelText = CentralRepository.isEnabled() String personaStatusLabelText = CentralRepository.isEnabled()
? Bundle.ContactArtifactViewer_persona_searching() ? Bundle.ContactArtifactViewer_persona_searching()
: Bundle.ContactArtifactViewer_persona_unknown(); : Bundle.ContactArtifactViewer_persona_unknown();
// create a gridbag layout to show each participant on one line this.personaSearchStatusLabel = new javax.swing.JLabel();
GridBagLayout gridBagLayout = new GridBagLayout(); personaSearchStatusLabel.setText(personaStatusLabelText);
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);
// Add a Persona Name label m_constraints.gridx = 0;
constraints.fill = GridBagConstraints.NONE;
constraints.weightx = 0;
//javax.swing.Box.Filler filler1 = this.createFiller(5, 0);
//personasPanel.add(filler1, constraints);
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);
constraints.gridy++;
javax.swing.JLabel personaStatusLabel = new javax.swing.JLabel();
personaStatusLabel.setText(personaStatusLabelText);
gridBagLayout.setConstraints(personaStatusLabel, constraints);
personasPanel.add(personaStatusLabel);
CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, m_constraints, personaSearchStatusLabel);
if (CentralRepository.isEnabled()) { if (CentralRepository.isEnabled()) {
personasLabel.setEnabled(true);
// Kick off a background task to serach for personas for the contact // Kick off a background task to serach for personas for the contact
ContactPersonaSearcherTask personaSearchTask = new ContactPersonaSearcherTask(accountAttributesList); personaSearchTask = new ContactPersonaSearcherTask(accountAttributesList);
personaSearchTask.execute(); personaSearchTask.execute();
} else { } else {
personasLabel.setEnabled(false); personaHeader.setEnabled(false);
personaLabel.setEnabled(false); personaSearchStatusLabel.setEnabled(false);
personaStatusLabel.setEnabled(false);
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
m_constraints.gridy++;
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
m_constraints.gridy++;
CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
} }
personasPanel.setLayout(gridBagLayout);
personasPanel.revalidate();
personasPanel.repaint();
} }
/** /**
* Updates the Persona panel with the gathered persona information. * 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(); // Remove the "Searching....." label
GridBagConstraints constraints = new GridBagConstraints(); this.remove(personaSearchStatusLabel);
constraints.anchor = GridBagConstraints.FIRST_LINE_START;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.insets = new java.awt.Insets(TOP_INSET, LEFT_INSET, 0, 0);
m_constraints.gridx = 0;
if (contactUniquePersonasMap.isEmpty()) { if (contactUniquePersonasMap.isEmpty()) {
showPersona(null, Collections.emptyList(), gridBagLayout, constraints); // No persona found - show a button to create one.
showPersona(null, 0, Collections.emptyList(), this.m_gridBagLayout, this.m_constraints);
} else { } else {
int matchCounter = 0;
for (Map.Entry<Persona, ArrayList<CentralRepoAccount>> entry : contactUniquePersonasMap.entrySet()) { for (Map.Entry<Persona, ArrayList<CentralRepoAccount>> entry : contactUniquePersonasMap.entrySet()) {
List<CentralRepoAccount> missingAccounts = new ArrayList<>(); List<CentralRepoAccount> missingAccounts = new ArrayList<>();
ArrayList<CentralRepoAccount> personaAccounts = entry.getValue(); ArrayList<CentralRepoAccount> personaAccounts = entry.getValue();
matchCounter++;
// create a list of accounts missing from this persona // create a list of accounts missing from this persona
for (CentralRepoAccount account : contactUniqueAccountsList) { for (CentralRepoAccount account : contactUniqueAccountsList) {
@ -528,52 +404,51 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
} }
} }
showPersona(entry.getKey(), missingAccounts, gridBagLayout, constraints); showPersona(entry.getKey(), matchCounter, missingAccounts, m_gridBagLayout, m_constraints);
m_constraints.gridy += 2;
constraints.gridy += 2;
} }
} }
personasPanel.setLayout(gridBagLayout); // add veritcal glue at the end
personasPanel.setSize(personasPanel.getPreferredSize()); CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
personasPanel.revalidate();
personasPanel.repaint();
}
@NbBundle.Messages({ // redraw the panel
"ContactArtifactViewer_persona_label=Persona ", this.setLayout(this.m_gridBagLayout);
"ContactArtifactViewer_persona_text_none=None found", this.revalidate();
"ContactArtifactViewer_persona_button_view=View", this.repaint();
"ContactArtifactViewer_persona_button_new=Create", }
"ContactArtifactViewer_missing_account_label=Missing Account: "
})
/** /**
* Displays the given persona in the persona panel. * Displays the given persona in the persona panel.
* *
* @param persona Persona to display. * @param persona Persona to display.
* @param missingAccountsList List of accounts this persona may be missing. * @param missingAccountsList List of contact accounts this persona may be
* missing.
* @param gridBagLayout Layout to use. * @param gridBagLayout Layout to use.
* @param constraints layout constraints. * @param constraints layout constraints.
* *
* @throws CentralRepoException * @throws CentralRepoException
*/ */
private void showPersona(Persona persona, List<CentralRepoAccount> missingAccountsList, GridBagLayout gridBagLayout, GridBagConstraints constraints) { @NbBundle.Messages({
"ContactArtifactViewer_persona_label=Persona ",
"ContactArtifactViewer_persona_no_match=No matches found",
"ContactArtifactViewer_persona_button_view=View",
"ContactArtifactViewer_persona_button_new=Create",
"ContactArtifactViewer_persona_match_num=Match ",
"ContactArtifactViewer_missing_account_label=Missing contact account",
"ContactArtifactViewer_found_all_accounts_label=All accounts found."
})
private void showPersona(Persona persona, int matchNumber, List<CentralRepoAccount> missingAccountsList, GridBagLayout gridBagLayout, GridBagConstraints constraints) {
constraints.fill = GridBagConstraints.NONE; // save the original insets
constraints.weightx = 0; Insets savedInsets = constraints.insets;
// some label are indented 2x to appear indented w.r.t column above
Insets extraIndentInsets = new java.awt.Insets(0, 2 * CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
// Add a Match X label in col 0.
constraints.gridx = 0; constraints.gridx = 0;
javax.swing.JLabel matchNumberLabel = CommunicationArtifactViewerHelper.addKey(this, gridBagLayout, constraints, String.format("%s %d", Bundle.ContactArtifactViewer_persona_match_num(), matchNumber));
//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.JLabel personaNameLabel = new javax.swing.JLabel();
javax.swing.JButton personaButton = new javax.swing.JButton(); javax.swing.JButton personaButton = new javax.swing.JButton();
@ -581,60 +456,111 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
String personaName; String personaName;
String personaButtonText; String personaButtonText;
ActionListener personaButtonListener; ActionListener personaButtonListener;
if (persona != null) { if (persona != null) {
personaName = persona.getName(); personaName = persona.getName();
personaButtonText = Bundle.ContactArtifactViewer_persona_button_view(); personaButtonText = Bundle.ContactArtifactViewer_persona_button_view();
personaButtonListener = new ViewPersonaButtonListener(persona); personaButtonListener = new ViewPersonaButtonListener(this, persona);
} else { } else {
personaName = Bundle.ContactArtifactViewer_persona_text_none(); matchNumberLabel.setVisible(false);
personaName = Bundle.ContactArtifactViewer_persona_no_match();
personaButtonText = Bundle.ContactArtifactViewer_persona_button_new(); personaButtonText = Bundle.ContactArtifactViewer_persona_button_new();
personaButtonListener = new CreatePersonaButtonListener(new PersonaUIComponents(personaNameLabel, personaButton)); personaButtonListener = new CreatePersonaButtonListener(this, new PersonaUIComponents(personaNameLabel, personaButton));
} }
// Add the label for persona name, //constraints.gridwidth = 1; // TBD: this may not be needed if we use single panel
constraints.gridy++; constraints.gridx++;
constraints.gridx = 0;
personaNameLabel.setText(personaName); personaNameLabel.setText(personaName);
gridBagLayout.setConstraints(personaNameLabel, constraints); gridBagLayout.setConstraints(personaNameLabel, constraints);
personasPanel.add(personaNameLabel); CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaNameLabel);
//personasPanel.add(personaNameLabel);
//constraints.gridx++;
//personasPanel.add(createFiller(5, 0), constraints);
// Add a Persona action button // Add a Persona action button
constraints.gridx++; constraints.gridx++;
//constraints.gridwidth = 1;
personaButton.setText(personaButtonText); personaButton.setText(personaButtonText);
personaButton.addActionListener(personaButtonListener); personaButton.addActionListener(personaButtonListener);
// no top inset of the button, in order to center align with the labels. // Shirnk the button height.
constraints.insets = new java.awt.Insets(0, LEFT_INSET, 0, 0); personaButton.setMargin(new Insets(0, 5, 0, 5));
gridBagLayout.setConstraints(personaButton, constraints); gridBagLayout.setConstraints(personaButton, constraints);
personasPanel.add(personaButton); CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaButton);
CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints);
// restore normal inset constraints.insets = savedInsets;
constraints.insets = new java.awt.Insets(TOP_INSET, LEFT_INSET, 0, 0);
// 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++;
constraints.gridx = 1;
//constraints.insets = labelInsets;
javax.swing.JLabel accountsStatus = new javax.swing.JLabel(Bundle.ContactArtifactViewer_found_all_accounts_label());
constraints.insets = extraIndentInsets;
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, accountsStatus);
constraints.insets = savedInsets;
CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints);
} else {
// show missing accounts. // show missing accounts.
for (CentralRepoAccount missingAccount : missingAccountsList) { for (CentralRepoAccount missingAccount : missingAccountsList) {
constraints.weightx = 0; //constraints.weightx = 0;
constraints.gridx = 0; constraints.gridx = 0;
constraints.gridy++; constraints.gridy++;
// Add a "Missing Account: " label // this needs an extra indent
constraints.gridx++; // Ident constraints.insets = extraIndentInsets;
javax.swing.JLabel missingAccountLabel = new javax.swing.JLabel(); CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 1);
missingAccountLabel.setText(Bundle.ContactArtifactViewer_missing_account_label()); constraints.insets = savedInsets;
gridBagLayout.setConstraints(missingAccountLabel, constraints);
personasPanel.add(missingAccountLabel);
// Add the label for account id, CommunicationArtifactViewerHelper.addValueAtCol(this, gridBagLayout, constraints, missingAccount.getIdentifier(), 2);
constraints.gridx++;
javax.swing.JLabel missingAccountIdentifierLabel = new javax.swing.JLabel();
missingAccountIdentifierLabel.setText(missingAccount.getIdentifier());
gridBagLayout.setConstraints(missingAccountIdentifierLabel, constraints);
personasPanel.add(missingAccountIdentifierLabel);
} }
} }
}
// 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(Boolean.TRUE);
personaSearchTask = null;
}
// 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.0;
m_constraints.weightx = 0.0; // keep components fixed horizontally.
m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
m_constraints.fill = GridBagConstraints.NONE;
}
/** /**
* Gets an image from a TSK_CONTACT artifact. * Gets an image from a TSK_CONTACT artifact.
@ -666,7 +592,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
imageIcon = new ImageIcon(image); imageIcon = new ImageIcon(image);
break; break;
} catch (IOException ex) { } catch (IOException ex) {
// ImageIO.read will through an IOException if file is not an image // ImageIO.read will throw an IOException if file is not an image
// therefore we don't need to report this exception just try // therefore we don't need to report this exception just try
// the next file. // the next file.
} }
@ -703,6 +629,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
Map<Persona, ArrayList<CentralRepoAccount>> uniquePersonas = new HashMap<>(); Map<Persona, ArrayList<CentralRepoAccount>> uniquePersonas = new HashMap<>();
// TBD: this search needs to change to use the new method CommunicationsManager.getAccountsRelatedToArtifact
for (BlackboardAttribute bba : accountAttributesList) { for (BlackboardAttribute bba : accountAttributesList) {
// Get account, add to accounts list // Get account, add to accounts list
@ -736,7 +663,6 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
} }
} }
} }
} }
return uniquePersonas; return uniquePersonas;
@ -758,7 +684,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
contactUniqueAccountsList.clear(); contactUniqueAccountsList.clear();
contactUniqueAccountsList.addAll(uniqueAccountsList); contactUniqueAccountsList.addAll(uniqueAccountsList);
updatePersonasPanel(); updatePersonas();
} catch (CancellationException ex) { } catch (CancellationException ex) {
logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS
@ -815,6 +741,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
*/ */
private class CreatePersonaButtonListener implements ActionListener { private class CreatePersonaButtonListener implements ActionListener {
private final Component parentComponent;
private final PersonaUIComponents personaUIComponents; private final PersonaUIComponents personaUIComponents;
/** /**
@ -822,8 +749,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
* *
* @param personaUIComponents UI components. * @param personaUIComponents UI components.
*/ */
CreatePersonaButtonListener(PersonaUIComponents personaUIComponents) { CreatePersonaButtonListener(Component parentComponent, PersonaUIComponents personaUIComponents) {
this.personaUIComponents = personaUIComponents; this.personaUIComponents = personaUIComponents;
this.parentComponent = parentComponent;
} }
@NbBundle.Messages({ @NbBundle.Messages({
@ -833,8 +761,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
// Launch the Persona Create dialog - do not display immediately // Launch the Persona Create dialog - do not display immediately
PersonaDetailsDialog createPersonaDialog = new PersonaDetailsDialog(ContactArtifactViewer.this, PersonaDetailsDialog createPersonaDialog = new PersonaDetailsDialog(parentComponent,
PersonaDetailsMode.CREATE, null, new PersonaCreateCallbackImpl(personaUIComponents), false); PersonaDetailsMode.CREATE, null, new PersonaCreateCallbackImpl(parentComponent, personaUIComponents), false);
// Pre populate the persona name and accounts if we have them. // Pre populate the persona name and accounts if we have them.
PersonaDetailsPanel personaPanel = createPersonaDialog.getDetailsPanel(); PersonaDetailsPanel personaPanel = createPersonaDialog.getDetailsPanel();
@ -859,19 +787,21 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
private class ViewPersonaButtonListener implements ActionListener { private class ViewPersonaButtonListener implements ActionListener {
private final Persona persona; private final Persona persona;
private final Component parentComponent;
/** /**
* Creates listener for View persona button. * Creates listener for View persona button.
* *
* @param persona * @param persona
*/ */
ViewPersonaButtonListener(Persona persona) { ViewPersonaButtonListener(Component parentComponent, Persona persona) {
this.persona = persona; this.persona = persona;
this.parentComponent = parentComponent;
} }
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
new PersonaDetailsDialog(ContactArtifactViewer.this, new PersonaDetailsDialog(parentComponent,
PersonaDetailsMode.VIEW, persona, new PersonaViewCallbackImpl()); PersonaDetailsMode.VIEW, persona, new PersonaViewCallbackImpl());
} }
} }
@ -881,6 +811,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
*/ */
class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback { class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback {
private final Component parentComponent;
private final PersonaUIComponents personaUIComponents; private final PersonaUIComponents personaUIComponents;
/** /**
@ -888,7 +819,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
* *
* @param personaUIComponents UI Components. * @param personaUIComponents UI Components.
*/ */
PersonaCreateCallbackImpl(PersonaUIComponents personaUIComponents) { PersonaCreateCallbackImpl(Component parentComponent, PersonaUIComponents personaUIComponents) {
this.parentComponent = parentComponent;
this.personaUIComponents = personaUIComponents; this.personaUIComponents = personaUIComponents;
} }
@ -905,7 +837,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
for (ActionListener act : personaButton.getActionListeners()) { for (ActionListener act : personaButton.getActionListeners()) {
personaButton.removeActionListener(act); personaButton.removeActionListener(act);
} }
personaButton.addActionListener(new ViewPersonaButtonListener(persona)); personaButton.addActionListener(new ViewPersonaButtonListener(parentComponent, persona));
} }
@ -925,18 +857,6 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
} }
} }
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel contactImage;
private javax.swing.JLabel contactNameLabel;
private javax.swing.JLabel emailsLabel;
private javax.swing.JPanel emailsPanel;
private javax.swing.JPanel namePanel;
private javax.swing.JPanel otherAttrsPanel;
private javax.swing.JLabel othersLabel;
private javax.swing.JLabel personasLabel;
private javax.swing.JPanel personasPanel;
private javax.swing.JPanel phoneNumbersPanel;
private javax.swing.JLabel phonesLabel;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -1,5 +1,5 @@
#Updated by build script #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 LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314 SPLASH_HEIGHT=314
SPLASH_WIDTH=538 SPLASH_WIDTH=538

View File

@ -1,4 +1,4 @@
#Updated by build script #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=Autopsy 4.15.0
CTL_MainWindow_Title_No_Project=Autopsy 4.15.0 CTL_MainWindow_Title_No_Project=Autopsy 4.15.0