mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge branch 'release-4.12.0' of https://github.com/sleuthkit/autopsy into 5187-LogicalImagerGUITweaks
This commit is contained in:
commit
78e8ecfbb3
@ -75,7 +75,7 @@ file.reference.javax.ws.rs-api-2.0.1.jar=release/modules/ext/javax.ws.rs-api-2.0
|
|||||||
file.reference.cxf-core-3.0.16.jar=release/modules/ext/cxf-core-3.0.16.jar
|
file.reference.cxf-core-3.0.16.jar=release/modules/ext/cxf-core-3.0.16.jar
|
||||||
file.reference.cxf-rt-frontend-jaxrs-3.0.16.jar=release/modules/ext/cxf-rt-frontend-jaxrs-3.0.16.jar
|
file.reference.cxf-rt-frontend-jaxrs-3.0.16.jar=release/modules/ext/cxf-rt-frontend-jaxrs-3.0.16.jar
|
||||||
file.reference.cxf-rt-transports-http-3.0.16.jar=release/modules/ext/cxf-rt-transports-http-3.0.16.jar
|
file.reference.cxf-rt-transports-http-3.0.16.jar=release/modules/ext/cxf-rt-transports-http-3.0.16.jar
|
||||||
file.reference.sleuthkit-postgresql-4.6.6.jar=release/modules/ext/sleuthkit-postgresql-4.6.6.jar
|
file.reference.sleuthkit-postgresql-4.6.7.jar=release/modules/ext/sleuthkit-postgresql-4.6.7.jar
|
||||||
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
||||||
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
|
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
|
||||||
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
|
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
|
||||||
|
@ -482,8 +482,8 @@
|
|||||||
<binary-origin>release\modules\ext\jmatio-1.5.jar</binary-origin>
|
<binary-origin>release\modules\ext\jmatio-1.5.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/sleuthkit-postgresql-4.6.6.jar</runtime-relative-path>
|
<runtime-relative-path>ext/sleuthkit-postgresql-4.6.7.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/sleuthkit-postgresql-4.6.6.jar</binary-origin>
|
<binary-origin>release/modules/ext/sleuthkit-postgresql-4.6.7.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/tika-parsers-1.20.jar</runtime-relative-path>
|
<runtime-relative-path>ext/tika-parsers-1.20.jar</runtime-relative-path>
|
||||||
|
BIN
Core/src/org/sleuthkit/autopsy/communications/images/nail.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/communications/images/nail.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 202 B |
BIN
Core/src/org/sleuthkit/autopsy/communications/images/screw.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/communications/images/screw.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 217 B |
BIN
Core/src/org/sleuthkit/autopsy/communications/images/threaded.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/communications/images/threaded.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 263 B |
BIN
Core/src/org/sleuthkit/autopsy/communications/images/unthreaded.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/communications/images/unthreaded.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 199 B |
@ -11,5 +11,13 @@ SummaryViewer.emailDataLabel.text=emails
|
|||||||
SummaryViewer.attachmentsDataLabel.text=attachments
|
SummaryViewer.attachmentsDataLabel.text=attachments
|
||||||
SummaryViewer.messagesLabel.text=Messages:
|
SummaryViewer.messagesLabel.text=Messages:
|
||||||
SummaryViewer.callLogsLabel.text=Call Logs:
|
SummaryViewer.callLogsLabel.text=Call Logs:
|
||||||
|
ThreadRootMessagePanel.showAllCheckBox.text=Show All Messages
|
||||||
|
ThreadPane.backButton.text=<---
|
||||||
SummaryViewer.caseReferencesPanel.border.title=Other Occurrences
|
SummaryViewer.caseReferencesPanel.border.title=Other Occurrences
|
||||||
SummaryViewer.fileReferencesPanel.border.title=File References in Current Case
|
SummaryViewer.fileReferencesPanel.border.title=File References in Current Case
|
||||||
|
MessageViewer.threadsLabel.text=Select a Thread to View
|
||||||
|
MessageViewer.threadNameLabel.text=<threadName>
|
||||||
|
MessageViewer.showingMessagesLabel.text=Showing Messages for Thread:
|
||||||
|
MessageViewer.backButton.AccessibleContext.accessibleDescription=
|
||||||
|
MessageViewer.backButton.text=Threads
|
||||||
|
MessageViewer.showAllButton.text=All Messages
|
||||||
|
@ -19,12 +19,16 @@ MessageNode_Node_Property_Subject=Subject
|
|||||||
MessageNode_Node_Property_To=To
|
MessageNode_Node_Property_To=To
|
||||||
MessageNode_Node_Property_Type=Type
|
MessageNode_Node_Property_Type=Type
|
||||||
MessageViewer_columnHeader_Attms=Attachments
|
MessageViewer_columnHeader_Attms=Attachments
|
||||||
MessageViewer_columnHeader_Date=Date
|
MessageViewer_columnHeader_Date=Data
|
||||||
|
MessageViewer_columnHeader_EarlyDate=Earliest Message
|
||||||
MessageViewer_columnHeader_From=From
|
MessageViewer_columnHeader_From=From
|
||||||
MessageViewer_columnHeader_Subject=Subject
|
MessageViewer_columnHeader_Subject=Subject
|
||||||
MessageViewer_columnHeader_To=To
|
MessageViewer_columnHeader_To=To
|
||||||
MessageViewer_no_messages=<No messages found for selected account>
|
MessageViewer_no_messages=<No messages found for selected account>
|
||||||
MessageViewer_tabTitle=Messages
|
MessageViewer_tabTitle=Messages
|
||||||
|
MessageViewer_viewMessage_all=All
|
||||||
|
MessageViewer_viewMessage_selected=Selected
|
||||||
|
MessageViewer_viewMessage_unthreaded=Unthreaded
|
||||||
SummaryViewer.countsPanel.border.title=Counts
|
SummaryViewer.countsPanel.border.title=Counts
|
||||||
SummaryViewer.emailLabel.text=Emails:
|
SummaryViewer.emailLabel.text=Emails:
|
||||||
SummaryViewer.contactsLabel.text=Contacts:
|
SummaryViewer.contactsLabel.text=Contacts:
|
||||||
@ -37,11 +41,19 @@ SummaryViewer.emailDataLabel.text=emails
|
|||||||
SummaryViewer.attachmentsDataLabel.text=attachments
|
SummaryViewer.attachmentsDataLabel.text=attachments
|
||||||
SummaryViewer.messagesLabel.text=Messages:
|
SummaryViewer.messagesLabel.text=Messages:
|
||||||
SummaryViewer.callLogsLabel.text=Call Logs:
|
SummaryViewer.callLogsLabel.text=Call Logs:
|
||||||
SummaryViewer.caseReferencesPanel.border.title=Other Occurrences
|
|
||||||
SummaryViewer.fileReferencesPanel.border.title=File References in Current Case
|
|
||||||
SummaryViewer_CaseRefNameColumn_Title=Case Name
|
SummaryViewer_CaseRefNameColumn_Title=Case Name
|
||||||
SummaryViewer_CentralRepository_Message=<Enable Central Resposity to see Other Occurrences>
|
SummaryViewer_CentralRepository_Message=<Enable Central Resposity to see Other Occurrences>
|
||||||
SummaryViewer_Creation_Date_Title=Creation Date
|
SummaryViewer_Creation_Date_Title=Creation Date
|
||||||
SummaryViewer_FileRefNameColumn_Title=Path
|
SummaryViewer_FileRefNameColumn_Title=Path
|
||||||
SummaryViewer_TabTitle=Summary
|
SummaryViewer_TabTitle=Summary
|
||||||
SummeryViewer_FileRef_Message=<Select one Accout to see File References>
|
SummeryViewer_FileRef_Message=<Select one Accout to see File References>
|
||||||
|
ThreadRootMessagePanel.showAllCheckBox.text=Show All Messages
|
||||||
|
ThreadPane.backButton.text=<---
|
||||||
|
SummaryViewer.caseReferencesPanel.border.title=Other Occurrences
|
||||||
|
SummaryViewer.fileReferencesPanel.border.title=File References in Current Case
|
||||||
|
MessageViewer.threadsLabel.text=Select a Thread to View
|
||||||
|
MessageViewer.threadNameLabel.text=<threadName>
|
||||||
|
MessageViewer.showingMessagesLabel.text=Showing Messages for Thread:
|
||||||
|
MessageViewer.backButton.AccessibleContext.accessibleDescription=
|
||||||
|
MessageViewer.backButton.text=Threads
|
||||||
|
MessageViewer.showAllButton.text=All Messages
|
||||||
|
@ -17,34 +17,7 @@
|
|||||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
<Layout>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="propertySheet" max="32767" attributes="0"/>
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="propertySheet" pref="283" max="32767" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JLabel" name="nameLabel">
|
<Component class="javax.swing.JLabel" name="nameLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -55,11 +28,21 @@
|
|||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="ContactDetailsPane.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="ContactDetailsPane.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</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="0" ipadY="0" insetsTop="16" insetsLeft="15" insetsBottom="15" insetsRight="15" anchor="23" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="org.openide.explorer.propertysheet.PropertySheet" name="propertySheet">
|
<Component class="org.openide.explorer.propertysheet.PropertySheet" name="propertySheet">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="descriptionAreaVisible" type="boolean" value="false"/>
|
<Property name="descriptionAreaVisible" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<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="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="15" insetsBottom="16" insetsRight="15" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -73,38 +73,36 @@ public final class ContactDetailsPane extends javax.swing.JPanel implements Expl
|
|||||||
@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;
|
||||||
|
|
||||||
messageContentViewer1 = new org.sleuthkit.autopsy.contentviewers.MessageContentViewer();
|
messageContentViewer1 = new org.sleuthkit.autopsy.contentviewers.MessageContentViewer();
|
||||||
nameLabel = new javax.swing.JLabel();
|
nameLabel = new javax.swing.JLabel();
|
||||||
propertySheet = new org.openide.explorer.propertysheet.PropertySheet();
|
propertySheet = new org.openide.explorer.propertysheet.PropertySheet();
|
||||||
|
|
||||||
|
setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
nameLabel.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
|
nameLabel.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(ContactDetailsPane.class, "ContactDetailsPane.nameLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(ContactDetailsPane.class, "ContactDetailsPane.nameLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(16, 15, 15, 15);
|
||||||
|
add(nameLabel, gridBagConstraints);
|
||||||
|
|
||||||
propertySheet.setDescriptionAreaVisible(false);
|
propertySheet.setDescriptionAreaVisible(false);
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
gridBagConstraints.gridx = 0;
|
||||||
this.setLayout(layout);
|
gridBagConstraints.gridy = 1;
|
||||||
layout.setHorizontalGroup(
|
gridBagConstraints.gridwidth = 2;
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||||
.addGroup(layout.createSequentialGroup()
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
.addContainerGap()
|
gridBagConstraints.weightx = 1.0;
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
gridBagConstraints.weighty = 1.0;
|
||||||
.addComponent(propertySheet, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
gridBagConstraints.insets = new java.awt.Insets(9, 15, 16, 15);
|
||||||
.addGroup(layout.createSequentialGroup()
|
add(propertySheet, gridBagConstraints);
|
||||||
.addComponent(nameLabel)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)))
|
|
||||||
.addContainerGap())
|
|
||||||
);
|
|
||||||
layout.setVerticalGroup(
|
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addComponent(nameLabel)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(propertySheet, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)
|
|
||||||
.addContainerGap())
|
|
||||||
);
|
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* ChildFactory for ContactNodes.
|
* ChildFactory for ContactNodes.
|
||||||
*/
|
*/
|
||||||
final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
||||||
private static final Logger logger = Logger.getLogger(MessagesChildNodeFactory.class.getName());
|
private static final Logger logger = Logger.getLogger(ContactsChildNodeFactory.class.getName());
|
||||||
|
|
||||||
private SelectionInfo selectionInfo;
|
private SelectionInfo selectionInfo;
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ package org.sleuthkit.autopsy.communications.relationships;
|
|||||||
|
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.Action;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
@ -40,20 +40,31 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBU
|
|||||||
import org.sleuthkit.datamodel.TimeUtilities;
|
import org.sleuthkit.datamodel.TimeUtilities;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.autopsy.communications.Utils;
|
import org.sleuthkit.autopsy.communications.Utils;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps a BlackboardArtifact as an AbstractNode for use in an OutlookView
|
* Wraps a BlackboardArtifact as an AbstractNode for use in an OutlookView
|
||||||
*/
|
*/
|
||||||
final class MessageNode extends BlackboardArtifactNode {
|
class MessageNode extends BlackboardArtifactNode {
|
||||||
|
|
||||||
|
public static final String UNTHREADED_ID = "<UNTHREADED>";
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(MessageNode.class.getName());
|
private static final Logger logger = Logger.getLogger(MessageNode.class.getName());
|
||||||
|
|
||||||
|
private final String threadID;
|
||||||
|
|
||||||
|
private final Action preferredAction;
|
||||||
|
|
||||||
MessageNode(BlackboardArtifact artifact) {
|
MessageNode(BlackboardArtifact artifact, String threadID, Action preferredAction) {
|
||||||
super(artifact);
|
super(artifact);
|
||||||
|
|
||||||
|
this.preferredAction = preferredAction;
|
||||||
|
|
||||||
final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); // NON-NLS
|
final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); // NON-NLS
|
||||||
String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); // NON-NLS
|
String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); // NON-NLS
|
||||||
setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase);
|
setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase);
|
||||||
|
|
||||||
|
this.threadID = threadID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Messages({
|
@Messages({
|
||||||
@ -75,6 +86,8 @@ final class MessageNode extends BlackboardArtifactNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sheetSet.put(new NodeProperty<>("Type", Bundle.MessageNode_Node_Property_Type(), "", getDisplayName())); //NON-NLS
|
sheetSet.put(new NodeProperty<>("Type", Bundle.MessageNode_Node_Property_Type(), "", getDisplayName())); //NON-NLS
|
||||||
|
|
||||||
|
sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",threadID == null ? UNTHREADED_ID : threadID)); //NON-NLS
|
||||||
|
|
||||||
final BlackboardArtifact artifact = getArtifact();
|
final BlackboardArtifact artifact = getArtifact();
|
||||||
|
|
||||||
@ -167,4 +180,13 @@ final class MessageNode extends BlackboardArtifactNode {
|
|||||||
public String getSourceName() {
|
public String getSourceName() {
|
||||||
return getDisplayName();
|
return getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getThreadID() {
|
||||||
|
return threadID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Action getPreferredAction() {
|
||||||
|
return preferredAction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
140
Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.form
Executable file
140
Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.form
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<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,3,-126,0,0,2,-76"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="rootMessagesPane">
|
||||||
|
<Properties>
|
||||||
|
<Property name="opaque" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||||
|
<CardConstraints cardName="threads"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JLabel" name="threadsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="MessageViewer.threadsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</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="0" ipadY="0" insetsTop="15" insetsLeft="15" insetsBottom="9" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="showAllButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="MessageViewer.showAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showAllButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<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="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="15" insetsBottom="15" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel" name="rootTablePane">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
||||||
|
<LineBorder/>
|
||||||
|
</Border>
|
||||||
|
</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="1" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="15" insetsBottom="9" insetsRight="15" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JPanel" name="messagePanel">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||||
|
<CardConstraints cardName="messages"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="org.sleuthkit.autopsy.communications.relationships.MessagesPanel" name="threadMessagesPanel">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new MessagesPanel()"/>
|
||||||
|
</AuxValues>
|
||||||
|
<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="3" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="15" insetsBottom="0" insetsRight="15" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="backButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="MessageViewer.backButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AccessibilityProperties>
|
||||||
|
<Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="MessageViewer.backButton.AccessibleContext.accessibleDescription" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</AccessibilityProperties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="backButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="0" insetsBottom="9" insetsRight="15" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="showingMessagesLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="MessageViewer.showingMessagesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</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="9" insetsLeft="15" insetsBottom="5" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="threadNameLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="MessageViewer.threadNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="5" insetsBottom="5" insetsRight="15" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
439
Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java
Executable file
439
Core/src/org/sleuthkit/autopsy/communications/relationships/MessageViewer.java
Executable file
@ -0,0 +1,439 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications.relationships;
|
||||||
|
|
||||||
|
import java.awt.CardLayout;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.KeyboardFocusManager;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.beans.PropertyVetoException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||||
|
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||||
|
import org.netbeans.swing.outline.Outline;
|
||||||
|
import org.openide.explorer.ExplorerManager;
|
||||||
|
import static org.openide.explorer.ExplorerUtils.createLookup;
|
||||||
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.Children;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.nodes.Node.Property;
|
||||||
|
import org.openide.nodes.Node.PropertySet;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main panel for the messages tab of the RelationshipViewer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
|
public class MessageViewer extends JPanel implements RelationshipsViewer {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(MessageViewer.class.getName());
|
||||||
|
|
||||||
|
private final ModifiableProxyLookup proxyLookup;
|
||||||
|
private final PropertyChangeListener focusPropertyListener;
|
||||||
|
private final ThreadChildNodeFactory rootMessageFactory;
|
||||||
|
private final MessagesChildNodeFactory threadMessageNodeFactory;
|
||||||
|
|
||||||
|
private SelectionInfo currentSelectionInfo = null;
|
||||||
|
|
||||||
|
OutlineViewPanel currentPanel;
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MessageViewer_tabTitle=Messages",
|
||||||
|
"MessageViewer_columnHeader_From=From",
|
||||||
|
"MessageViewer_columnHeader_Date=Data",
|
||||||
|
"MessageViewer_columnHeader_To=To",
|
||||||
|
"MessageViewer_columnHeader_EarlyDate=Earliest Message",
|
||||||
|
"MessageViewer_columnHeader_Subject=Subject",
|
||||||
|
"MessageViewer_columnHeader_Attms=Attachments",
|
||||||
|
"MessageViewer_no_messages=<No messages found for selected account>",
|
||||||
|
"MessageViewer_viewMessage_all=All",
|
||||||
|
"MessageViewer_viewMessage_selected=Selected",
|
||||||
|
"MessageViewer_viewMessage_unthreaded=Unthreaded",})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form MessageViewer
|
||||||
|
*/
|
||||||
|
public MessageViewer() {
|
||||||
|
|
||||||
|
initComponents();
|
||||||
|
currentPanel = rootTablePane;
|
||||||
|
proxyLookup = new ModifiableProxyLookup(createLookup(rootTablePane.getExplorerManager(), getActionMap()));
|
||||||
|
rootMessageFactory = new ThreadChildNodeFactory(new ShowThreadMessagesAction());
|
||||||
|
threadMessageNodeFactory = new MessagesChildNodeFactory();
|
||||||
|
|
||||||
|
// See org.sleuthkit.autopsy.timeline.TimeLineTopComponent for a detailed
|
||||||
|
// explaination of focusPropertyListener
|
||||||
|
focusPropertyListener = (final PropertyChangeEvent focusEvent) -> {
|
||||||
|
if (focusEvent.getPropertyName().equalsIgnoreCase("focusOwner")) {
|
||||||
|
final Component newFocusOwner = (Component) focusEvent.getNewValue();
|
||||||
|
|
||||||
|
if (newFocusOwner == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isDescendingFrom(newFocusOwner, rootTablePane)) {
|
||||||
|
proxyLookup.setNewLookups(createLookup(rootTablePane.getExplorerManager(), getActionMap()));
|
||||||
|
} else if (isDescendingFrom(newFocusOwner, MessageViewer.this)) {
|
||||||
|
proxyLookup.setNewLookups(createLookup(currentPanel.getExplorerManager(), getActionMap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rootTablePane.getExplorerManager().setRootContext(
|
||||||
|
new AbstractNode(Children.create(rootMessageFactory, true)));
|
||||||
|
|
||||||
|
rootTablePane.getOutlineView().setPopupAllowed(false);
|
||||||
|
|
||||||
|
Outline outline = rootTablePane.getOutlineView().getOutline();
|
||||||
|
rootTablePane.getOutlineView().setPropertyColumns(
|
||||||
|
"Date", Bundle.MessageViewer_columnHeader_EarlyDate(),
|
||||||
|
"Subject", Bundle.MessageViewer_columnHeader_Subject()
|
||||||
|
);
|
||||||
|
outline.setRootVisible(false);
|
||||||
|
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel("Type");
|
||||||
|
outline.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
|
||||||
|
|
||||||
|
rootTablePane.getExplorerManager().addPropertyChangeListener((PropertyChangeEvent evt) -> {
|
||||||
|
if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
|
||||||
|
showSelectedThread();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
threadMessagesPanel.setChildFactory(threadMessageNodeFactory);
|
||||||
|
|
||||||
|
rootTablePane.setTableColumnsWidth(10, 20, 70);
|
||||||
|
|
||||||
|
Image image = getScaledImage((new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/timeline/images/arrow-180.png"))).getImage(), 16, 16);
|
||||||
|
backButton.setIcon(new ImageIcon(image) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return Bundle.MessageViewer_tabTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JPanel getPanel() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelectionInfo(SelectionInfo info) {
|
||||||
|
currentSelectionInfo = info;
|
||||||
|
|
||||||
|
currentPanel = rootTablePane;
|
||||||
|
|
||||||
|
CardLayout layout = (CardLayout) this.getLayout();
|
||||||
|
layout.show(this, "threads");
|
||||||
|
|
||||||
|
rootMessageFactory.refresh(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Lookup getLookup() {
|
||||||
|
return proxyLookup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotify() {
|
||||||
|
super.addNotify();
|
||||||
|
//add listener that maintains correct selection in the Global Actions Context
|
||||||
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
|
.addPropertyChangeListener("focusOwner", focusPropertyListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeNotify() {
|
||||||
|
super.removeNotify();
|
||||||
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
|
.removePropertyChangeListener("focusOwner", focusPropertyListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private void showSelectedThread() {
|
||||||
|
final Node[] nodes = rootTablePane.getExplorerManager().getSelectedNodes();
|
||||||
|
|
||||||
|
if (nodes == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes.length == 0 || nodes.length > 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> threadIDList = new ArrayList<>();
|
||||||
|
String subject = "";
|
||||||
|
|
||||||
|
PropertySet[] propertySets = nodes[0].getPropertySets();
|
||||||
|
for (PropertySet pset : propertySets) {
|
||||||
|
Property[] properties = pset.getProperties();
|
||||||
|
for (Property prop : properties) {
|
||||||
|
if (prop.getName().equalsIgnoreCase("threadid")) {
|
||||||
|
try {
|
||||||
|
String threadID = prop.getValue().toString();
|
||||||
|
if (!threadIDList.contains(threadID)) {
|
||||||
|
threadIDList.add(threadID);
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("Unable to get threadid for node: %s", nodes[0].getDisplayName()), ex);
|
||||||
|
}
|
||||||
|
} else if (prop.getName().equalsIgnoreCase("subject")) {
|
||||||
|
try {
|
||||||
|
subject = prop.getValue().toString();
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("Unable to get subject for node: %s", nodes[0].getDisplayName()), ex);
|
||||||
|
subject = "<unavailable>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!threadIDList.isEmpty()) {
|
||||||
|
threadMessageNodeFactory.refresh(currentSelectionInfo, threadIDList);
|
||||||
|
|
||||||
|
if (!subject.isEmpty()) {
|
||||||
|
threadNameLabel.setText(subject);
|
||||||
|
} else {
|
||||||
|
threadNameLabel.setText(Bundle.MessageViewer_viewMessage_unthreaded());
|
||||||
|
}
|
||||||
|
|
||||||
|
showMessagesPane();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the threads pane visible.
|
||||||
|
*/
|
||||||
|
private void showThreadsPane() {
|
||||||
|
switchCard("threads");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the message pane visible.
|
||||||
|
*/
|
||||||
|
private void showMessagesPane() {
|
||||||
|
switchCard("messages");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the visible panel (card).
|
||||||
|
*
|
||||||
|
* @param cardName Name of card to show
|
||||||
|
*/
|
||||||
|
private void switchCard(String cardName) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CardLayout layout = (CardLayout)getLayout();
|
||||||
|
layout.show(MessageViewer.this, cardName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scales the given image to the given width and height.
|
||||||
|
*
|
||||||
|
* @param srcImg Image to scale
|
||||||
|
* @param w Image width
|
||||||
|
* @param h Image height
|
||||||
|
*
|
||||||
|
* @return Scaled version of srcImg
|
||||||
|
*/
|
||||||
|
private Image getScaledImage(Image srcImg, int w, int h){
|
||||||
|
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g2 = resizedImg.createGraphics();
|
||||||
|
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||||
|
g2.drawImage(srcImg, 0, 0, w, h, null);
|
||||||
|
g2.dispose();
|
||||||
|
|
||||||
|
return resizedImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.'
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
rootMessagesPane = new javax.swing.JPanel();
|
||||||
|
threadsLabel = new javax.swing.JLabel();
|
||||||
|
showAllButton = new javax.swing.JButton();
|
||||||
|
rootTablePane = new org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel();
|
||||||
|
messagePanel = new javax.swing.JPanel();
|
||||||
|
threadMessagesPanel = new MessagesPanel();
|
||||||
|
backButton = new javax.swing.JButton();
|
||||||
|
showingMessagesLabel = new javax.swing.JLabel();
|
||||||
|
threadNameLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
setLayout(new java.awt.CardLayout());
|
||||||
|
|
||||||
|
rootMessagesPane.setOpaque(false);
|
||||||
|
rootMessagesPane.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(threadsLabel, org.openide.util.NbBundle.getMessage(MessageViewer.class, "MessageViewer.threadsLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(15, 15, 9, 0);
|
||||||
|
rootMessagesPane.add(threadsLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(showAllButton, org.openide.util.NbBundle.getMessage(MessageViewer.class, "MessageViewer.showAllButton.text")); // NOI18N
|
||||||
|
showAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
showAllButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 15, 15, 0);
|
||||||
|
rootMessagesPane.add(showAllButton, gridBagConstraints);
|
||||||
|
|
||||||
|
rootTablePane.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.gridwidth = 2;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.weighty = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 15, 9, 15);
|
||||||
|
rootMessagesPane.add(rootTablePane, gridBagConstraints);
|
||||||
|
|
||||||
|
add(rootMessagesPane, "threads");
|
||||||
|
|
||||||
|
messagePanel.setLayout(new java.awt.GridBagLayout());
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 3;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.weighty = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 15, 0, 15);
|
||||||
|
messagePanel.add(threadMessagesPanel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(backButton, org.openide.util.NbBundle.getMessage(MessageViewer.class, "MessageViewer.backButton.text")); // NOI18N
|
||||||
|
backButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
backButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 2;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 0, 9, 15);
|
||||||
|
messagePanel.add(backButton, gridBagConstraints);
|
||||||
|
backButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(MessageViewer.class, "MessageViewer.backButton.AccessibleContext.accessibleDescription")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(showingMessagesLabel, org.openide.util.NbBundle.getMessage(MessageViewer.class, "MessageViewer.showingMessagesLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 15, 5, 0);
|
||||||
|
messagePanel.add(showingMessagesLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(threadNameLabel, org.openide.util.NbBundle.getMessage(MessageViewer.class, "MessageViewer.threadNameLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 5, 5, 15);
|
||||||
|
messagePanel.add(threadNameLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
add(messagePanel, "messages");
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void backButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backButtonActionPerformed
|
||||||
|
try {
|
||||||
|
rootTablePane.getExplorerManager().setSelectedNodes(new Node[0]);
|
||||||
|
} catch (PropertyVetoException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
showThreadsPane();
|
||||||
|
}//GEN-LAST:event_backButtonActionPerformed
|
||||||
|
|
||||||
|
private void showAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showAllButtonActionPerformed
|
||||||
|
threadMessageNodeFactory.refresh(currentSelectionInfo, null);
|
||||||
|
threadNameLabel.setText("All Messages");
|
||||||
|
|
||||||
|
showMessagesPane();
|
||||||
|
}//GEN-LAST:event_showAllButtonActionPerformed
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JButton backButton;
|
||||||
|
private javax.swing.JPanel messagePanel;
|
||||||
|
private javax.swing.JPanel rootMessagesPane;
|
||||||
|
private org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel rootTablePane;
|
||||||
|
private javax.swing.JButton showAllButton;
|
||||||
|
private javax.swing.JLabel showingMessagesLabel;
|
||||||
|
private org.sleuthkit.autopsy.communications.relationships.MessagesPanel threadMessagesPanel;
|
||||||
|
private javax.swing.JLabel threadNameLabel;
|
||||||
|
private javax.swing.JLabel threadsLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The preferred action of the table nodes.
|
||||||
|
*/
|
||||||
|
class ShowThreadMessagesAction extends AbstractAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
showSelectedThread();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,52 +27,51 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
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.CommunicationsManager;
|
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ChildFactory that creates createKeys and nodes from a given selectionInfo for
|
* A ChildFactory subclass for creating MessageNodes from a set of
|
||||||
* only emails, call logs and messages.
|
* BlackboardArtifact objects.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact> {
|
public class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(MessagesChildNodeFactory.class.getName());
|
private static final Logger logger = Logger.getLogger(MessagesChildNodeFactory.class.getName());
|
||||||
|
|
||||||
private SelectionInfo selectionInfo;
|
private SelectionInfo selectionInfo;
|
||||||
|
|
||||||
/**
|
private List<String> threadIDs;
|
||||||
* Construct a new MessageChildNodeFactory from the currently selectionInfo
|
|
||||||
*
|
MessagesChildNodeFactory(SelectionInfo selectionInfo, List<String> threadIDs) {
|
||||||
* @param selectionInfo SelectionInfo object for the currently selected
|
|
||||||
* accounts
|
|
||||||
*/
|
|
||||||
MessagesChildNodeFactory(SelectionInfo selectionInfo) {
|
|
||||||
this.selectionInfo = selectionInfo;
|
this.selectionInfo = selectionInfo;
|
||||||
|
this.threadIDs = threadIDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessagesChildNodeFactory() {
|
||||||
|
this(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the current instance of selectionInfo and calls the refresh method.
|
* Updates the current instance of selectionInfo and calls the refresh method.
|
||||||
*
|
*
|
||||||
* @param selectionInfo New instance of the currently selected accounts
|
* @param selectionInfo New instance of the currently selected accounts
|
||||||
|
* @param threadIDs A list of threadIDs to filter the keys by, null will
|
||||||
|
* return all keys for the selected accounts.
|
||||||
*/
|
*/
|
||||||
public void refresh(SelectionInfo selectionInfo) {
|
public void refresh(SelectionInfo selectionInfo, List<String> threadIDs) {
|
||||||
this.selectionInfo = selectionInfo;
|
this.threadIDs = threadIDs;
|
||||||
|
this.selectionInfo = selectionInfo;
|
||||||
refresh(true);
|
refresh(true);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Creates a list of Keys (BlackboardArtifact) for only messages for the
|
|
||||||
* currently selected accounts
|
|
||||||
*
|
|
||||||
* @param list List of BlackboardArtifact to populate
|
|
||||||
*
|
|
||||||
* @return True on success
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean createKeys(List<BlackboardArtifact> list) {
|
protected boolean createKeys(List<BlackboardArtifact> list) {
|
||||||
CommunicationsManager communicationManager;
|
CommunicationsManager communicationManager;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
|
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
|
||||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
@ -87,19 +86,37 @@ final class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact> {
|
|||||||
final Set<Content> relationshipSources;
|
final Set<Content> relationshipSources;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
|
relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
|
||||||
|
for(Content content: relationshipSources) {
|
||||||
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
|
if( !(content instanceof BlackboardArtifact)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
BlackboardArtifact bba = (BlackboardArtifact) content;
|
BlackboardArtifact bba = (BlackboardArtifact) content;
|
||||||
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
|
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
|
||||||
|
|
||||||
if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG
|
if (fromID != BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG
|
||||||
|| fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG
|
&& fromID != BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG
|
||||||
|| fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) {
|
&& fromID != BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want all artifacts that do not have "threadIDs" to appear as one thread in the UI
|
||||||
|
// To achive this assign any artifact that does not have a threadID
|
||||||
|
// the "UNTHREADED_ID"
|
||||||
|
String artifactThreadID = MessageNode.UNTHREADED_ID;
|
||||||
|
BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
|
||||||
|
|
||||||
|
if(attribute != null) {
|
||||||
|
artifactThreadID = attribute.getValueString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(threadIDs == null || threadIDs.contains(artifactThreadID)) {
|
||||||
list.add(bba);
|
list.add(bba);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
}
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
|
||||||
@ -107,9 +124,10 @@ final class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact> {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node createNodeForKey(BlackboardArtifact key) {
|
protected Node createNodeForKey(BlackboardArtifact key) {
|
||||||
return new MessageNode(key);
|
return new MessageNode(key, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<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,33 +11,23 @@
|
|||||||
<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,3,13,0,0,2,103"/>
|
<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.DesignBorderLayout"/>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Container class="javax.swing.JSplitPane" name="splitPane">
|
<Container class="javax.swing.JSplitPane" name="splitPane">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="orientation" type="int" value="0"/>
|
<Property name="orientation" type="int" value="0"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
|
<BorderConstraints direction="Center"/>
|
||||||
</Constraint>
|
</Constraint>
|
||||||
</Constraints>
|
</Constraints>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="org.sleuthkit.autopsy.contentviewers.MessageContentViewer" name="contentViewer">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new MessageDataContent()"/>
|
|
||||||
</AuxValues>
|
|
||||||
<Constraints>
|
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
|
||||||
<JSplitPaneConstraints position="bottom"/>
|
|
||||||
</Constraint>
|
|
||||||
</Constraints>
|
|
||||||
</Component>
|
|
||||||
<Component class="org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel" name="outlineViewPanel">
|
<Component class="org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel" name="outlineViewPanel">
|
||||||
<Constraints>
|
<Constraints>
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||||
@ -45,6 +35,16 @@
|
|||||||
</Constraint>
|
</Constraint>
|
||||||
</Constraints>
|
</Constraints>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="org.sleuthkit.autopsy.contentviewers.MessageContentViewer" name="messageContentViewer">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new MessageDataContent()"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||||
|
<JSplitPaneConstraints position="right"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obt ain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
@ -22,57 +22,38 @@ import java.awt.Component;
|
|||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||||
import org.netbeans.swing.outline.Outline;
|
import org.netbeans.swing.outline.Outline;
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
import static org.openide.explorer.ExplorerUtils.createLookup;
|
import static org.openide.explorer.ExplorerUtils.createLookup;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.NodeAdapter;
|
|
||||||
import org.openide.nodes.NodeMemberEvent;
|
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.openide.util.NbBundle.Messages;
|
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
|
||||||
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
||||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visualation for the messages of the currently selected accounts.
|
*
|
||||||
|
* General Purpose class for panels that need OutlineView of message nodes at
|
||||||
|
* the top with a MessageContentViewer at the bottom.
|
||||||
*/
|
*/
|
||||||
@ServiceProvider(service = RelationshipsViewer.class)
|
public class MessagesPanel extends javax.swing.JPanel implements Lookup.Provider {
|
||||||
public final class MessagesViewer extends JPanel implements RelationshipsViewer {
|
|
||||||
|
|
||||||
private final Outline outline;
|
private final Outline outline;
|
||||||
private final ModifiableProxyLookup proxyLookup;
|
private final ModifiableProxyLookup proxyLookup;
|
||||||
private final PropertyChangeListener focusPropertyListener;
|
private final PropertyChangeListener focusPropertyListener;
|
||||||
private final MessagesChildNodeFactory nodeFactory;
|
|
||||||
|
|
||||||
@Messages({
|
|
||||||
"MessageViewer_tabTitle=Messages",
|
|
||||||
"MessageViewer_columnHeader_From=From",
|
|
||||||
"MessageViewer_columnHeader_To=To",
|
|
||||||
"MessageViewer_columnHeader_Date=Date",
|
|
||||||
"MessageViewer_columnHeader_Subject=Subject",
|
|
||||||
"MessageViewer_columnHeader_Attms=Attachments",
|
|
||||||
"MessageViewer_no_messages=<No messages found for selected account>"
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visualation for the messages of the currently selected accounts.
|
* Creates new form MessagesPanel
|
||||||
*/
|
*/
|
||||||
public MessagesViewer() {
|
public MessagesPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
splitPane.setResizeWeight(0.5);
|
|
||||||
|
|
||||||
outlineViewPanel.hideOutlineView(Bundle.MessageViewer_no_messages());
|
|
||||||
|
|
||||||
proxyLookup = new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
|
proxyLookup = new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
|
||||||
nodeFactory = new MessagesChildNodeFactory(null);
|
|
||||||
|
|
||||||
// See org.sleuthkit.autopsy.timeline.TimeLineTopComponent for a detailed
|
// See org.sleuthkit.autopsy.timeline.TimeLineTopComponent for a detailed
|
||||||
// explaination of focusPropertyListener
|
// explaination of focusPropertyListener
|
||||||
@ -83,10 +64,10 @@ public final class MessagesViewer extends JPanel implements RelationshipsViewer
|
|||||||
if (newFocusOwner == null) {
|
if (newFocusOwner == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isDescendingFrom(newFocusOwner, contentViewer)) {
|
if (isDescendingFrom(newFocusOwner, messageContentViewer)) {
|
||||||
//if the focus owner is within the MessageContentViewer (the attachments table)
|
//if the focus owner is within the MessageContentViewer (the attachments table)
|
||||||
proxyLookup.setNewLookups(createLookup(((MessageDataContent) contentViewer).getExplorerManager(), getActionMap()));
|
proxyLookup.setNewLookups(createLookup(((MessageDataContent) messageContentViewer).getExplorerManager(), getActionMap()));
|
||||||
} else if (isDescendingFrom(newFocusOwner, MessagesViewer.this)) {
|
} else if (isDescendingFrom(newFocusOwner, MessagesPanel.this)) {
|
||||||
//... or if it is within the Results table.
|
//... or if it is within the Results table.
|
||||||
proxyLookup.setNewLookups(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
|
proxyLookup.setNewLookups(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
|
||||||
|
|
||||||
@ -110,54 +91,24 @@ public final class MessagesViewer extends JPanel implements RelationshipsViewer
|
|||||||
final Node[] nodes = outlineViewPanel.getExplorerManager().getSelectedNodes();
|
final Node[] nodes = outlineViewPanel.getExplorerManager().getSelectedNodes();
|
||||||
|
|
||||||
if (nodes != null && nodes.length == 1) {
|
if (nodes != null && nodes.length == 1) {
|
||||||
contentViewer.setNode(nodes[0]);
|
messageContentViewer.setNode(nodes[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
contentViewer.setNode(null);
|
messageContentViewer.setNode(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
outlineViewPanel.getExplorerManager().setRootContext(
|
splitPane.setResizeWeight(0.5);
|
||||||
new TableFilterNode(
|
splitPane.setDividerLocation(0.5);
|
||||||
new DataResultFilterNode(
|
|
||||||
new AbstractNode(
|
|
||||||
Children.create(nodeFactory, true)),
|
|
||||||
outlineViewPanel.getExplorerManager()),
|
|
||||||
true));
|
|
||||||
|
|
||||||
// When a new set of nodes are added to the OutlineView the childrenAdded
|
|
||||||
// seems to be fired before the childrenRemoved.
|
|
||||||
outlineViewPanel.getExplorerManager().getRootContext().addNodeListener(new NodeAdapter() {
|
|
||||||
@Override
|
|
||||||
public void childrenAdded(NodeMemberEvent nme) {
|
|
||||||
updateOutlineViewPanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void childrenRemoved(NodeMemberEvent nme) {
|
|
||||||
updateOutlineViewPanel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
outlineViewPanel.setTableColumnsWidth(5,10,10,15,50,10);
|
outlineViewPanel.setTableColumnsWidth(5,10,10,15,50,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public MessagesPanel(ChildFactory<?> nodeFactory) {
|
||||||
public String getDisplayName() {
|
this();
|
||||||
return Bundle.MessageViewer_tabTitle();
|
setChildFactory(nodeFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JPanel getPanel() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSelectionInfo(SelectionInfo info) {
|
|
||||||
nodeFactory.refresh(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Lookup getLookup() {
|
public Lookup getLookup() {
|
||||||
return proxyLookup;
|
return proxyLookup;
|
||||||
@ -177,16 +128,16 @@ public final class MessagesViewer extends JPanel implements RelationshipsViewer
|
|||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
.removePropertyChangeListener("focusOwner", focusPropertyListener);
|
.removePropertyChangeListener("focusOwner", focusPropertyListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateOutlineViewPanel() {
|
|
||||||
int nodeCount = outlineViewPanel.getExplorerManager().getRootContext().getChildren().getNodesCount();
|
|
||||||
if(nodeCount == 0) {
|
|
||||||
outlineViewPanel.hideOutlineView(Bundle.MessageViewer_no_messages());
|
|
||||||
} else {
|
|
||||||
outlineViewPanel.showOutlineView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
final void setChildFactory(ChildFactory<?> nodeFactory) {
|
||||||
|
outlineViewPanel.getExplorerManager().setRootContext(
|
||||||
|
new TableFilterNode(
|
||||||
|
new DataResultFilterNode(
|
||||||
|
new AbstractNode(
|
||||||
|
Children.create(nodeFactory, true)),
|
||||||
|
outlineViewPanel.getExplorerManager()),true));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -195,31 +146,23 @@ public final class MessagesViewer extends JPanel implements RelationshipsViewer
|
|||||||
@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;
|
|
||||||
|
|
||||||
splitPane = new javax.swing.JSplitPane();
|
splitPane = new javax.swing.JSplitPane();
|
||||||
contentViewer = new MessageDataContent();
|
|
||||||
outlineViewPanel = new org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel();
|
outlineViewPanel = new org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel();
|
||||||
|
messageContentViewer = new MessageDataContent();
|
||||||
|
|
||||||
setLayout(new java.awt.GridBagLayout());
|
setLayout(new java.awt.BorderLayout());
|
||||||
|
|
||||||
splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||||
splitPane.setBottomComponent(contentViewer);
|
|
||||||
splitPane.setLeftComponent(outlineViewPanel);
|
splitPane.setLeftComponent(outlineViewPanel);
|
||||||
|
splitPane.setRightComponent(messageContentViewer);
|
||||||
|
|
||||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
add(splitPane, java.awt.BorderLayout.CENTER);
|
||||||
gridBagConstraints.gridx = 0;
|
|
||||||
gridBagConstraints.gridy = 0;
|
|
||||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
|
||||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
|
||||||
gridBagConstraints.weightx = 1.0;
|
|
||||||
gridBagConstraints.weighty = 1.0;
|
|
||||||
add(splitPane, gridBagConstraints);
|
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private org.sleuthkit.autopsy.contentviewers.MessageContentViewer contentViewer;
|
private org.sleuthkit.autopsy.contentviewers.MessageContentViewer messageContentViewer;
|
||||||
private org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel outlineViewPanel;
|
private org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel outlineViewPanel;
|
||||||
private javax.swing.JSplitPane splitPane;
|
private javax.swing.JSplitPane splitPane;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
@ -1,9 +1,6 @@
|
|||||||
<?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.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<Properties>
|
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
|
||||||
</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"/>
|
||||||
@ -23,12 +20,6 @@
|
|||||||
</Layout>
|
</Layout>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="org.openide.explorer.view.OutlineView" name="outlineView">
|
<Component class="org.openide.explorer.view.OutlineView" name="outlineView">
|
||||||
<Properties>
|
|
||||||
<Property name="horizontalScrollBarPolicy" type="int" value="32"/>
|
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
|
||||||
<Dimension value="[300, 400]"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<Constraints>
|
<Constraints>
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||||
<CardConstraints cardName="outlineCard"/>
|
<CardConstraints cardName="outlineCard"/>
|
||||||
|
@ -101,6 +101,15 @@ public class OutlineViewPanel extends javax.swing.JPanel implements ExplorerMana
|
|||||||
outlineView.setEnabled(enabled);
|
outlineView.setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the width of the columns of the OutlineView based on the passed in
|
||||||
|
* list of percentages. There should be on double value for each column
|
||||||
|
* in the OutlineView.
|
||||||
|
*
|
||||||
|
* @param percentages A series of double percentages values representing
|
||||||
|
* what percent of the total width of the table each
|
||||||
|
* column should have.
|
||||||
|
*/
|
||||||
public void setTableColumnsWidth(double... percentages) {
|
public void setTableColumnsWidth(double... percentages) {
|
||||||
JTable table = outlineView.getOutline();
|
JTable table = outlineView.getOutline();
|
||||||
double total = 0;
|
double total = 0;
|
||||||
@ -113,7 +122,7 @@ public class OutlineViewPanel extends javax.swing.JPanel implements ExplorerMana
|
|||||||
column.setPreferredWidth((int) (table.getPreferredSize().width * (percentages[i] / total)));
|
column.setPreferredWidth((int) (table.getPreferredSize().width * (percentages[i] / total)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -127,11 +136,7 @@ public class OutlineViewPanel extends javax.swing.JPanel implements ExplorerMana
|
|||||||
messagePanel = new javax.swing.JPanel();
|
messagePanel = new javax.swing.JPanel();
|
||||||
messageLabel = new javax.swing.JLabel();
|
messageLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
setEnabled(false);
|
|
||||||
setLayout(new java.awt.CardLayout(5, 5));
|
setLayout(new java.awt.CardLayout(5, 5));
|
||||||
|
|
||||||
outlineView.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
|
|
||||||
outlineView.setPreferredSize(new java.awt.Dimension(300, 400));
|
|
||||||
add(outlineView, "outlineCard");
|
add(outlineView, "outlineCard");
|
||||||
|
|
||||||
messagePanel.setLayout(new java.awt.BorderLayout());
|
messagePanel.setLayout(new java.awt.BorderLayout());
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
<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,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"/>
|
||||||
@ -22,7 +21,7 @@
|
|||||||
</Events>
|
</Events>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
<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="1" ipadX="0" ipadY="0" insetsTop="1" insetsLeft="1" insetsBottom="1" insetsRight="1" anchor="18" weightX="1.0" weightY="1.0"/>
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||||
</Constraint>
|
</Constraint>
|
||||||
</Constraints>
|
</Constraints>
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider
|
|||||||
|
|
||||||
private SelectionInfo currentSelection;
|
private SelectionInfo currentSelection;
|
||||||
|
|
||||||
private final MessagesViewer messagesViewer;
|
private final MessageViewer messagesViewer;
|
||||||
private final ContactsViewer contactsViewer;
|
private final ContactsViewer contactsViewer;
|
||||||
private final SummaryViewer summaryViewer;
|
private final SummaryViewer summaryViewer;
|
||||||
private final MediaViewer mediaViewer;
|
private final MediaViewer mediaViewer;
|
||||||
@ -42,24 +42,23 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider
|
|||||||
* Creates new form RelationshipBrowser
|
* Creates new form RelationshipBrowser
|
||||||
*/
|
*/
|
||||||
public RelationshipBrowser() {
|
public RelationshipBrowser() {
|
||||||
messagesViewer = new MessagesViewer();
|
initComponents();
|
||||||
|
messagesViewer = new MessageViewer();
|
||||||
contactsViewer = new ContactsViewer();
|
contactsViewer = new ContactsViewer();
|
||||||
summaryViewer = new SummaryViewer();
|
summaryViewer = new SummaryViewer();
|
||||||
mediaViewer = new MediaViewer();
|
mediaViewer = new MediaViewer();
|
||||||
|
|
||||||
proxyLookup = new ModifiableProxyLookup(messagesViewer.getLookup());
|
proxyLookup = new ModifiableProxyLookup(messagesViewer.getLookup());
|
||||||
|
|
||||||
initComponents();
|
|
||||||
|
|
||||||
tabPane.add(summaryViewer.getDisplayName(), summaryViewer);
|
tabPane.add(summaryViewer.getDisplayName(), summaryViewer);
|
||||||
tabPane.add(messagesViewer.getDisplayName(), messagesViewer);
|
tabPane.add(messagesViewer.getDisplayName(), messagesViewer);
|
||||||
tabPane.add(contactsViewer.getDisplayName(), contactsViewer);
|
tabPane.add(contactsViewer.getDisplayName(), contactsViewer);
|
||||||
tabPane.add(mediaViewer.getDisplayName(), mediaViewer);
|
tabPane.add(mediaViewer.getDisplayName(), mediaViewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of currentSelection and passes the SelectionInfo onto the
|
* Sets the value of currentSelection and passes the SelectionInfo onto the
|
||||||
* currently selected or visible tab.
|
* currently selected\visible tab.
|
||||||
*
|
*
|
||||||
* @param info Currently selected account nodes
|
* @param info Currently selected account nodes
|
||||||
*/
|
*/
|
||||||
@ -94,7 +93,6 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider
|
|||||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
gridBagConstraints.weightx = 1.0;
|
gridBagConstraints.weightx = 1.0;
|
||||||
gridBagConstraints.weighty = 1.0;
|
gridBagConstraints.weighty = 1.0;
|
||||||
gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
|
|
||||||
add(tabPane, gridBagConstraints);
|
add(tabPane, gridBagConstraints);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications.relationships;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.ChildFactory;
|
||||||
|
import org.openide.nodes.Children;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.nodes.Sheet;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ChildFactory that creates createKeys and nodes from a given selectionInfo for
|
||||||
|
* only emails, call logs and messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
final class ThreadChildNodeFactory extends ChildFactory<BlackboardArtifact> {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(ThreadChildNodeFactory.class.getName());
|
||||||
|
|
||||||
|
private SelectionInfo selectionInfo;
|
||||||
|
|
||||||
|
private final Action preferredAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new ThreadChildNodeFactory from the currently selectionInfo
|
||||||
|
*
|
||||||
|
* @param preferredAction SelectionInfo object for the currently selected
|
||||||
|
* accounts
|
||||||
|
*/
|
||||||
|
|
||||||
|
ThreadChildNodeFactory(Action preferredAction) {
|
||||||
|
this.preferredAction = preferredAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current instance of selectionInfo and calls the refresh method.
|
||||||
|
*
|
||||||
|
* @param selectionInfo New instance of the currently selected accounts
|
||||||
|
*/
|
||||||
|
public void refresh(SelectionInfo selectionInfo) {
|
||||||
|
this.selectionInfo = selectionInfo;
|
||||||
|
refresh(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a list of Keys (BlackboardArtifact) for only messages for the
|
||||||
|
* currently selected accounts.
|
||||||
|
*
|
||||||
|
* @param list List of BlackboardArtifact to populate
|
||||||
|
*
|
||||||
|
* @return True on success
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean createKeys(List<BlackboardArtifact> list) {
|
||||||
|
CommunicationsManager communicationManager;
|
||||||
|
try {
|
||||||
|
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get communications manager from case.", ex); //NON-NLS
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selectionInfo == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Set<Content> relationshipSources;
|
||||||
|
|
||||||
|
try {
|
||||||
|
relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
|
||||||
|
|
||||||
|
createRootMessageKeys(list, relationshipSources) ;
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds only BlackboardArtifact objects to the list where are the earliest
|
||||||
|
* message in a message thread (based on threadID). If there are "unthreaded"
|
||||||
|
* messages (messages that do not have a threadID) one representitive artifact
|
||||||
|
* will be added to the list and dealt with a node creation time.
|
||||||
|
*
|
||||||
|
* @param list List to populate with BlackboardArtifact keys
|
||||||
|
* @param relationshipSources Set of Content objects
|
||||||
|
* @return True on success
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private boolean createRootMessageKeys(List<BlackboardArtifact> list, Set<Content> relationshipSources) throws TskCoreException{
|
||||||
|
Map<String, BlackboardArtifact> rootMessageMap = new HashMap<>();
|
||||||
|
for(Content content: relationshipSources) {
|
||||||
|
if(!(content instanceof BlackboardArtifact)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlackboardArtifact bba = (BlackboardArtifact) content;
|
||||||
|
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
|
||||||
|
|
||||||
|
if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG
|
||||||
|
|| fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG
|
||||||
|
|| fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) {
|
||||||
|
|
||||||
|
// We want all artifacts that do not have "threadIDs" to appear as one thread in the UI
|
||||||
|
// To achive this assign any artifact that does not have a threadID
|
||||||
|
// the "UNTHREADED_ID"
|
||||||
|
String threadID = MessageNode.UNTHREADED_ID;
|
||||||
|
BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
|
||||||
|
|
||||||
|
if(attribute != null) {
|
||||||
|
threadID = attribute.getValueString();
|
||||||
|
}
|
||||||
|
|
||||||
|
BlackboardArtifact tableArtifact = rootMessageMap.get(threadID);
|
||||||
|
if(tableArtifact == null) {
|
||||||
|
rootMessageMap.put(threadID, bba);
|
||||||
|
} else {
|
||||||
|
// Get the date of the message
|
||||||
|
BlackboardAttribute tableAttribute = tableArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
|
||||||
|
attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
|
||||||
|
|
||||||
|
// put the earliest message into the table
|
||||||
|
if(tableAttribute != null
|
||||||
|
&& attribute != null
|
||||||
|
&& tableAttribute.getValueLong() > attribute.getValueLong()) {
|
||||||
|
rootMessageMap.put(threadID, bba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(BlackboardArtifact bba: rootMessageMap.values()) {
|
||||||
|
list.add(bba);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Node createNodeForKey(BlackboardArtifact bba) {
|
||||||
|
BlackboardAttribute attribute = null;
|
||||||
|
try {
|
||||||
|
attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("Unable to get threadID for artifact: %s", bba.getName()), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribute != null) {
|
||||||
|
return new ThreadNode(bba, attribute.getValueString(), preferredAction);
|
||||||
|
} else {
|
||||||
|
// Only one of these should occur.
|
||||||
|
return new UnthreadedNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An this node represents the "unthreaded" thread.
|
||||||
|
*/
|
||||||
|
final class UnthreadedNode extends AbstractNode {
|
||||||
|
/**
|
||||||
|
* Construct an instance of UnthreadNode.
|
||||||
|
*/
|
||||||
|
UnthreadedNode() {
|
||||||
|
super(Children.LEAF);
|
||||||
|
setDisplayName("Unthreaded");
|
||||||
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/unthreaded.png" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Sheet createSheet() {
|
||||||
|
Sheet sheet = super.createSheet();
|
||||||
|
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
|
||||||
|
if (sheetSet == null) {
|
||||||
|
sheetSet = Sheet.createPropertiesSet();
|
||||||
|
sheet.put(sheetSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give this node a threadID of "UNTHEADED_ID"
|
||||||
|
sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",MessageNode.UNTHREADED_ID));
|
||||||
|
|
||||||
|
return sheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadNode.java
Executable file
60
Core/src/org/sleuthkit/autopsy/communications/relationships/ThreadNode.java
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications.relationships;
|
||||||
|
|
||||||
|
import javax.swing.Action;
|
||||||
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.Children;
|
||||||
|
import org.openide.nodes.Sheet;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An AbstractNode subclass which wraps a MessagNode object. Doing this allows
|
||||||
|
* for the reuse of the createSheet and other function from MessageNode, but
|
||||||
|
* also some customizing of how a ThreadNode is shown.
|
||||||
|
*/
|
||||||
|
final class ThreadNode extends AbstractNode{
|
||||||
|
|
||||||
|
final private MessageNode messageNode;
|
||||||
|
|
||||||
|
ThreadNode(BlackboardArtifact artifact, String threadID, Action preferredAction) {
|
||||||
|
super(Children.LEAF);
|
||||||
|
messageNode = new MessageNode(artifact, threadID, preferredAction);
|
||||||
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/threaded.png" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Sheet createSheet() {
|
||||||
|
return messageNode.createSheet();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getThreadID() {
|
||||||
|
return messageNode.getThreadID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Action getPreferredAction() {
|
||||||
|
return messageNode.getPreferredAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return messageNode.getDisplayName();
|
||||||
|
}
|
||||||
|
}
|
@ -302,6 +302,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
if (rootNode != null) {
|
if (rootNode != null) {
|
||||||
|
this.rootNode = rootNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if we have previously created a paging support
|
* Check to see if we have previously created a paging support
|
||||||
* class for this node.
|
* class for this node.
|
||||||
@ -364,8 +366,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
* case database round trips.
|
* case database round trips.
|
||||||
*/
|
*/
|
||||||
if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
|
if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
|
||||||
this.rootNode = rootNode;
|
|
||||||
|
|
||||||
this.getExplorerManager().setRootContext(this.rootNode);
|
this.getExplorerManager().setRootContext(this.rootNode);
|
||||||
setupTable();
|
setupTable();
|
||||||
} else {
|
} else {
|
||||||
|
@ -490,6 +490,12 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractAction visit(BlackboardArtifactNode ban) {
|
public AbstractAction visit(BlackboardArtifactNode ban) {
|
||||||
|
|
||||||
|
Action preferredAction = ban.getPreferredAction();
|
||||||
|
if(preferredAction instanceof AbstractAction) {
|
||||||
|
return (AbstractAction) preferredAction;
|
||||||
|
}
|
||||||
|
|
||||||
BlackboardArtifact artifact = ban.getArtifact();
|
BlackboardArtifact artifact = ban.getArtifact();
|
||||||
try {
|
try {
|
||||||
if ((artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID())
|
if ((artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID())
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014-2018 Basis Technology Corp.
|
* Copyright 2014-2019 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -286,7 +286,7 @@ public final class DataSourceIngestJob {
|
|||||||
this.addIngestModules(fileIngestModuleTemplates, IngestModuleType.FILE_LEVEL, skCase);
|
this.addIngestModules(fileIngestModuleTemplates, IngestModuleType.FILE_LEVEL, skCase);
|
||||||
this.addIngestModules(secondStageDataSourceModuleTemplates, IngestModuleType.DATA_SOURCE_LEVEL, skCase);
|
this.addIngestModules(secondStageDataSourceModuleTemplates, IngestModuleType.DATA_SOURCE_LEVEL, skCase);
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to add ingest modules to database.", ex);
|
logErrorMessage(Level.WARNING, "Failed to add ingest modules listing to case database", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,13 +421,13 @@ public final class DataSourceIngestJob {
|
|||||||
try {
|
try {
|
||||||
this.ingestJob = Case.getCurrentCaseThrows().getSleuthkitCase().addIngestJob(dataSource, NetworkUtils.getLocalHostName(), ingestModules, new Date(this.createTime), new Date(0), IngestJobStatusType.STARTED, "");
|
this.ingestJob = Case.getCurrentCaseThrows().getSleuthkitCase().addIngestJob(dataSource, NetworkUtils.getLocalHostName(), ingestModules, new Date(this.createTime), new Date(0), IngestJobStatusType.STARTED, "");
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to add ingest job to database.", ex);
|
logErrorMessage(Level.WARNING, "Failed to add ingest job info to case database", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
if (this.hasFirstStageDataSourceIngestPipeline() || this.hasFileIngestPipeline()) {
|
if (this.hasFirstStageDataSourceIngestPipeline() || this.hasFileIngestPipeline()) {
|
||||||
logger.log(Level.INFO, "Starting first stage analysis for {0} (jobId={1})", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Starting first stage analysis"); //NON-NLS
|
||||||
this.startFirstStage();
|
this.startFirstStage();
|
||||||
} else if (this.hasSecondStageDataSourceIngestPipeline()) {
|
} else if (this.hasSecondStageDataSourceIngestPipeline()) {
|
||||||
logger.log(Level.INFO, "Starting second stage analysis for {0} (jobId={1}), no first stage configured", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Starting second stage analysis"); //NON-NLS
|
||||||
this.startSecondStage();
|
this.startSecondStage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -521,13 +521,13 @@ public final class DataSourceIngestJob {
|
|||||||
* Schedule the first stage tasks.
|
* Schedule the first stage tasks.
|
||||||
*/
|
*/
|
||||||
if (this.hasFirstStageDataSourceIngestPipeline() && this.hasFileIngestPipeline()) {
|
if (this.hasFirstStageDataSourceIngestPipeline() && this.hasFileIngestPipeline()) {
|
||||||
logger.log(Level.INFO, "Scheduling first stage data source and file level analysis tasks for {0} (jobId={1})", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Scheduling first stage data source and file level analysis tasks"); //NON-NLS
|
||||||
DataSourceIngestJob.taskScheduler.scheduleIngestTasks(this);
|
DataSourceIngestJob.taskScheduler.scheduleIngestTasks(this);
|
||||||
} else if (this.hasFirstStageDataSourceIngestPipeline()) {
|
} else if (this.hasFirstStageDataSourceIngestPipeline()) {
|
||||||
logger.log(Level.INFO, "Scheduling first stage data source level analysis tasks for {0} (jobId={1}), no file level analysis configured", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Scheduling first stage data source level analysis tasks"); //NON-NLS
|
||||||
DataSourceIngestJob.taskScheduler.scheduleDataSourceIngestTask(this);
|
DataSourceIngestJob.taskScheduler.scheduleDataSourceIngestTask(this);
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.INFO, "Scheduling file level analysis tasks for {0} (jobId={1}), no first stage data source level analysis configured", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Scheduling file level analysis tasks, no first stage data source level analysis configured"); //NON-NLS
|
||||||
DataSourceIngestJob.taskScheduler.scheduleFileIngestTasks(this, this.files);
|
DataSourceIngestJob.taskScheduler.scheduleFileIngestTasks(this, this.files);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -546,7 +546,7 @@ public final class DataSourceIngestJob {
|
|||||||
* Starts the second stage of this ingest job.
|
* Starts the second stage of this ingest job.
|
||||||
*/
|
*/
|
||||||
private void startSecondStage() {
|
private void startSecondStage() {
|
||||||
logger.log(Level.INFO, "Starting second stage analysis for {0} (jobId={1})", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Starting second stage analysis"); //NON-NLS
|
||||||
this.stage = DataSourceIngestJob.Stages.SECOND;
|
this.stage = DataSourceIngestJob.Stages.SECOND;
|
||||||
if (this.doUI) {
|
if (this.doUI) {
|
||||||
this.startDataSourceIngestProgressBar();
|
this.startDataSourceIngestProgressBar();
|
||||||
@ -554,7 +554,7 @@ public final class DataSourceIngestJob {
|
|||||||
synchronized (this.dataSourceIngestPipelineLock) {
|
synchronized (this.dataSourceIngestPipelineLock) {
|
||||||
this.currentDataSourceIngestPipeline = this.secondStageDataSourceIngestPipeline;
|
this.currentDataSourceIngestPipeline = this.secondStageDataSourceIngestPipeline;
|
||||||
}
|
}
|
||||||
logger.log(Level.INFO, "Scheduling second stage data source level analysis tasks for {0} (jobId={1})", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Scheduling second stage data source level analysis tasks"); //NON-NLS
|
||||||
DataSourceIngestJob.taskScheduler.scheduleDataSourceIngestTask(this);
|
DataSourceIngestJob.taskScheduler.scheduleDataSourceIngestTask(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,7 +643,7 @@ public final class DataSourceIngestJob {
|
|||||||
* job and starts the second stage, if appropriate.
|
* job and starts the second stage, if appropriate.
|
||||||
*/
|
*/
|
||||||
private void finishFirstStage() {
|
private void finishFirstStage() {
|
||||||
logger.log(Level.INFO, "Finished first stage analysis for {0} (jobId={1})", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Finished first stage analysis"); //NON-NLS
|
||||||
|
|
||||||
// Shut down the file ingest pipelines. Note that no shut down is
|
// Shut down the file ingest pipelines. Note that no shut down is
|
||||||
// required for the data source ingest pipeline because data source
|
// required for the data source ingest pipeline because data source
|
||||||
@ -693,7 +693,7 @@ public final class DataSourceIngestJob {
|
|||||||
* Shuts down the ingest pipelines and progress bars for this job.
|
* Shuts down the ingest pipelines and progress bars for this job.
|
||||||
*/
|
*/
|
||||||
private void finish() {
|
private void finish() {
|
||||||
logger.log(Level.INFO, "Finished analysis for {0} (jobId={1})", new Object[]{dataSource.getName(), this.id}); //NON-NLS
|
logInfoMessage("Finished analysis"); //NON-NLS
|
||||||
this.stage = DataSourceIngestJob.Stages.FINALIZATION;
|
this.stage = DataSourceIngestJob.Stages.FINALIZATION;
|
||||||
|
|
||||||
if (this.doUI) {
|
if (this.doUI) {
|
||||||
@ -711,19 +711,19 @@ public final class DataSourceIngestJob {
|
|||||||
try {
|
try {
|
||||||
ingestJob.setIngestJobStatus(IngestJobStatusType.CANCELLED);
|
ingestJob.setIngestJobStatus(IngestJobStatusType.CANCELLED);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to set ingest status for ingest job in database.", ex);
|
logErrorMessage(Level.WARNING, "Failed to update ingest job status in case database", ex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
ingestJob.setIngestJobStatus(IngestJobStatusType.COMPLETED);
|
ingestJob.setIngestJobStatus(IngestJobStatusType.COMPLETED);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to set ingest status for ingest job in database.", ex);
|
logErrorMessage(Level.WARNING, "Failed to update ingest job status in case database", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.ingestJob.setEndDateTime(new Date());
|
this.ingestJob.setEndDateTime(new Date());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to set end date for ingest job in database.", ex);
|
logErrorMessage(Level.WARNING, "Failed to set job end date in case database", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.parentJob.dataSourceJobFinished(this);
|
this.parentJob.dataSourceJobFinished(this);
|
||||||
@ -842,7 +842,7 @@ public final class DataSourceIngestJob {
|
|||||||
if (DataSourceIngestJob.Stages.FIRST == this.stage) {
|
if (DataSourceIngestJob.Stages.FIRST == this.stage) {
|
||||||
DataSourceIngestJob.taskScheduler.fastTrackFileIngestTasks(this, files);
|
DataSourceIngestJob.taskScheduler.fastTrackFileIngestTasks(this, files);
|
||||||
} else {
|
} else {
|
||||||
DataSourceIngestJob.logger.log(Level.SEVERE, "Adding files during second stage not supported"); //NON-NLS
|
logErrorMessage(Level.SEVERE, "Adding files to job during second stage analysis not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1066,6 +1066,39 @@ public final class DataSourceIngestJob {
|
|||||||
return this.cancellationReason;
|
return this.cancellationReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an info message to the application log that includes the data
|
||||||
|
* source name, data source object id, and the job id.
|
||||||
|
*
|
||||||
|
* @param message The message.
|
||||||
|
*/
|
||||||
|
private void logInfoMessage(String message) {
|
||||||
|
logger.log(Level.INFO, String.format("%s (data source = %s, objId = %d, jobId = %d)", message, dataSource.getName(), dataSource.getId(), id)); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an error message to the application log that includes the data
|
||||||
|
* source name, data source object id, and the job id.
|
||||||
|
*
|
||||||
|
* @param level The logging level for the message.
|
||||||
|
* @param message The message.
|
||||||
|
* @param throwable The throwable associated with the error.
|
||||||
|
*/
|
||||||
|
private void logErrorMessage(Level level, String message, Throwable throwable) {
|
||||||
|
logger.log(level, String.format("%s (data source = %s, objId = %d, jobId = %d)", message, dataSource.getName(), dataSource.getId(), id), throwable); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an error message to the application log that includes the data
|
||||||
|
* source name, data source object id, and the job id.
|
||||||
|
*
|
||||||
|
* @param level The logging level for the message.
|
||||||
|
* @param message The message.
|
||||||
|
*/
|
||||||
|
private void logErrorMessage(Level level, String message) {
|
||||||
|
logger.log(level, String.format("%s (data source = %s, objId = %d, jobId = %d)", message, dataSource.getName(), dataSource.getId(), id)); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write ingest module errors to the log.
|
* Write ingest module errors to the log.
|
||||||
*
|
*
|
||||||
@ -1073,7 +1106,7 @@ public final class DataSourceIngestJob {
|
|||||||
*/
|
*/
|
||||||
private void logIngestModuleErrors(List<IngestModuleError> errors) {
|
private void logIngestModuleErrors(List<IngestModuleError> errors) {
|
||||||
for (IngestModuleError error : errors) {
|
for (IngestModuleError error : errors) {
|
||||||
DataSourceIngestJob.logger.log(Level.SEVERE, String.format("%s experienced an error analyzing %s (jobId=%d)", error.getModuleDisplayName(), dataSource.getName(), this.id), error.getThrowable()); //NON-NLS
|
logErrorMessage(Level.SEVERE, String.format("%s experienced an error during analysis", error.getModuleDisplayName()), error.getThrowable()); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2012-2018 Basis Technology Corp.
|
* Copyright 2012-2019 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -403,10 +403,10 @@ public class IngestManager implements IngestProgressSnapshotProvider {
|
|||||||
synchronized (ingestJobsById) {
|
synchronized (ingestJobsById) {
|
||||||
ingestJobsById.put(job.getId(), job);
|
ingestJobsById.put(job.getId(), job);
|
||||||
}
|
}
|
||||||
|
IngestManager.logger.log(Level.INFO, "Starting ingest job {0}", job.getId()); //NON-NLS
|
||||||
errors = job.start();
|
errors = job.start();
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
this.fireIngestJobStarted(job.getId());
|
this.fireIngestJobStarted(job.getId());
|
||||||
IngestManager.logger.log(Level.INFO, "Ingest job {0} started", job.getId()); //NON-NLS
|
|
||||||
} else {
|
} else {
|
||||||
synchronized (ingestJobsById) {
|
synchronized (ingestJobsById) {
|
||||||
this.ingestJobsById.remove(job.getId());
|
this.ingestJobsById.remove(job.getId());
|
||||||
|
@ -41,6 +41,9 @@ public final class OpenCvLoader {
|
|||||||
* Return whether or not the OpenCV library has been loaded.
|
* Return whether or not the OpenCV library has been loaded.
|
||||||
*
|
*
|
||||||
* @return - true if the opencv library is loaded or false if it is not
|
* @return - true if the opencv library is loaded or false if it is not
|
||||||
|
* @throws UnsatisfiedLinkError - A COPY of the exception that prevented OpenCV from loading.
|
||||||
|
* Note that the stack trace in the exception can be confusing because it refers to a
|
||||||
|
* past invocation.
|
||||||
*/
|
*/
|
||||||
public static boolean isOpenCvLoaded() throws UnsatisfiedLinkError {
|
public static boolean isOpenCvLoaded() throws UnsatisfiedLinkError {
|
||||||
if (!OPEN_CV_LOADED) {
|
if (!OPEN_CV_LOADED) {
|
||||||
|
@ -99,13 +99,14 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer):
|
|||||||
resultSet = None
|
resultSet = None
|
||||||
try:
|
try:
|
||||||
resultSet = statement.executeQuery(
|
resultSet = statement.executeQuery(
|
||||||
"SELECT address, date, read, type, subject, body FROM sms;")
|
"SELECT address, date, read, type, subject, body, thread_id FROM sms;")
|
||||||
while resultSet.next():
|
while resultSet.next():
|
||||||
address = resultSet.getString("address") # may be phone number, or other addresses
|
address = resultSet.getString("address") # may be phone number, or other addresses
|
||||||
date = Long.valueOf(resultSet.getString("date")) / 1000
|
date = Long.valueOf(resultSet.getString("date")) / 1000
|
||||||
read = resultSet.getInt("read") # may be unread = 0, read = 1
|
read = resultSet.getInt("read") # may be unread = 0, read = 1
|
||||||
subject = resultSet.getString("subject") # message subject
|
subject = resultSet.getString("subject") # message subject
|
||||||
body = resultSet.getString("body") # message body
|
body = resultSet.getString("body") # message body
|
||||||
|
thread_id = "{0}_{1}".format(abstractFile.getId(), resultSet.getInt("thread_id"))
|
||||||
attributes = ArrayList()
|
attributes = ArrayList()
|
||||||
artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE); #create Message artifact and then add attributes from result set.
|
artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE); #create Message artifact and then add attributes from result set.
|
||||||
if resultSet.getString("type") == "1":
|
if resultSet.getString("type") == "1":
|
||||||
@ -119,6 +120,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer):
|
|||||||
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT, general.MODULE_NAME, subject))
|
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT, general.MODULE_NAME, subject))
|
||||||
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, general.MODULE_NAME, body))
|
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, general.MODULE_NAME, body))
|
||||||
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "SMS Message"))
|
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "SMS Message"))
|
||||||
|
attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID, general.MODULE_NAME, thread_id))
|
||||||
|
|
||||||
artifact.addAttributes(attributes)
|
artifact.addAttributes(attributes)
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<project name="TSK_VERSION">
|
<project name="TSK_VERSION">
|
||||||
<property name="TSK_VERSION" value="4.6.6"/>
|
<property name="TSK_VERSION" value="4.6.7"/>
|
||||||
</project>
|
</project>
|
||||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy User Documentation"
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 4.11.0
|
PROJECT_NUMBER = 4.12.0
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
@ -1025,7 +1025,7 @@ GENERATE_HTML = YES
|
|||||||
# The default directory is: html.
|
# The default directory is: html.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_OUTPUT = 4.11.0
|
HTML_OUTPUT = 4.12.0
|
||||||
|
|
||||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||||
# generated HTML page (for example: .htm, .php, .asp).
|
# generated HTML page (for example: .htm, .php, .asp).
|
||||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy"
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 4.11.0
|
PROJECT_NUMBER = 4.12.0
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears a the top of each page and should give viewer a
|
# for a project that appears a the top of each page and should give viewer a
|
||||||
@ -1063,7 +1063,7 @@ GENERATE_HTML = YES
|
|||||||
# The default directory is: html.
|
# The default directory is: html.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_OUTPUT = api-docs/4.11.0/
|
HTML_OUTPUT = api-docs/4.12.0/
|
||||||
|
|
||||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||||
# generated HTML page (for example: .htm, .php, .asp).
|
# generated HTML page (for example: .htm, .php, .asp).
|
||||||
|
@ -4,10 +4,10 @@ app.title=Autopsy
|
|||||||
### lowercase version of above
|
### lowercase version of above
|
||||||
app.name=${branding.token}
|
app.name=${branding.token}
|
||||||
### if left unset, version will default to today's date
|
### if left unset, version will default to today's date
|
||||||
app.version=4.11.0
|
app.version=4.12.0
|
||||||
### build.type must be one of: DEVELOPMENT, RELEASE
|
### build.type must be one of: DEVELOPMENT, RELEASE
|
||||||
#build.type=RELEASE
|
build.type=RELEASE
|
||||||
build.type=DEVELOPMENT
|
#build.type=DEVELOPMENT
|
||||||
|
|
||||||
project.org.netbeans.progress=org-netbeans-api-progress
|
project.org.netbeans.progress=org-netbeans-api-progress
|
||||||
project.org.sleuthkit.autopsy.experimental=Experimental
|
project.org.sleuthkit.autopsy.experimental=Experimental
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
# NOTE: update_sleuthkit_version.pl updates this value and relies
|
# NOTE: update_sleuthkit_version.pl updates this value and relies
|
||||||
# on it keeping the same name and whitespace. Don't change it.
|
# on it keeping the same name and whitespace. Don't change it.
|
||||||
TSK_VERSION=4.6.6
|
TSK_VERSION=4.6.7
|
||||||
|
|
||||||
|
|
||||||
# In the beginning...
|
# In the beginning...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user