mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-03 15:59:52 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into 6345-64bitCarverOneInstaller
This commit is contained in:
@@ -107,7 +107,7 @@ import org.sleuthkit.autopsy.coreutils.Version;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||
import org.sleuthkit.autopsy.filequery.OpenFileDiscoveryAction;
|
||||
import org.sleuthkit.autopsy.discovery.OpenDiscoveryAction;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
@@ -1124,7 +1124,7 @@ public class Case {
|
||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenFileDiscoveryAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(true);
|
||||
|
||||
/*
|
||||
* Add the case to the recent cases tracker that supplies a list
|
||||
@@ -1179,7 +1179,7 @@ public class Case {
|
||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenFileDiscoveryAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(false);
|
||||
|
||||
/*
|
||||
* Clear the notifications in the notfier component in the lower
|
||||
|
||||
@@ -310,6 +310,18 @@ public class Persona {
|
||||
PersonaAccount.removePersonaAccount(account.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the confidence / justification of the given PersonaAccount
|
||||
*
|
||||
* @param account account to modify
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in querying the
|
||||
* Personas table.
|
||||
*/
|
||||
public void modifyAccount(PersonaAccount account, Confidence confidence, String justification) throws CentralRepoException {
|
||||
PersonaAccount.modifyPersonaAccount(account.getId(), confidence, justification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this persona as deleted
|
||||
*/
|
||||
@@ -459,7 +471,7 @@ public class Persona {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given alias
|
||||
* Removes the given alias.
|
||||
*
|
||||
* @param alias alias to remove
|
||||
*
|
||||
@@ -469,6 +481,18 @@ public class Persona {
|
||||
public void removeAlias(PersonaAlias alias) throws CentralRepoException {
|
||||
PersonaAlias.removePersonaAlias(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given alias.
|
||||
*
|
||||
* @param alias alias to modify
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in querying the
|
||||
* Personas table.
|
||||
*/
|
||||
public void modifyAlias(PersonaAlias key, Confidence confidence, String justification) throws CentralRepoException {
|
||||
PersonaAlias.modifyPersonaAlias(key, confidence, justification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all aliases for the persona.
|
||||
@@ -497,7 +521,7 @@ public class Persona {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given metadata from this persona
|
||||
* Removes the given metadata from this persona.
|
||||
*
|
||||
* @param metadata metadata to remove
|
||||
*
|
||||
@@ -507,6 +531,18 @@ public class Persona {
|
||||
public void removeMetadata(PersonaMetadata metadata) throws CentralRepoException {
|
||||
PersonaMetadata.removePersonaMetadata(metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given metadata.
|
||||
*
|
||||
* @param metadata metadata to modify
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in querying the
|
||||
* Personas table.
|
||||
*/
|
||||
public void modifyMetadata(PersonaMetadata key, Confidence confidence, String justification) throws CentralRepoException {
|
||||
PersonaMetadata.modifyPersonaMetadata(key, confidence, justification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all metadata for the persona.
|
||||
|
||||
@@ -363,6 +363,25 @@ public class PersonaAccount {
|
||||
String deleteClause = " DELETE FROM persona_accounts WHERE id = " + id;
|
||||
cr.executeDeleteSQL(deleteClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the PersonaAccount row by the given id
|
||||
*
|
||||
* @param id row id for the account to be removed
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in removing the
|
||||
* account.
|
||||
*/
|
||||
static void modifyPersonaAccount(long id, Persona.Confidence confidence, String justification) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if (cr == null) {
|
||||
throw new CentralRepoException("Failed to modify persona account, Central Repo is not enabled");
|
||||
}
|
||||
|
||||
String updateClause = "UPDATE persona_accounts SET confidence_id = " + confidence.getLevelId() + ", justification = \"" + justification + "\" WHERE id = " + id;
|
||||
cr.executeUpdateSQL(updateClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to process a query that gets all accounts belonging to a
|
||||
|
||||
@@ -38,7 +38,7 @@ public class PersonaAlias {
|
||||
"SELECT pa.id, pa.persona_id, pa.alias, pa.justification, pa.confidence_id, pa.date_added, pa.examiner_id, e.login_name, e.display_name "
|
||||
+ "FROM persona_alias as pa "
|
||||
+ "INNER JOIN examiners as e ON e.id = pa.examiner_id ";
|
||||
|
||||
|
||||
private final long id;
|
||||
private final long personaId;
|
||||
private final String alias;
|
||||
@@ -144,6 +144,25 @@ public class PersonaAlias {
|
||||
CentralRepository.getInstance().executeDeleteSQL(deleteClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a PesronaAlias.
|
||||
*
|
||||
* @param alias Alias to modify.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in modifying the alias.
|
||||
*/
|
||||
static void modifyPersonaAlias(PersonaAlias alias, Persona.Confidence confidence, String justification) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if (cr == null) {
|
||||
throw new CentralRepoException("Failed to modify persona alias, Central Repo is not enabled");
|
||||
}
|
||||
|
||||
String updateClause = "UPDATE persona_alias SET confidence_id = " + confidence.getLevelId() + ", justification = \"" + justification + "\" WHERE id = " + alias.id;
|
||||
cr.executeUpdateSQL(updateClause);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback to process a Persona aliases query.
|
||||
*/
|
||||
|
||||
@@ -155,6 +155,24 @@ public class PersonaMetadata {
|
||||
CentralRepository.getInstance().executeDeleteSQL(deleteClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given PersonaMetadata
|
||||
*
|
||||
* @param metadata Metadata to modify.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in modifying the metadata.
|
||||
*/
|
||||
static void modifyPersonaMetadata(PersonaMetadata metadata, Persona.Confidence confidence, String justification) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if (cr == null) {
|
||||
throw new CentralRepoException("Failed to modify persona metadata, Central Repo is not enabled");
|
||||
}
|
||||
|
||||
String updateClause = "UPDATE persona_metadata SET confidence_id = " + confidence.getLevelId() + ", justification = \"" + justification + "\" WHERE id = " + metadata.id;
|
||||
cr.executeUpdateSQL(updateClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to process a Persona metadata query.
|
||||
*/
|
||||
|
||||
@@ -70,3 +70,6 @@ PersonaMetadataDialog.nameTextField.text=
|
||||
PersonaMetadataDialog.nameLbl.text=Name:
|
||||
PersonaMetadataDialog.okBtn.text=OK
|
||||
PersonaMetadataDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsPanel.editAccountBtn.text=Edit
|
||||
PersonaDetailsPanel.editMetadataBtn.text=Edit
|
||||
PersonaDetailsPanel.editAliasBtn.text=Edit
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
AddMetadataDialog.title.text=Add Metadata
|
||||
AddMetadataDialog_dup_msg=A metadata entry with this name has already been added to this persona
|
||||
AddMetadataDialog_dup_msg=A metadata entry with this name has already been added to this persona.
|
||||
AddMetadataDialog_dup_Title=Metadata add failure
|
||||
AddMetadataDialog_empty_name_msg=A metadata entry cannot have an empty name or value.
|
||||
AddMetadataDialog_empty_name_Title=Missing field(s)
|
||||
CTL_OpenPersonaManager=Persona Manager
|
||||
CTL_PersonaManagerTopComponentAction=Persona Manager
|
||||
CTL_PersonaDetailsTopComponent=Persona Details
|
||||
@@ -17,22 +19,24 @@ PersonaAccountDialog_search_empty_Title=Account not found
|
||||
PersonaAccountDialog_search_failure_msg=Central Repository account search failed.
|
||||
PersonaAccountDialog_search_failure_Title=Account add failure
|
||||
PersonaAliasDialog.title.text=Add Alias
|
||||
PersonaAliasDialog_dup_msg=This alias has already been added to this persona
|
||||
PersonaAliasDialog_dup_msg=This alias has already been added to this persona.
|
||||
PersonaAliasDialog_dup_Title=Alias add failure
|
||||
PersonaAliasDialog_empty_msg=An alias cannot be empty.
|
||||
PersonaAliasDialog_empty_Title=Empty alias
|
||||
PersonaDetailsDialogCreateTitle=Create Persona
|
||||
PersonaDetailsDialogEditTitle=Edit Persona
|
||||
PersonaDetailsDialogViewTitle=View Persona
|
||||
PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository
|
||||
PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository.
|
||||
PersonaDetailsPanel_CentralRepoErr_Title=Central Repository failure
|
||||
PersonaDetailsPanel_empty_justification_msg=The justification field cannot be empty
|
||||
PersonaDetailsPanel_empty_justification_Title=Empty justification
|
||||
PersonaDetailsPanel_EmptyComment_msg=Persona comment cannot be empty
|
||||
PersonaDetailsPanel_EmptyComment_msg=Persona comment cannot be empty.
|
||||
PersonaDetailsPanel_EmptyComment_Title=Empty persona comment
|
||||
PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty
|
||||
PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty.
|
||||
PersonaDetailsPanel_EmptyName_Title=Empty persona name
|
||||
PersonaDetailsPanel_load_exception_msg=Failed to load persona
|
||||
PersonaDetailsPanel_load_exception_msg=Failed to load persona.
|
||||
PersonaDetailsPanel_load_exception_Title=Initialization failure
|
||||
PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account
|
||||
PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account.
|
||||
PersonaDetailsPanel_NotEnoughAccounts_Title=Missing account
|
||||
PersonaManagerTopComponent.createBtn.text=New Persona
|
||||
PersonaManagerTopComponent.searchBtn.text=Search
|
||||
@@ -103,6 +107,9 @@ PersonaMetadataDialog.nameTextField.text=
|
||||
PersonaMetadataDialog.nameLbl.text=Name:
|
||||
PersonaMetadataDialog.okBtn.text=OK
|
||||
PersonaMetadataDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsPanel.editAccountBtn.text=Edit
|
||||
PersonaDetailsPanel.editMetadataBtn.text=Edit
|
||||
PersonaDetailsPanel.editAliasBtn.text=Edit
|
||||
PMTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?
|
||||
PMTopComponent_delete_confirmation_Title=Are you sure?
|
||||
PMTopComponent_delete_exception_msg=Failed to delete persona.
|
||||
|
||||
+51
-23
@@ -23,11 +23,11 @@ import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
|
||||
@@ -46,27 +46,50 @@ public class PersonaAccountDialog extends JDialog {
|
||||
private static final Logger logger = Logger.getLogger(PersonaAccountDialog.class.getName());
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
private final TypeChoiceRenderer TYPE_CHOICE_RENDERER = new TypeChoiceRenderer();
|
||||
private final PersonaDetailsPanel pdp;
|
||||
|
||||
|
||||
private PersonaDetailsPanel.PAccount currentAccount = null;
|
||||
|
||||
/**
|
||||
* Creates new add account dialog
|
||||
*/
|
||||
@Messages({"PersonaAccountDialog.title.text=Add Account",})
|
||||
public PersonaAccountDialog(PersonaDetailsPanel pdp) {
|
||||
super((JFrame) WindowManager.getDefault().getMainWindow(),
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.PersonaAccountDialog_title_text(),
|
||||
true);
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
this.pdp = pdp;
|
||||
|
||||
initComponents();
|
||||
typeComboBox.setRenderer(TYPE_CHOICE_RENDERER);
|
||||
display();
|
||||
}
|
||||
|
||||
|
||||
PersonaAccountDialog(PersonaDetailsPanel pdp, PersonaDetailsPanel.PAccount acc) {
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.PersonaAccountDialog_title_text(),
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
this.pdp = pdp;
|
||||
|
||||
initComponents();
|
||||
currentAccount = acc;
|
||||
confidenceComboBox.setSelectedItem(acc.confidence);
|
||||
justificationTextField.setText(acc.justification);
|
||||
typeComboBox.setSelectedItem(acc.account.getAccountType());
|
||||
identifierTextField.setText(acc.account.getIdentifier());
|
||||
|
||||
typeComboBox.setEnabled(false);
|
||||
identifierTextField.setEnabled(false);
|
||||
|
||||
typeComboBox.setRenderer(TYPE_CHOICE_RENDERER);
|
||||
display();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles displaying and rendering drop down menu for account choices
|
||||
* This class handles displaying and rendering drop down menu for account
|
||||
* choices
|
||||
*/
|
||||
private class TypeChoiceRenderer extends JLabel implements ListCellRenderer<CentralRepoAccountType>, Serializable {
|
||||
|
||||
@@ -80,11 +103,10 @@ public class PersonaAccountDialog extends JDialog {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Messages({
|
||||
"PersonaAccountDialog_get_types_exception_Title=Central Repository failure",
|
||||
"PersonaAccountDialog_get_types_exception_msg=Failed to access central repository.",
|
||||
})
|
||||
"PersonaAccountDialog_get_types_exception_msg=Failed to access central repository.",})
|
||||
private CentralRepoAccountType[] getAllAccountTypes() {
|
||||
Collection<CentralRepoAccountType> allAccountTypes;
|
||||
try {
|
||||
@@ -92,9 +114,9 @@ public class PersonaAccountDialog extends JDialog {
|
||||
} catch (CentralRepoException e) {
|
||||
logger.log(Level.SEVERE, "Failed to access central repository", e);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAccountDialog_get_types_exception_Title(),
|
||||
Bundle.PersonaAccountDialog_get_types_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
Bundle.PersonaAccountDialog_get_types_exception_Title(),
|
||||
Bundle.PersonaAccountDialog_get_types_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return new CentralRepoAccountType[0];
|
||||
}
|
||||
return allAccountTypes.toArray(new CentralRepoAccountType[0]);
|
||||
@@ -303,17 +325,23 @@ public class PersonaAccountDialog extends JDialog {
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pdp.addAccount(
|
||||
result,
|
||||
justificationTextField.getText(),
|
||||
(Persona.Confidence) confidenceComboBox.getSelectedItem())) {
|
||||
|
||||
Persona.Confidence confidence = (Persona.Confidence) confidenceComboBox.getSelectedItem();
|
||||
String justification = justificationTextField.getText();
|
||||
|
||||
if (currentAccount != null) {
|
||||
currentAccount.confidence = confidence;
|
||||
currentAccount.justification = justification;
|
||||
dispose();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAccountDialog_dup_msg(),
|
||||
Bundle.PersonaAccountDialog_dup_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
if (pdp.addAccount(result, justification, confidence)) {
|
||||
dispose();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAccountDialog_dup_msg(),
|
||||
Bundle.PersonaAccountDialog_dup_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_okBtnActionPerformed
|
||||
|
||||
@@ -324,7 +352,7 @@ public class PersonaAccountDialog extends JDialog {
|
||||
private void identifierTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_identifierTextFieldActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_identifierTextFieldActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton cancelBtn;
|
||||
private javax.swing.JComboBox<org.sleuthkit.autopsy.centralrepository.datamodel.Persona.Confidence> confidenceComboBox;
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
package org.sleuthkit.autopsy.centralrepository.persona;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
@@ -35,20 +35,39 @@ public class PersonaAliasDialog extends JDialog {
|
||||
|
||||
private final PersonaDetailsPanel pdp;
|
||||
|
||||
private PersonaDetailsPanel.PAlias currentAlias = null;
|
||||
|
||||
/**
|
||||
* Creates new add alias dialog
|
||||
*/
|
||||
@Messages({"PersonaAliasDialog.title.text=Add Alias",})
|
||||
public PersonaAliasDialog(PersonaDetailsPanel pdp) {
|
||||
super((JFrame) WindowManager.getDefault().getMainWindow(),
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.PersonaAliasDialog_title_text(),
|
||||
true);
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
this.pdp = pdp;
|
||||
|
||||
initComponents();
|
||||
display();
|
||||
}
|
||||
|
||||
PersonaAliasDialog(PersonaDetailsPanel pdp, PersonaDetailsPanel.PAlias pa) {
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.PersonaAliasDialog_title_text(),
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
this.pdp = pdp;
|
||||
|
||||
initComponents();
|
||||
currentAlias = pa;
|
||||
confidenceComboBox.setSelectedItem(pa.confidence);
|
||||
justificationTextField.setText(pa.justification);
|
||||
aliasTextField.setText(pa.alias);
|
||||
|
||||
aliasTextField.setEnabled(false);
|
||||
|
||||
display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -176,9 +195,18 @@ public class PersonaAliasDialog extends JDialog {
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"PersonaAliasDialog_empty_Title=Empty alias",
|
||||
"PersonaAliasDialog_empty_msg=An alias cannot be empty.",
|
||||
"PersonaAliasDialog_dup_Title=Alias add failure",
|
||||
"PersonaAliasDialog_dup_msg=This alias has already been added to this persona",})
|
||||
"PersonaAliasDialog_dup_msg=This alias has already been added to this persona.",})
|
||||
private void okBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okBtnActionPerformed
|
||||
if (aliasTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAliasDialog_empty_msg(),
|
||||
Bundle.PersonaAliasDialog_empty_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (justificationTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaDetailsPanel_empty_justification_msg(),
|
||||
@@ -186,16 +214,23 @@ public class PersonaAliasDialog extends JDialog {
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (pdp.addAlias(
|
||||
aliasTextField.getText(),
|
||||
justificationTextField.getText(),
|
||||
(Persona.Confidence) confidenceComboBox.getSelectedItem())) {
|
||||
|
||||
Persona.Confidence confidence = (Persona.Confidence) confidenceComboBox.getSelectedItem();
|
||||
String justification = justificationTextField.getText();
|
||||
|
||||
if (currentAlias != null) {
|
||||
currentAlias.confidence = confidence;
|
||||
currentAlias.justification = justification;
|
||||
dispose();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
if (pdp.addAlias(aliasTextField.getText(), justification, confidence)) {
|
||||
dispose();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAliasDialog_dup_msg(),
|
||||
Bundle.PersonaAliasDialog_dup_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_okBtnActionPerformed
|
||||
|
||||
|
||||
@@ -84,19 +84,25 @@
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="addAccountBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="editAccountBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="deleteAccountBtn" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="addMetadataBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="editMetadataBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="deleteMetadataBtn" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="addAliasBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="editAliasBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="deleteAliasBtn" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@@ -144,24 +150,27 @@
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="addAccountBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteAccountBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="editAccountBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="metadataLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="metadataTablePane" min="-2" pref="66" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deleteMetadataBtn" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="addMetadataBtn" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="addMetadataBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteMetadataBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="editMetadataBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="aliasesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="aliasesTablePane" min="-2" pref="74" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deleteAliasBtn" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="addAliasBtn" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="addAliasBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteAliasBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="editAliasBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="casesLbl" min="-2" max="-2" attributes="0"/>
|
||||
@@ -264,6 +273,14 @@
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editAccountBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaDetailsPanel.editAccountBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteAccountBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
@@ -303,6 +320,14 @@
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editMetadataBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaDetailsPanel.editMetadataBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteMetadataBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
@@ -342,6 +367,14 @@
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editAliasBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaDetailsPanel.editAliasBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteAliasBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
|
||||
+143
-39
@@ -23,8 +23,10 @@ import java.awt.event.ActionEvent;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JOptionPane;
|
||||
@@ -69,6 +71,10 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
private final List<PersonaMetadata> metadataToRemove = new ArrayList<>();
|
||||
private final List<PersonaAlias> aliasesToRemove = new ArrayList<>();
|
||||
|
||||
private final Map<PersonaAccount, PAccount> accountsToEdit = new HashMap<>();
|
||||
private final Map<PersonaMetadata, PMetadata> metadataToEdit = new HashMap<>();
|
||||
private final Map<PersonaAlias, PAlias> aliasesToEdit = new HashMap<>();
|
||||
|
||||
private Persona currentPersona;
|
||||
private List<PersonaAccount> currentAccounts = new ArrayList<>();
|
||||
private List<PersonaMetadata> currentMetadata = new ArrayList<>();
|
||||
@@ -91,6 +97,19 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
addAccountBtn.addActionListener((ActionEvent e) -> {
|
||||
new PersonaAccountDialog(this);
|
||||
});
|
||||
editAccountBtn.addActionListener((ActionEvent e) -> {
|
||||
int selectedRow = accountsTable.getSelectedRow();
|
||||
if (selectedRow != -1) {
|
||||
if (selectedRow >= currentAccounts.size()) {
|
||||
PAccount acc = accountsToAdd.get(selectedRow - currentAccounts.size());
|
||||
new PersonaAccountDialog(this, acc);
|
||||
} else {
|
||||
PersonaAccount personaAccount = currentAccounts.get(selectedRow);
|
||||
accountsToEdit.putIfAbsent(personaAccount, new PAccount(personaAccount.getAccount(), personaAccount.getJustification(), personaAccount.getConfidence()));
|
||||
new PersonaAccountDialog(this, accountsToEdit.get(personaAccount));
|
||||
}
|
||||
}
|
||||
});
|
||||
deleteAccountBtn.addActionListener((ActionEvent e) -> {
|
||||
int selectedRow = accountsTable.getSelectedRow();
|
||||
if (selectedRow != -1) {
|
||||
@@ -98,21 +117,36 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
if (selectedRow >= currentAccounts.size()) {
|
||||
accountsToAdd.remove(selectedRow - currentAccounts.size());
|
||||
} else {
|
||||
accountsToRemove.add(currentAccounts.get(selectedRow));
|
||||
currentAccounts.remove(selectedRow);
|
||||
PersonaAccount toRemove = currentAccounts.get(selectedRow);
|
||||
accountsToEdit.remove(toRemove);
|
||||
accountsToRemove.add(toRemove);
|
||||
currentAccounts.remove(toRemove);
|
||||
}
|
||||
updateAccountsTable();
|
||||
}
|
||||
});
|
||||
accountsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
accountsTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
|
||||
handleSelectionChange(e, deleteAccountBtn, accountsTable);
|
||||
handleSelectionChange(e, editAccountBtn, deleteAccountBtn, accountsTable);
|
||||
});
|
||||
|
||||
// Metadata
|
||||
addMetadataBtn.addActionListener((ActionEvent e) -> {
|
||||
new PersonaMetadataDialog(this);
|
||||
});
|
||||
editMetadataBtn.addActionListener((ActionEvent e) -> {
|
||||
int selectedRow = metadataTable.getSelectedRow();
|
||||
if (selectedRow != -1) {
|
||||
if (selectedRow >= currentMetadata.size()) {
|
||||
PMetadata md = metadataToAdd.get(selectedRow - currentMetadata.size());
|
||||
new PersonaMetadataDialog(this, md);
|
||||
} else {
|
||||
PersonaMetadata personaMetadata = currentMetadata.get(selectedRow);
|
||||
metadataToEdit.putIfAbsent(personaMetadata, new PMetadata(personaMetadata.getName(), personaMetadata.getValue(), personaMetadata.getJustification(), personaMetadata.getConfidence()));
|
||||
new PersonaMetadataDialog(this, metadataToEdit.get(personaMetadata));
|
||||
}
|
||||
}
|
||||
});
|
||||
deleteMetadataBtn.addActionListener((ActionEvent e) -> {
|
||||
int selectedRow = metadataTable.getSelectedRow();
|
||||
if (selectedRow != -1) {
|
||||
@@ -120,21 +154,36 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
if (selectedRow >= currentMetadata.size()) {
|
||||
metadataToAdd.remove(selectedRow - currentMetadata.size());
|
||||
} else {
|
||||
metadataToRemove.add(currentMetadata.get(selectedRow));
|
||||
currentMetadata.remove(selectedRow);
|
||||
PersonaMetadata toRemove = currentMetadata.get(selectedRow);
|
||||
metadataToEdit.remove(toRemove);
|
||||
metadataToRemove.add(toRemove);
|
||||
currentMetadata.remove(toRemove);
|
||||
}
|
||||
updateMetadataTable();
|
||||
}
|
||||
});
|
||||
metadataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
metadataTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
|
||||
handleSelectionChange(e, deleteMetadataBtn, metadataTable);
|
||||
handleSelectionChange(e, editMetadataBtn, deleteMetadataBtn, metadataTable);
|
||||
});
|
||||
|
||||
// Aliases
|
||||
addAliasBtn.addActionListener((ActionEvent e) -> {
|
||||
new PersonaAliasDialog(this);
|
||||
});
|
||||
editAliasBtn.addActionListener((ActionEvent e) -> {
|
||||
int selectedRow = aliasesTable.getSelectedRow();
|
||||
if (selectedRow != -1) {
|
||||
if (selectedRow >= currentAliases.size()) {
|
||||
PAlias pa = aliasesToAdd.get(selectedRow - currentAliases.size());
|
||||
new PersonaAliasDialog(this, pa);
|
||||
} else {
|
||||
PersonaAlias personaAlias = currentAliases.get(selectedRow);
|
||||
aliasesToEdit.putIfAbsent(personaAlias, new PAlias(personaAlias.getAlias(), personaAlias.getJustification(), personaAlias.getConfidence()));
|
||||
new PersonaAliasDialog(this, aliasesToEdit.get(personaAlias));
|
||||
}
|
||||
}
|
||||
});
|
||||
deleteAliasBtn.addActionListener((ActionEvent e) -> {
|
||||
int selectedRow = aliasesTable.getSelectedRow();
|
||||
if (selectedRow != -1) {
|
||||
@@ -142,33 +191,48 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
if (selectedRow >= currentAliases.size()) {
|
||||
aliasesToAdd.remove(selectedRow - currentAliases.size());
|
||||
} else {
|
||||
aliasesToRemove.add(currentAliases.get(selectedRow));
|
||||
currentAliases.remove(selectedRow);
|
||||
PersonaAlias toRemove = currentAliases.get(selectedRow);
|
||||
aliasesToEdit.remove(toRemove);
|
||||
aliasesToRemove.add(toRemove);
|
||||
currentAliases.remove(toRemove);
|
||||
}
|
||||
updateAliasesTable();
|
||||
}
|
||||
});
|
||||
aliasesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
aliasesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
|
||||
handleSelectionChange(e, deleteAliasBtn, aliasesTable);
|
||||
handleSelectionChange(e, editAliasBtn, deleteAliasBtn, aliasesTable);
|
||||
});
|
||||
}
|
||||
|
||||
private void handleSelectionChange(ListSelectionEvent e, JButton btn, JTable table) {
|
||||
private void handleSelectionChange(ListSelectionEvent e, JButton editBtn, JButton deleteBtn, JTable table) {
|
||||
if (e.getValueIsAdjusting()) {
|
||||
return;
|
||||
}
|
||||
btn.setEnabled(mode != PersonaDetailsMode.VIEW && table.getSelectedRow() != -1);
|
||||
editBtn.setEnabled(mode != PersonaDetailsMode.VIEW && table.getSelectedRow() != -1);
|
||||
deleteBtn.setEnabled(mode != PersonaDetailsMode.VIEW && table.getSelectedRow() != -1);
|
||||
}
|
||||
|
||||
void addEditExistingAccount(PersonaAccount account, String justification, Persona.Confidence confidence) {
|
||||
accountsToEdit.put(account, new PAccount(account.getAccount(), justification, confidence));
|
||||
}
|
||||
|
||||
void addEditExistingMetadata(PersonaMetadata metadata, String justification, Persona.Confidence confidence) {
|
||||
metadataToEdit.put(metadata, new PMetadata(metadata.getName(), metadata.getValue(), justification, confidence));
|
||||
}
|
||||
|
||||
void addEditExistingAlias(PersonaAlias alias, String justification, Persona.Confidence confidence) {
|
||||
aliasesToEdit.put(alias, new PAlias(alias.getAlias(), justification, confidence));
|
||||
}
|
||||
|
||||
/**
|
||||
* A data bucket class for yet-to-be-created PersonaAccount
|
||||
*/
|
||||
private class PAccount {
|
||||
class PAccount {
|
||||
|
||||
private final CentralRepoAccount account;
|
||||
private final String justification;
|
||||
private final Persona.Confidence confidence;
|
||||
CentralRepoAccount account;
|
||||
String justification;
|
||||
Persona.Confidence confidence;
|
||||
|
||||
PAccount(CentralRepoAccount account, String justification, Persona.Confidence confidence) {
|
||||
this.account = account;
|
||||
@@ -189,7 +253,7 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addAccount(CentralRepoAccount account, String justification, Persona.Confidence confidence) {
|
||||
if (!accountExists(account)) {
|
||||
@@ -203,12 +267,12 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
/**
|
||||
* A data bucket class for yet-to-be-created PersonaMetadata
|
||||
*/
|
||||
private class PMetadata {
|
||||
class PMetadata {
|
||||
|
||||
private final String name;
|
||||
private final String value;
|
||||
private final String justification;
|
||||
private final Persona.Confidence confidence;
|
||||
String name;
|
||||
String value;
|
||||
String justification;
|
||||
Persona.Confidence confidence;
|
||||
|
||||
PMetadata(String name, String value, String justification, Persona.Confidence confidence) {
|
||||
this.name = name;
|
||||
@@ -244,11 +308,11 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
/**
|
||||
* A data bucket class for yet-to-be-created PersonaAlias
|
||||
*/
|
||||
private class PAlias {
|
||||
class PAlias {
|
||||
|
||||
private final String alias;
|
||||
private final String justification;
|
||||
private final Persona.Confidence confidence;
|
||||
String alias;
|
||||
String justification;
|
||||
Persona.Confidence confidence;
|
||||
|
||||
PAlias(String alias, String justification, Persona.Confidence confidence) {
|
||||
this.alias = alias;
|
||||
@@ -301,16 +365,19 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
accountsTablePane = new javax.swing.JScrollPane();
|
||||
accountsTable = new javax.swing.JTable();
|
||||
addAccountBtn = new javax.swing.JButton();
|
||||
editAccountBtn = new javax.swing.JButton();
|
||||
deleteAccountBtn = new javax.swing.JButton();
|
||||
metadataLabel = new javax.swing.JLabel();
|
||||
metadataTablePane = new javax.swing.JScrollPane();
|
||||
metadataTable = new javax.swing.JTable();
|
||||
addMetadataBtn = new javax.swing.JButton();
|
||||
editMetadataBtn = new javax.swing.JButton();
|
||||
deleteMetadataBtn = new javax.swing.JButton();
|
||||
aliasesLabel = new javax.swing.JLabel();
|
||||
aliasesTablePane = new javax.swing.JScrollPane();
|
||||
aliasesTable = new javax.swing.JTable();
|
||||
addAliasBtn = new javax.swing.JButton();
|
||||
editAliasBtn = new javax.swing.JButton();
|
||||
deleteAliasBtn = new javax.swing.JButton();
|
||||
casesLbl = new javax.swing.JLabel();
|
||||
casesTablePane = new javax.swing.JScrollPane();
|
||||
@@ -354,6 +421,9 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(addAccountBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.addAccountBtn.text")); // NOI18N
|
||||
addAccountBtn.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editAccountBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.editAccountBtn.text")); // NOI18N
|
||||
editAccountBtn.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteAccountBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.deleteAccountBtn.text")); // NOI18N
|
||||
deleteAccountBtn.setEnabled(false);
|
||||
|
||||
@@ -375,6 +445,9 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(addMetadataBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.addMetadataBtn.text")); // NOI18N
|
||||
addMetadataBtn.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editMetadataBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.editMetadataBtn.text")); // NOI18N
|
||||
editMetadataBtn.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteMetadataBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.deleteMetadataBtn.text")); // NOI18N
|
||||
deleteMetadataBtn.setEnabled(false);
|
||||
|
||||
@@ -396,6 +469,9 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(addAliasBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.addAliasBtn.text")); // NOI18N
|
||||
addAliasBtn.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editAliasBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.editAliasBtn.text")); // NOI18N
|
||||
editAliasBtn.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteAliasBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.deleteAliasBtn.text")); // NOI18N
|
||||
deleteAliasBtn.setEnabled(false);
|
||||
|
||||
@@ -442,14 +518,20 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
.addGroup(detailsPanelLayout.createSequentialGroup()
|
||||
.addComponent(addAccountBtn)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(editAccountBtn)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(deleteAccountBtn))
|
||||
.addGroup(detailsPanelLayout.createSequentialGroup()
|
||||
.addComponent(addMetadataBtn)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(editMetadataBtn)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(deleteMetadataBtn))
|
||||
.addGroup(detailsPanelLayout.createSequentialGroup()
|
||||
.addComponent(addAliasBtn)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(editAliasBtn)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(deleteAliasBtn)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(detailsPanelLayout.createSequentialGroup()
|
||||
@@ -486,23 +568,26 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(addAccountBtn)
|
||||
.addComponent(deleteAccountBtn))
|
||||
.addComponent(deleteAccountBtn)
|
||||
.addComponent(editAccountBtn))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(metadataLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(metadataTablePane, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(addMetadataBtn)
|
||||
.addComponent(deleteMetadataBtn)
|
||||
.addComponent(addMetadataBtn))
|
||||
.addComponent(editMetadataBtn))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(aliasesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(aliasesTablePane, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(addAliasBtn)
|
||||
.addComponent(deleteAliasBtn)
|
||||
.addComponent(addAliasBtn))
|
||||
.addComponent(editAliasBtn))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(casesLbl)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
@@ -549,6 +634,9 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JButton deleteAliasBtn;
|
||||
private javax.swing.JButton deleteMetadataBtn;
|
||||
private javax.swing.JPanel detailsPanel;
|
||||
private javax.swing.JButton editAccountBtn;
|
||||
private javax.swing.JButton editAliasBtn;
|
||||
private javax.swing.JButton editMetadataBtn;
|
||||
private javax.swing.JTextField examinerField;
|
||||
private javax.swing.JLabel examinerLbl;
|
||||
private javax.swing.JLabel metadataLabel;
|
||||
@@ -560,7 +648,7 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
|
||||
@Messages({
|
||||
"PersonaDetailsPanel_load_exception_Title=Initialization failure",
|
||||
"PersonaDetailsPanel_load_exception_msg=Failed to load persona",})
|
||||
"PersonaDetailsPanel_load_exception_msg=Failed to load persona.",})
|
||||
private void loadPersona(Component parent, Persona persona) {
|
||||
String examiner;
|
||||
String creationDate;
|
||||
@@ -626,6 +714,9 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
deleteAccountBtn.setEnabled(false);
|
||||
deleteMetadataBtn.setEnabled(false);
|
||||
deleteAliasBtn.setEnabled(false);
|
||||
editAccountBtn.setEnabled(false);
|
||||
editMetadataBtn.setEnabled(false);
|
||||
editAliasBtn.setEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -729,12 +820,15 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
addAccountBtn.setEnabled(enabled);
|
||||
addMetadataBtn.setEnabled(enabled);
|
||||
addAliasBtn.setEnabled(enabled);
|
||||
|
||||
|
||||
addAccountBtn.setVisible(enabled);
|
||||
editAccountBtn.setVisible(enabled);
|
||||
deleteAccountBtn.setVisible(enabled);
|
||||
addMetadataBtn.setVisible(enabled);
|
||||
editMetadataBtn.setVisible(enabled);
|
||||
deleteMetadataBtn.setVisible(enabled);
|
||||
addAliasBtn.setVisible(enabled);
|
||||
editAliasBtn.setVisible(enabled);
|
||||
deleteAliasBtn.setVisible(enabled);
|
||||
}
|
||||
|
||||
@@ -780,13 +874,13 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account",
|
||||
"PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account.",
|
||||
"PersonaDetailsPanel_NotEnoughAccounts_Title=Missing account",
|
||||
"PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository",
|
||||
"PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository.",
|
||||
"PersonaDetailsPanel_CentralRepoErr_Title=Central Repository failure",
|
||||
"PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty",
|
||||
"PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty.",
|
||||
"PersonaDetailsPanel_EmptyName_Title=Empty persona name",
|
||||
"PersonaDetailsPanel_EmptyComment_msg=Persona comment cannot be empty",
|
||||
"PersonaDetailsPanel_EmptyComment_msg=Persona comment cannot be empty.",
|
||||
"PersonaDetailsPanel_EmptyComment_Title=Empty persona comment",})
|
||||
Persona okHandler() {
|
||||
if (accountsToAdd.size() + currentAccounts.size() < 1) {
|
||||
@@ -851,18 +945,27 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
for (PersonaAccount acc : accountsToRemove) {
|
||||
ret.removeAccount(acc);
|
||||
}
|
||||
for (HashMap.Entry<PersonaAccount, PAccount> entry : accountsToEdit.entrySet()) {
|
||||
ret.modifyAccount(entry.getKey(), entry.getValue().confidence, entry.getValue().justification);
|
||||
}
|
||||
for (PMetadata md : metadataToAdd) {
|
||||
ret.addMetadata(md.name, md.value, md.justification, md.confidence);
|
||||
}
|
||||
for (PersonaMetadata md : metadataToRemove) {
|
||||
ret.removeMetadata(md);
|
||||
}
|
||||
for (HashMap.Entry<PersonaMetadata, PMetadata> entry : metadataToEdit.entrySet()) {
|
||||
ret.modifyMetadata(entry.getKey(), entry.getValue().confidence, entry.getValue().justification);
|
||||
}
|
||||
for (PAlias pa : aliasesToAdd) {
|
||||
ret.addAlias(pa.alias, pa.justification, pa.confidence);
|
||||
}
|
||||
for (PersonaAlias pa : aliasesToRemove) {
|
||||
ret.removeAlias(pa);
|
||||
}
|
||||
for (HashMap.Entry<PersonaAlias, PAlias> entry : aliasesToEdit.entrySet()) {
|
||||
ret.modifyAlias(entry.getKey(), entry.getValue().confidence, entry.getValue().justification);
|
||||
}
|
||||
} catch (CentralRepoException e) {
|
||||
logger.log(Level.SEVERE, "Failed to access central repository", e);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
@@ -873,20 +976,21 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
break;
|
||||
case VIEW:
|
||||
ret = currentPersona;
|
||||
break;
|
||||
default:
|
||||
logger.log(Level.SEVERE, "Unsupported mode: {0}", mode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the persona name field.
|
||||
*
|
||||
*
|
||||
* @param name Persona name.
|
||||
*/
|
||||
public void setPersonaName(String name) {
|
||||
nameField.setText(name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+46
-10
@@ -19,8 +19,8 @@
|
||||
package org.sleuthkit.autopsy.centralrepository.persona;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
@@ -35,20 +35,41 @@ public class PersonaMetadataDialog extends JDialog {
|
||||
|
||||
private final PersonaDetailsPanel pdp;
|
||||
|
||||
private PersonaDetailsPanel.PMetadata currentMetadata;
|
||||
|
||||
/**
|
||||
* Creates new add metadata dialog
|
||||
*/
|
||||
@Messages({"AddMetadataDialog.title.text=Add Metadata",})
|
||||
public PersonaMetadataDialog(PersonaDetailsPanel pdp) {
|
||||
super((JFrame) WindowManager.getDefault().getMainWindow(),
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.AddMetadataDialog_title_text(),
|
||||
true);
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
this.pdp = pdp;
|
||||
|
||||
initComponents();
|
||||
display();
|
||||
}
|
||||
|
||||
PersonaMetadataDialog(PersonaDetailsPanel pdp, PersonaDetailsPanel.PMetadata md) {
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.AddMetadataDialog_title_text(),
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
this.pdp = pdp;
|
||||
|
||||
initComponents();
|
||||
currentMetadata = md;
|
||||
confidenceComboBox.setSelectedItem(md.confidence);
|
||||
justificationTextField.setText(md.justification);
|
||||
nameTextField.setText(md.name);
|
||||
valueTextField.setText(md.value);
|
||||
|
||||
nameTextField.setEnabled(false);
|
||||
valueTextField.setEnabled(false);
|
||||
|
||||
display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -191,8 +212,17 @@ public class PersonaMetadataDialog extends JDialog {
|
||||
|
||||
@Messages({
|
||||
"AddMetadataDialog_dup_Title=Metadata add failure",
|
||||
"AddMetadataDialog_dup_msg=A metadata entry with this name has already been added to this persona",})
|
||||
"AddMetadataDialog_dup_msg=A metadata entry with this name has already been added to this persona.",
|
||||
"AddMetadataDialog_empty_name_Title=Missing field(s)",
|
||||
"AddMetadataDialog_empty_name_msg=A metadata entry cannot have an empty name or value.",})
|
||||
private void okBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okBtnActionPerformed
|
||||
if (nameTextField.getText().isEmpty() || valueTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.AddMetadataDialog_empty_name_msg(),
|
||||
Bundle.AddMetadataDialog_empty_name_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (justificationTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaDetailsPanel_empty_justification_msg(),
|
||||
@@ -200,17 +230,23 @@ public class PersonaMetadataDialog extends JDialog {
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (pdp.addMetadata(
|
||||
nameTextField.getText(),
|
||||
valueTextField.getText(),
|
||||
justificationTextField.getText(),
|
||||
(Persona.Confidence) confidenceComboBox.getSelectedItem())) {
|
||||
|
||||
Persona.Confidence confidence = (Persona.Confidence) confidenceComboBox.getSelectedItem();
|
||||
String justification = justificationTextField.getText();
|
||||
|
||||
if (currentMetadata != null) {
|
||||
currentMetadata.confidence = confidence;
|
||||
currentMetadata.justification = justification;
|
||||
dispose();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
if (pdp.addMetadata(nameTextField.getText(), valueTextField.getText(), justification, confidence)) {
|
||||
dispose();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.AddMetadataDialog_dup_msg(),
|
||||
Bundle.AddMetadataDialog_dup_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_okBtnActionPerformed
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.contentviewers;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* A data bag for the persona searching thread. It wraps the account id to
|
||||
* search for, and the UI label and button to update once the search completes.
|
||||
*/
|
||||
class AccountPersonaSearcherData {
|
||||
|
||||
// Account identifier to search personas for.
|
||||
private final String accountIdentifer;
|
||||
// Persona name label to be updated when the search is complete.
|
||||
private final JLabel personaNameLabel;
|
||||
// Persona action button to be updated when the search is complete
|
||||
private final JButton personaActionButton;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param accountIdentifer Account identifier.
|
||||
* @param personaNameLabel Persona name label.
|
||||
* @param personaActionButton Persona button.
|
||||
*/
|
||||
AccountPersonaSearcherData(String accountIdentifer, JLabel personaNameLabel, JButton personaActionButton) {
|
||||
this.accountIdentifer = accountIdentifer;
|
||||
this.personaNameLabel = personaNameLabel;
|
||||
this.personaActionButton = personaActionButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the account identifier.
|
||||
*
|
||||
* @return Account identifier.
|
||||
*/
|
||||
public String getAccountIdentifer() {
|
||||
return accountIdentifer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the persona name label.
|
||||
*
|
||||
* @return Persona name label.
|
||||
*/
|
||||
public JLabel getPersonaNameLabel() {
|
||||
return personaNameLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the persona button.
|
||||
*
|
||||
* @return Persona button.
|
||||
*/
|
||||
public JButton getPersonaActionButton() {
|
||||
return personaActionButton;
|
||||
}
|
||||
}
|
||||
@@ -976,7 +976,9 @@ MessageArtifactViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF
|
||||
MessageArtifactViewer.toText.text=to list goes here
|
||||
MessageArtifactViewer.toLabel.text=To:
|
||||
MessageArtifactViewer.htmlPane.TabConstraints.tabTitle=HTML
|
||||
CallLogArtifactViewer.localAccountPersonaLabel.text=Persona:
|
||||
CallLogArtifactViewer.localAccountPersonaLabel.text=Persona
|
||||
CallLogArtifactViewer.localAccountPersonaNameLabel.text=jLabel1
|
||||
CallLogArtifactViewer.localAccountPersonaButton.text=jButton1
|
||||
ContactArtifactViewer.personasLabel.text=Personas
|
||||
MessageArtifactViewer.accountsTab.TabConstraints.tabTitle=Accounts
|
||||
ContactArtifactViewer.contactImage.text=
|
||||
|
||||
@@ -35,6 +35,8 @@ AnnotationsContentViewer.title=Annotations
|
||||
AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content.
|
||||
ApplicationContentViewer.title=Application
|
||||
ApplicationContentViewer.toolTip=Displays file contents.
|
||||
CallLogArtifactViewer_crdisbaled_persona_button_text=Create
|
||||
CallLogArtifactViewer_crdisbaled_persona_label=Unknown
|
||||
CallLogArtifactViewer_number_from=From
|
||||
CallLogArtifactViewer_number_to=To
|
||||
CallLogArtifactViewer_persona_button_new=Create
|
||||
@@ -49,6 +51,7 @@ ContactArtifactViewer_persona_button_view=View
|
||||
ContactArtifactViewer_persona_label=Persona
|
||||
ContactArtifactViewer_persona_searching=\ Searching...
|
||||
ContactArtifactViewer_persona_text_none=None found
|
||||
ContactArtifactViewer_persona_unknown=Unknown
|
||||
DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database
|
||||
DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database
|
||||
DefaultArtifactContentViewer.attrsTableHeader.sources=Source(s)
|
||||
@@ -104,6 +107,10 @@ MediaViewVideoPanel.progressLabel.text=00:00
|
||||
MediaViewVideoPanel.infoLabel.text=info
|
||||
MediaViewImagePanel.imgFileTooLarge.msg=Could not load image file (too large): {0}
|
||||
|
||||
MessageAccountPanel_button_create_label=Create
|
||||
MessageAccountPanel_button_view_label=View
|
||||
MessageAccountPanel_persona_label=Persona:
|
||||
MessageAccountPanel_unknown_label=Unknown
|
||||
MessageArtifactViewer.AttachmentPanel.title=Attachments
|
||||
Metadata.nodeText.none=None
|
||||
Metadata.nodeText.truncated=(results truncated)
|
||||
@@ -1084,7 +1091,9 @@ MessageArtifactViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF
|
||||
MessageArtifactViewer.toText.text=to list goes here
|
||||
MessageArtifactViewer.toLabel.text=To:
|
||||
MessageArtifactViewer.htmlPane.TabConstraints.tabTitle=HTML
|
||||
CallLogArtifactViewer.localAccountPersonaLabel.text=Persona:
|
||||
CallLogArtifactViewer.localAccountPersonaLabel.text=Persona
|
||||
CallLogArtifactViewer.localAccountPersonaNameLabel.text=jLabel1
|
||||
CallLogArtifactViewer.localAccountPersonaButton.text=jButton1
|
||||
ContactArtifactViewer.personasLabel.text=Personas
|
||||
MessageArtifactViewer.accountsTab.TabConstraints.tabTitle=Accounts
|
||||
ContactArtifactViewer.contactImage.text=
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
@@ -11,391 +11,8 @@
|
||||
<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,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="topPanel" min="-2" pref="860" max="-2" attributes="0"/>
|
||||
<Component id="bottomPanel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="topPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="bottomPanel" min="-2" pref="297" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="topPanel">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="callDetailsPanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[400, 150]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="callDetailsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="directionLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="callLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="onLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="dateTimeLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="durationLabel" min="-2" pref="88" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="participantsListPanel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="485" max="32767" 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="callDetailsLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="participantsListPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="directionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="callLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="onLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dateTimeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="durationLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="directionLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font component="directionLabel" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.directionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="dateTimeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.dateTimeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="durationLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.durationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="callDetailsLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="callDetailsLabel" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.callDetailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="onLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.onLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="callLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.callLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="participantsListPanel">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="350" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="58" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="otherAttributesPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Last"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="otherAttributesListPanel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
|
||||
<Component id="otherInfoLabel" min="-2" pref="372" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="otherInfoLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="otherAttributesListPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="otherInfoLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="otherInfoLabel" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.otherInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="otherAttributesListPanel">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="413" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="88" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="bottomPanel">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="localAccountInfoPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="North"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="localAccountLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel4" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deviceIdLabel" alignment="0" pref="437" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dataSourceNameLabel" min="-2" pref="130" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="localAccountIdLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="localAccountPersonaLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="localAccountPersonaNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="localAccountPersonaButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
|
||||
<Component id="sourceSectionLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="243" max="32767" 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="sourceSectionLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="localAccountLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="localAccountIdLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="localAccountPersonaLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="localAccountPersonaNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="localAccountPersonaButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel4" alignment="3" min="-2" pref="16" max="-2" attributes="0"/>
|
||||
<Component id="dataSourceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deviceIdLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="22" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="dataSourceNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.dataSourceNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="deviceIdLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.deviceIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="localAccountLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="localAccountIdLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="sourceSectionLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="sourceSectionLabel" property="font" relativeSize="true" size="0"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.sourceSectionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="localAccountPersonaLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountPersonaLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="localAccountPersonaNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountPersonaNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="localAccountPersonaButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountPersonaButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Form>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,50 +29,61 @@ import java.util.Map;
|
||||
*/
|
||||
final class CallLogViewData {
|
||||
|
||||
// primary to/from number/adddress/accountId
|
||||
private String number;
|
||||
private String numberTypeDesignator; // to for from designator
|
||||
private String name = null;
|
||||
private String fromAccount = null;
|
||||
private String toAccount = null;
|
||||
|
||||
// account identifier of the device owner, if known.
|
||||
// will be one of the to or from account.
|
||||
private String localAccountId = null;
|
||||
|
||||
private String direction;
|
||||
private String dateTimeStr = null;
|
||||
private String duration = null;
|
||||
private Collection<String> otherRecipients = new ArrayList<>();
|
||||
private String dataSourceName = null;
|
||||
private String dataSourceDeviceId = null;
|
||||
private String localAccountId = null; // number/accountId of device owner, may not be always known
|
||||
|
||||
// Account identifers of other parties in the call.
|
||||
private Collection<String> otherParties = new ArrayList<>();
|
||||
|
||||
private Map<String, String> otherAttributes = new HashMap<>();
|
||||
|
||||
CallLogViewData(String number) {
|
||||
this(number, null);
|
||||
private String dataSourceName = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param fromAccount From account identifier, may be null;
|
||||
* @param toAccount To account identifier, may be null;
|
||||
*/
|
||||
CallLogViewData(String fromAccount, String toAccount) {
|
||||
this(fromAccount, toAccount, null);
|
||||
}
|
||||
|
||||
CallLogViewData(String number, String direction) {
|
||||
this.number = number;
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param fromAccount From account identifier, may be null;
|
||||
* @param toAccount To account identifier, may be null;
|
||||
* @param direction Direction, may be null.
|
||||
*/
|
||||
CallLogViewData(String fromAccount, String toAccount, String direction) {
|
||||
this.fromAccount = fromAccount;
|
||||
this.toAccount = toAccount;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
String getNumber() {
|
||||
return number;
|
||||
String getFromAccount() {
|
||||
return fromAccount;
|
||||
}
|
||||
|
||||
void setNumber(String number) {
|
||||
this.number = number;
|
||||
void setFromAccount(String fromAccount) {
|
||||
this.fromAccount = fromAccount;
|
||||
}
|
||||
|
||||
public String getNumberDesignator() {
|
||||
return numberTypeDesignator;
|
||||
String getToAccount() {
|
||||
return toAccount;
|
||||
}
|
||||
|
||||
public void setNumberDesignator(String numberDesignator) {
|
||||
this.numberTypeDesignator = numberDesignator;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
void setToAccount(String toAccount) {
|
||||
this.toAccount = toAccount;
|
||||
}
|
||||
|
||||
String getDirection() {
|
||||
@@ -91,14 +102,6 @@ final class CallLogViewData {
|
||||
this.dataSourceName = dataSourceName;
|
||||
}
|
||||
|
||||
String getDataSourceDeviceId() {
|
||||
return dataSourceDeviceId;
|
||||
}
|
||||
|
||||
void setDataSourceDeviceId(String dataSourceDeviceId) {
|
||||
this.dataSourceDeviceId = dataSourceDeviceId;
|
||||
}
|
||||
|
||||
String getDateTimeStr() {
|
||||
return dateTimeStr;
|
||||
}
|
||||
@@ -115,13 +118,13 @@ final class CallLogViewData {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
Collection<String> getOtherRecipients() {
|
||||
return Collections.unmodifiableCollection(otherRecipients);
|
||||
Collection<String> getOtherParties() {
|
||||
return Collections.unmodifiableCollection(otherParties);
|
||||
}
|
||||
|
||||
void setOtherRecipients(Collection<String> otherParticipants) {
|
||||
void setOtherParties(Collection<String> otherParticipants) {
|
||||
if (otherParticipants != null) {
|
||||
this.otherRecipients = new ArrayList<>(otherParticipants);
|
||||
this.otherParties = new ArrayList<>(otherParticipants);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +133,7 @@ final class CallLogViewData {
|
||||
}
|
||||
|
||||
public void setOtherAttributes(Map<String, String> otherAttributes) {
|
||||
if (otherRecipients != null) {
|
||||
if (otherAttributes != null) {
|
||||
this.otherAttributes = new HashMap<>(otherAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.contentviewers;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.util.Optional;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* A class to help display a communication artifact in a panel using a
|
||||
* gridbaglayout.
|
||||
*/
|
||||
public final class CommunicationArtifactViewerHelper {
|
||||
|
||||
// Number of columns in the gridbag layout.
|
||||
private final static int MAX_COLS = 4;
|
||||
|
||||
private final static int LEFT_INDENT = 12;
|
||||
|
||||
/**
|
||||
* Empty private constructor
|
||||
*/
|
||||
private CommunicationArtifactViewerHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new heading to the panel.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param headerString Heading string to display.
|
||||
*/
|
||||
static void addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) {
|
||||
|
||||
// add a blank line before the start of new section, unless it's
|
||||
// the first section
|
||||
if (constraints.gridy != 0) {
|
||||
addBlankLine(panel, gridbagLayout, constraints);
|
||||
}
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
|
||||
// let the header span all of the row
|
||||
constraints.gridwidth = MAX_COLS;
|
||||
|
||||
// create label for heading
|
||||
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
|
||||
headingLabel.setText(headerString);
|
||||
|
||||
// make it large and bold
|
||||
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(headingLabel, constraints);
|
||||
panel.add(headingLabel);
|
||||
|
||||
// reset constraints to normal
|
||||
constraints.gridwidth = 1;
|
||||
|
||||
// add line end glue
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a filler/glue at the end of the line to keep the other columns
|
||||
* aligned, in case the panel is resized.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
*/
|
||||
private static void addLineEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
// Place the filler just past the last column.
|
||||
constraints.gridx = MAX_COLS;
|
||||
|
||||
double savedWeightX = constraints.weightx;
|
||||
int savedFill = constraints.fill;
|
||||
|
||||
constraints.weightx = 1.0; // take up all the horizontal space
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
|
||||
javax.swing.Box.Filler horizontalFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 0));
|
||||
gridbagLayout.setConstraints(horizontalFiller, constraints);
|
||||
panel.add(horizontalFiller);
|
||||
|
||||
// restore fill & weight
|
||||
constraints.fill = savedFill;
|
||||
constraints.weightx = savedWeightX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a filler/glue at the bottom of the panel to keep the data rows
|
||||
* aligned, in case the panel is resized.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
*/
|
||||
static void addPageEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
|
||||
constraints.gridx = 0;
|
||||
|
||||
double savedWeighty = constraints.weighty;
|
||||
int savedFill = constraints.fill;
|
||||
|
||||
constraints.weighty = 1.0; // take up all the vertical space
|
||||
constraints.fill = GridBagConstraints.VERTICAL;
|
||||
|
||||
javax.swing.Box.Filler vertFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(0, 32767));
|
||||
gridbagLayout.setConstraints(vertFiller, constraints);
|
||||
panel.add(vertFiller, constraints);
|
||||
|
||||
//Resore weight & fill
|
||||
constraints.weighty = savedWeighty;
|
||||
constraints.fill = savedFill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a blank line to the panel.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
*/
|
||||
private static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
|
||||
javax.swing.JLabel filler = new javax.swing.JLabel(" ");
|
||||
gridbagLayout.setConstraints(filler, constraints);
|
||||
panel.add(filler);
|
||||
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a label/key to the panel.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param keyString Key name to display.
|
||||
*/
|
||||
static void addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) {
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// Set inset to indent in
|
||||
constraints.insets = new java.awt.Insets(0, LEFT_INDENT, 0, 0);
|
||||
|
||||
// create label,
|
||||
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
|
||||
keyLabel.setText(keyString + ": ");
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(keyLabel, constraints);
|
||||
panel.add(keyLabel);
|
||||
|
||||
// restore inset
|
||||
constraints.insets = savedInsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value string to the panel.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param keyString Value string to display.
|
||||
*/
|
||||
static void addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) {
|
||||
|
||||
constraints.gridx = 1;
|
||||
|
||||
int savedGridwidth = constraints.gridwidth;
|
||||
|
||||
// let the value span 2 cols
|
||||
constraints.gridwidth = 2;
|
||||
|
||||
// create label,
|
||||
javax.swing.JLabel valueField = new javax.swing.JLabel();
|
||||
valueField.setText(valueString);
|
||||
|
||||
// attach a right click menu with Copy option
|
||||
valueField.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
valueLabelMouseClicked(evt, valueField);
|
||||
}
|
||||
});
|
||||
|
||||
// add label to panel
|
||||
gridbagLayout.setConstraints(valueField, constraints);
|
||||
panel.add(valueField);
|
||||
|
||||
// restore constraints
|
||||
constraints.gridwidth = savedGridwidth;
|
||||
|
||||
// end the line
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Persona row to the panel.
|
||||
*
|
||||
* Adds a persona name label and a button to the panel. Kicks off a
|
||||
* background task to search for persona for the given account. Updates the
|
||||
* persona name and button when the task is done.
|
||||
*
|
||||
* If CentralRepostory is disabled, just displays 'Unknown' persona name.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param accountIdentifier Account identifier to search the persona.
|
||||
*
|
||||
* @return Optional PersonaSearchAndDisplayTask started to search for
|
||||
* persona.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CommunicationArtifactViewerHelper_persona_label=Persona: ",
|
||||
"CommunicationArtifactViewerHelper_persona_searching=Searching...",
|
||||
"CommunicationArtifactViewerHelper_persona_unknown=Unknown",
|
||||
"CommunicationArtifactViewerHelper_persona_button_view=View",
|
||||
"CommunicationArtifactViewerHelper_persona_button_create=Create"
|
||||
})
|
||||
static Optional<PersonaSearchAndDisplayTask> addPersonaRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String accountIdentifier) {
|
||||
|
||||
PersonaSearchAndDisplayTask personaTask = null;
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 1;
|
||||
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// Indent in
|
||||
constraints.insets = new java.awt.Insets(0, LEFT_INDENT, 0, 0);
|
||||
|
||||
// create label
|
||||
javax.swing.JLabel personaLabel = new javax.swing.JLabel();
|
||||
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
||||
personaLabelText = personaLabelText.concat(CentralRepository.isEnabled()
|
||||
? Bundle.CommunicationArtifactViewerHelper_persona_searching()
|
||||
: Bundle.CommunicationArtifactViewerHelper_persona_unknown());
|
||||
|
||||
personaLabel.setText(personaLabelText);
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(personaLabel, constraints);
|
||||
panel.add(personaLabel);
|
||||
|
||||
// restore constraint
|
||||
constraints.insets = savedInsets;
|
||||
|
||||
constraints.gridx++;
|
||||
|
||||
// Place a button as place holder. It will be enabled when persona is available.
|
||||
javax.swing.JButton personaButton = new javax.swing.JButton();
|
||||
personaButton.setText(Bundle.CommunicationArtifactViewerHelper_persona_button_view());
|
||||
personaButton.setEnabled(false);
|
||||
|
||||
|
||||
gridbagLayout.setConstraints(personaButton, constraints);
|
||||
panel.add(personaButton);
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
// kick off a task to find the persona for this account
|
||||
personaTask = new PersonaSearchAndDisplayTask(panel, new AccountPersonaSearcherData(accountIdentifier, personaLabel, personaButton));
|
||||
personaTask.execute();
|
||||
} else {
|
||||
personaLabel.setEnabled(false);
|
||||
}
|
||||
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
|
||||
return Optional.ofNullable(personaTask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for mouse click event. Attaches a 'Copy' menu item to right
|
||||
* click.
|
||||
*
|
||||
* @param evt Event to check.
|
||||
* @param valueLabel Label to attach the menu item to.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CommunicationArtifactViewerHelper_menuitem_copy=Copy"
|
||||
})
|
||||
private static void valueLabelMouseClicked(java.awt.event.MouseEvent evt, JLabel valueLabel) {
|
||||
if (SwingUtilities.isRightMouseButton(evt)) {
|
||||
JPopupMenu popup = new JPopupMenu();
|
||||
|
||||
JMenuItem copyMenu = new JMenuItem(Bundle.CommunicationArtifactViewerHelper_menuitem_copy()); // NON-NLS
|
||||
copyMenu.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(valueLabel.getText()), null);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
popup.add(copyMenu);
|
||||
popup.show(valueLabel, evt.getX(), evt.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,30 +19,11 @@
|
||||
<Container class="javax.swing.JPanel" name="namePanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="4" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="1" gridWidth="5" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="contactNameLabel" min="-2" pref="240" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" 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="contactNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="contactNameLabel">
|
||||
<Properties>
|
||||
@@ -55,6 +36,11 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.contactNameLabel.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="111" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
@@ -71,14 +57,14 @@
|
||||
</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="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="phoneNumbersPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="3" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
@@ -97,14 +83,14 @@
|
||||
</Properties>
|
||||
<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="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="4" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="emailsPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="4" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="5" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
@@ -123,14 +109,14 @@
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="otherAttrsPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="6" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="7" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
@@ -149,7 +135,7 @@
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="7" gridWidth="1" gridHeight="2" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.1"/>
|
||||
<GridBagConstraints gridX="0" gridY="8" gridWidth="1" gridHeight="2" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.1"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -175,14 +161,14 @@
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="8" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="9" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="personasPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="9" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="10" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
@@ -201,7 +187,7 @@
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="10" gridWidth="4" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="11" gridWidth="4" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -218,7 +204,22 @@
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="8" fill="1" ipadX="2" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="4" gridY="3" gridWidth="1" gridHeight="8" fill="1" ipadX="2" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="contactImage">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/defaultContact.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.contactImage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{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="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
|
||||
@@ -23,6 +23,9 @@ import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -33,6 +36,8 @@ import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
@@ -42,6 +47,7 @@ import javax.swing.SwingWorker;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
@@ -49,8 +55,10 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallb
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
@@ -75,11 +83,16 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
// account identifier attributes of the Contact artifact.
|
||||
private final Map<Persona, ArrayList<CentralRepoAccount>> contactUniquePersonasMap = new HashMap<>();
|
||||
|
||||
private final static String DEFAULT_IMAGE_PATH = "/org/sleuthkit/autopsy/images/defaultContact.png";
|
||||
private final ImageIcon defaultImage;
|
||||
|
||||
/**
|
||||
* Creates new form for ContactArtifactViewer
|
||||
*/
|
||||
public ContactArtifactViewer() {
|
||||
initComponents();
|
||||
|
||||
defaultImage = new ImageIcon(ContactArtifactViewer.class.getResource(DEFAULT_IMAGE_PATH));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,41 +118,38 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
personasPanel = new javax.swing.JPanel();
|
||||
javax.swing.Box.Filler bottomFiller = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
|
||||
javax.swing.Box.Filler rightFiller = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
||||
contactImage = new javax.swing.JLabel();
|
||||
|
||||
setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
namePanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
contactNameLabel.setFont(contactNameLabel.getFont().deriveFont((contactNameLabel.getFont().getStyle() | java.awt.Font.ITALIC) | java.awt.Font.BOLD, contactNameLabel.getFont().getSize()+6));
|
||||
org.openide.awt.Mnemonics.setLocalizedText(contactNameLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.contactNameLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout namePanelLayout = new javax.swing.GroupLayout(namePanel);
|
||||
namePanel.setLayout(namePanelLayout);
|
||||
namePanelLayout.setHorizontalGroup(
|
||||
namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(namePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(contactNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
namePanelLayout.setVerticalGroup(
|
||||
namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(namePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(contactNameLabel)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.ipadx = 111;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
namePanel.add(contactNameLabel, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.gridwidth = 5;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
|
||||
add(namePanel, gridBagConstraints);
|
||||
|
||||
phonesLabel.setFont(phonesLabel.getFont().deriveFont(phonesLabel.getFont().getStyle() | java.awt.Font.BOLD, phonesLabel.getFont().getSize()+2));
|
||||
org.openide.awt.Mnemonics.setLocalizedText(phonesLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.phonesLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.gridwidth = 3;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
|
||||
@@ -148,7 +158,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
phoneNumbersPanel.setLayout(new java.awt.GridBagLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
@@ -159,7 +169,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
org.openide.awt.Mnemonics.setLocalizedText(emailsLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.emailsLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
|
||||
@@ -168,7 +178,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
emailsPanel.setLayout(new java.awt.GridBagLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
@@ -179,7 +189,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
org.openide.awt.Mnemonics.setLocalizedText(othersLabel, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.othersLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
|
||||
add(othersLabel, gridBagConstraints);
|
||||
@@ -187,7 +197,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
otherAttrsPanel.setLayout(new java.awt.GridBagLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.gridy = 7;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
@@ -195,7 +205,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
add(otherAttrsPanel, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 7;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.gridheight = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
|
||||
gridBagConstraints.weighty = 0.1;
|
||||
@@ -208,7 +218,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
personasLabel.setPreferredSize(new java.awt.Dimension(90, 19));
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.gridy = 9;
|
||||
gridBagConstraints.gridwidth = 3;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
|
||||
@@ -217,7 +227,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
personasPanel.setLayout(new java.awt.GridBagLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 9;
|
||||
gridBagConstraints.gridy = 10;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
@@ -225,19 +235,27 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
add(personasPanel, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 10;
|
||||
gridBagConstraints.gridy = 11;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
add(bottomFiller, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.gridheight = 8;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.ipadx = 2;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
add(rightFiller, gridBagConstraints);
|
||||
|
||||
contactImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/defaultContact.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(contactImage, org.openide.util.NbBundle.getMessage(ContactArtifactViewer.class, "ContactArtifactViewer.contactImage.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 19, 0, 0);
|
||||
add(contactImage, gridBagConstraints);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@Override
|
||||
@@ -291,6 +309,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
logger.log(Level.SEVERE, String.format("Error getting Personas for Contact artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
|
||||
}
|
||||
|
||||
contactImage.setIcon(getImageFromArtifact(artifact));
|
||||
|
||||
// repaint
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
@@ -333,6 +353,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
contactName = null;
|
||||
contactUniqueAccountsList.clear();
|
||||
contactUniquePersonasMap.clear();
|
||||
contactImage.setIcon(defaultImage);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,12 +445,17 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* @throws CentralRepoException
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"ContactArtifactViewer_persona_searching= Searching..."
|
||||
"ContactArtifactViewer_persona_searching= Searching...",
|
||||
"ContactArtifactViewer_persona_unknown=Unknown"
|
||||
})
|
||||
private void initiatePersonasSearch(List<BlackboardAttribute> accountAttributesList) throws CentralRepoException {
|
||||
|
||||
personasLabel.setVisible(true);
|
||||
|
||||
String personaStatusLabelText = CentralRepository.isEnabled()
|
||||
? Bundle.ContactArtifactViewer_persona_searching()
|
||||
: Bundle.ContactArtifactViewer_persona_unknown();
|
||||
|
||||
// create a gridbag layout to show each participant on one line
|
||||
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
@@ -451,19 +477,27 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
personasPanel.add(personaLabel);
|
||||
|
||||
constraints.gridy++;
|
||||
javax.swing.JLabel primaryPersonaNameLabel = new javax.swing.JLabel();
|
||||
primaryPersonaNameLabel.setText(Bundle.ContactArtifactViewer_persona_searching());
|
||||
gridBagLayout.setConstraints(primaryPersonaNameLabel, constraints);
|
||||
personasPanel.add(primaryPersonaNameLabel);
|
||||
javax.swing.JLabel personaStatusLabel = new javax.swing.JLabel();
|
||||
personaStatusLabel.setText(personaStatusLabelText);
|
||||
gridBagLayout.setConstraints(personaStatusLabel, constraints);
|
||||
personasPanel.add(personaStatusLabel);
|
||||
|
||||
|
||||
if (CentralRepository.isEnabled() ) {
|
||||
personasLabel.setEnabled(true);
|
||||
|
||||
// Kick off a background task to serach for personas for the contact
|
||||
ContactPersonaSearcherTask personaSearchTask = new ContactPersonaSearcherTask(accountAttributesList);
|
||||
personaSearchTask.execute();
|
||||
} else {
|
||||
personasLabel.setEnabled(false);
|
||||
personaLabel.setEnabled(false);
|
||||
personaStatusLabel.setEnabled(false);
|
||||
}
|
||||
|
||||
personasPanel.setLayout(gridBagLayout);
|
||||
personasPanel.revalidate();
|
||||
personasPanel.repaint();
|
||||
|
||||
// Kick off a background task to serach for personas for the contact
|
||||
ContactPersonaSearcherTask personaSearchTask = new ContactPersonaSearcherTask(accountAttributesList);
|
||||
personaSearchTask.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -602,6 +636,49 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an image from a TSK_CONTACT artifact.
|
||||
*
|
||||
* @param artifact
|
||||
*
|
||||
* @return Image from a TSK_CONTACT artifact or default image if none was
|
||||
* found or the artifact is not a TSK_CONTACT
|
||||
*/
|
||||
private ImageIcon getImageFromArtifact(BlackboardArtifact artifact) {
|
||||
ImageIcon imageIcon = defaultImage;
|
||||
|
||||
if (artifact == null) {
|
||||
return imageIcon;
|
||||
}
|
||||
|
||||
BlackboardArtifact.ARTIFACT_TYPE artifactType = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID());
|
||||
if (artifactType != BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT) {
|
||||
return imageIcon;
|
||||
}
|
||||
|
||||
try {
|
||||
for (Content content : artifact.getChildren()) {
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) content;
|
||||
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(new File(file.getLocalAbsPath()));
|
||||
imageIcon = new ImageIcon(image);
|
||||
break;
|
||||
} catch (IOException ex) {
|
||||
// ImageIO.read will through an IOException if file is not an image
|
||||
// therefore we don't need to report this exception just try
|
||||
// the next file.
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, String.format("Unable to load image for contact: %d", artifact.getId()), ex);
|
||||
}
|
||||
|
||||
return imageIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread to search for a personas for all account identifier attributes for
|
||||
* a contact.
|
||||
@@ -850,6 +927,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel contactImage;
|
||||
private javax.swing.JLabel contactNameLabel;
|
||||
private javax.swing.JLabel emailsLabel;
|
||||
private javax.swing.JPanel emailsPanel;
|
||||
|
||||
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.contentviewers;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import javax.swing.GroupLayout.ParallelGroup;
|
||||
import javax.swing.GroupLayout.SequentialGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Panel for displaying accounts and their persona information.
|
||||
*
|
||||
*/
|
||||
final class MessageAccountPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(MessageAccountPanel.class.getName());
|
||||
|
||||
private AccountFetcher currentFetcher = null;
|
||||
|
||||
/**
|
||||
* Set the new artifact for the panel.
|
||||
*
|
||||
* @param artifact
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
void setArtifact(BlackboardArtifact artifact) {
|
||||
removeAll();
|
||||
setLayout(null);
|
||||
repaint();
|
||||
|
||||
if (artifact == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentFetcher != null && !currentFetcher.isDone()) {
|
||||
currentFetcher.cancel(true);
|
||||
}
|
||||
|
||||
currentFetcher = new AccountFetcher(artifact);
|
||||
currentFetcher.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Swingworker that fetches the accounts for a given artifact
|
||||
*/
|
||||
class AccountFetcher extends SwingWorker<List<AccountContainer>, Void> {
|
||||
|
||||
private final BlackboardArtifact artifact;
|
||||
|
||||
/**
|
||||
* Construct a new AccountFetcher.
|
||||
*
|
||||
* @param artifact The artifact to get accounts for.
|
||||
*/
|
||||
AccountFetcher(BlackboardArtifact artifact) {
|
||||
this.artifact = artifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AccountContainer> doInBackground() throws Exception {
|
||||
List<AccountContainer> dataList = new ArrayList<>();
|
||||
|
||||
CommunicationsManager commManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||
List<Account> accountList = commManager.getAccountsRelatedToArtifact(artifact);
|
||||
for (Account account : accountList) {
|
||||
if (isCancelled()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
Collection<PersonaAccount> personAccounts = PersonaAccount.getPersonaAccountsForAccount(account);
|
||||
if (personAccounts != null && !personAccounts.isEmpty()) {
|
||||
for (PersonaAccount personaAccount : PersonaAccount.getPersonaAccountsForAccount(account)) {
|
||||
dataList.add(new AccountContainer(account, personaAccount));
|
||||
}
|
||||
} else {
|
||||
dataList.add(new AccountContainer(account, null));
|
||||
}
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
List<AccountContainer> dataList = get();
|
||||
|
||||
dataList.forEach(container -> {
|
||||
container.initalizeSwingControls();
|
||||
});
|
||||
|
||||
GroupLayout layout = new GroupLayout(MessageAccountPanel.this);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(getMainHorizontalGroup(layout, dataList))
|
||||
.addContainerGap(158, Short.MAX_VALUE)));
|
||||
|
||||
layout.setVerticalGroup(getMainVerticalGroup(layout, dataList));
|
||||
setLayout(layout);
|
||||
repaint();
|
||||
} catch (CancellationException ex) {
|
||||
logger.log(Level.INFO, "MessageAccoutPanel thread cancelled", ex);
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get account list for MessageAccountPanel", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the main horizontal ParalleGroup the encompasses all of the
|
||||
* controls.
|
||||
*
|
||||
* @return A ParallelGroup object
|
||||
*/
|
||||
private ParallelGroup getMainHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||
ParallelGroup group = layout.createParallelGroup(Alignment.LEADING);
|
||||
for (AccountContainer o : data) {
|
||||
group.addComponent(o.getAccountLabel());
|
||||
}
|
||||
group.addGroup(getPersonaHorizontalGroup(layout, data));
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Vertical Group for the account controls.
|
||||
*
|
||||
* @return The vertical group object
|
||||
*/
|
||||
private ParallelGroup getMainVerticalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||
SequentialGroup group = layout.createSequentialGroup();
|
||||
for (AccountContainer o : data) {
|
||||
group.addGap(5)
|
||||
.addComponent(o.getAccountLabel())
|
||||
.addGroup(o.getPersonLineVerticalGroup(layout));
|
||||
}
|
||||
|
||||
group.addContainerGap(83, Short.MAX_VALUE);
|
||||
|
||||
return layout.createParallelGroup().addGroup(group);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* To line up the Persona buttons they need to be in their own
|
||||
* ParalletGroup.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private ParallelGroup getButtonGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||
ParallelGroup group = layout.createParallelGroup(Alignment.LEADING);
|
||||
for (AccountContainer o : data) {
|
||||
group.addComponent(o.getButton());
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the group with just the persona header and the person value.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private SequentialGroup getPersonaHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||
SequentialGroup group = layout.createSequentialGroup();
|
||||
ParallelGroup pgroup = layout.createParallelGroup(Alignment.LEADING);
|
||||
group.addGap(10);
|
||||
for (AccountContainer o : data) {
|
||||
pgroup.addGroup(o.getPersonaSequentialGroup(layout));
|
||||
}
|
||||
group.addGap(10)
|
||||
.addGroup(pgroup)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(getButtonGroup(layout, data));
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Container for each account entry in the panel. This class holds both the
|
||||
* account objects and the ui components.
|
||||
*/
|
||||
private class AccountContainer {
|
||||
|
||||
private final Account account;
|
||||
private Persona persona = null;
|
||||
|
||||
private JLabel accountLabel;
|
||||
private JLabel personaHeader;
|
||||
private JLabel personaDisplayName;
|
||||
private JButton button;
|
||||
|
||||
/**
|
||||
* Construct a new AccountContainer
|
||||
*
|
||||
* @param account
|
||||
* @param personaAccount
|
||||
*/
|
||||
AccountContainer(Account account, PersonaAccount personaAccount) {
|
||||
this.account = account;
|
||||
this.persona = personaAccount != null ? personaAccount.getPersona() : null;
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"MessageAccountPanel_persona_label=Persona:",
|
||||
"MessageAccountPanel_unknown_label=Unknown",
|
||||
"MessageAccountPanel_button_view_label=View",
|
||||
"MessageAccountPanel_button_create_label=Create"
|
||||
})
|
||||
/**
|
||||
* Swing components will not be initialized until this method is called.
|
||||
*/
|
||||
private void initalizeSwingControls() {
|
||||
accountLabel = new JLabel();
|
||||
personaHeader = new JLabel(Bundle.MessageAccountPanel_persona_label());
|
||||
personaDisplayName = new JLabel();
|
||||
button = new JButton();
|
||||
button.addActionListener(new PersonaButtonListener(this));
|
||||
|
||||
accountLabel.setText(account.getTypeSpecificID());
|
||||
|
||||
personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label());
|
||||
button.setText(persona != null ? Bundle.MessageAccountPanel_button_view_label() : Bundle.MessageAccountPanel_button_create_label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new persona for this object and update the controls.
|
||||
*
|
||||
* @param persona
|
||||
*/
|
||||
private void setPersona(Persona persona) {
|
||||
this.persona = persona;
|
||||
|
||||
// Make sure this runs in EDT
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label());
|
||||
button.setText(persona != null ? Bundle.MessageAccountPanel_button_view_label() : Bundle.MessageAccountPanel_button_create_label());
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the account object for this container.
|
||||
*
|
||||
* @return Account object.
|
||||
*/
|
||||
private Account getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PersonaAccount object for this container. Maybe null;
|
||||
*
|
||||
* @return PersonaAccount object or null if one was not set.
|
||||
*/
|
||||
private Persona getPersona() {
|
||||
return persona;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JLabel for that contains the Account type specific id.
|
||||
*
|
||||
* @return JLabel object
|
||||
*/
|
||||
private JLabel getAccountLabel() {
|
||||
return accountLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Persona Buttons for this container.
|
||||
*
|
||||
* @return The persona button.
|
||||
*/
|
||||
private JButton getButton() {
|
||||
return button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the horizontal layout code for the person line.
|
||||
*
|
||||
* @param layout Instance of GroupLayout to update.
|
||||
*
|
||||
* @return A group for the personal controls.
|
||||
*/
|
||||
private SequentialGroup getPersonaSequentialGroup(GroupLayout layout) {
|
||||
SequentialGroup group = layout.createSequentialGroup();
|
||||
|
||||
group
|
||||
.addComponent(personaHeader)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(personaDisplayName);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the vertical layout code for the persona line.
|
||||
*
|
||||
* @param layout Instance of GroupLayout to update.
|
||||
*
|
||||
* @return A group for the personal controls.
|
||||
*/
|
||||
private ParallelGroup getPersonLineVerticalGroup(GroupLayout layout) {
|
||||
return layout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(personaHeader)
|
||||
.addComponent(personaDisplayName)
|
||||
.addComponent(button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ActionListner for the persona buttons.
|
||||
*/
|
||||
private class PersonaButtonListener implements ActionListener {
|
||||
|
||||
private final AccountContainer accountContainer;
|
||||
|
||||
/**
|
||||
* Constructs the listener.
|
||||
*
|
||||
* @param accountContainer The account that does with list Listner.
|
||||
*/
|
||||
PersonaButtonListener(AccountContainer accountContainer) {
|
||||
this.accountContainer = accountContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Persona persona = accountContainer.getPersona();
|
||||
if (persona == null) {
|
||||
PersonaDetailsDialog createPersonaDialog = new PersonaDetailsDialog(
|
||||
MessageAccountPanel.this,
|
||||
PersonaDetailsMode.CREATE,
|
||||
null,
|
||||
new PersonaDialogCallbackImpl(accountContainer),
|
||||
false);
|
||||
|
||||
// Pre populate the persona name and accounts if we have them.
|
||||
PersonaDetailsPanel personaPanel = createPersonaDialog.getDetailsPanel();
|
||||
|
||||
personaPanel.setPersonaName(accountContainer.getAccount().getTypeSpecificID());
|
||||
|
||||
// display the dialog now
|
||||
createPersonaDialog.display();
|
||||
} else {
|
||||
new PersonaDetailsDialog(MessageAccountPanel.this,
|
||||
PersonaDetailsMode.VIEW, persona, new PersonaDialogCallbackImpl(accountContainer));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Call back for use by the PersonaDetailsDialog.
|
||||
*/
|
||||
private class PersonaDialogCallbackImpl implements PersonaDetailsDialogCallback {
|
||||
|
||||
private final AccountContainer accountContainer;
|
||||
|
||||
PersonaDialogCallbackImpl(AccountContainer accountContainer) {
|
||||
this.accountContainer = accountContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callback(Persona persona) {
|
||||
accountContainer.setPersona(persona);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -320,6 +320,30 @@
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="attachmentsScrollPane">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="accountsTab">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="Accounts">
|
||||
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="MessageArtifactViewer.accountsTab.TabConstraints.tabTitle" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="accountScrollPane">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.contentviewers.TranslatablePanel.TranslatablePanelException;
|
||||
import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
||||
@@ -125,6 +126,7 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
private static final int HTML_TAB_INDEX = 2;
|
||||
private static final int RTF_TAB_INDEX = 3;
|
||||
private static final int ATTM_TAB_INDEX = 4;
|
||||
private static final int ACCT_TAB_INDEX = 5;
|
||||
|
||||
private final List<JTextComponent> textAreas;
|
||||
private final org.sleuthkit.autopsy.contentviewers.HtmlPanel htmlPanel = new org.sleuthkit.autopsy.contentviewers.HtmlPanel();
|
||||
@@ -135,6 +137,13 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
private BlackboardArtifact artifact;
|
||||
private final DataResultPanel drp;
|
||||
private ExplorerManager drpExplorerManager;
|
||||
|
||||
private MessageAccountPanel accountsPanel;
|
||||
|
||||
public MessageArtifactViewer(List<JTextComponent> textAreas, DataResultPanel drp) {
|
||||
this.textAreas = textAreas;
|
||||
this.drp = drp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new MessageContentViewer
|
||||
@@ -142,6 +151,8 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
@NbBundle.Messages("MessageArtifactViewer.AttachmentPanel.title=Attachments")
|
||||
public MessageArtifactViewer() {
|
||||
initComponents();
|
||||
accountsPanel = new MessageAccountPanel();
|
||||
|
||||
htmlPane.add(htmlPanel);
|
||||
envelopePanel.setBackground(new Color(0, 0, 0, 38));
|
||||
drp = DataResultPanel.createInstanceUninitialized(Bundle.MessageArtifactViewer_AttachmentPanel_title(), "", new TableFilterNode(Node.EMPTY, false), 0, null);
|
||||
@@ -154,6 +165,9 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
TEXT_TAB_INDEX);
|
||||
|
||||
msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true);
|
||||
|
||||
accountScrollPane.setViewportView(accountsPanel);
|
||||
msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, CentralRepository.isEnabled());
|
||||
|
||||
/*
|
||||
* HTML tab uses the HtmlPanel instead of an internal text pane, so we
|
||||
@@ -205,6 +219,8 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
attachmentsPanel = new javax.swing.JPanel();
|
||||
viewInNewWindowButton = new javax.swing.JButton();
|
||||
attachmentsScrollPane = new javax.swing.JScrollPane();
|
||||
accountsTab = new javax.swing.JPanel();
|
||||
accountScrollPane = new javax.swing.JScrollPane();
|
||||
|
||||
envelopePanel.setBackground(new java.awt.Color(204, 204, 204));
|
||||
|
||||
@@ -342,6 +358,11 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.attachmentsPanel.TabConstraints.tabTitle"), attachmentsPanel); // NOI18N
|
||||
|
||||
accountsTab.setLayout(new java.awt.BorderLayout());
|
||||
accountsTab.add(accountScrollPane, java.awt.BorderLayout.CENTER);
|
||||
|
||||
msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.accountsTab.TabConstraints.tabTitle"), accountsTab); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
@@ -370,6 +391,8 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane accountScrollPane;
|
||||
private javax.swing.JPanel accountsTab;
|
||||
private javax.swing.JPanel attachmentsPanel;
|
||||
private javax.swing.JScrollPane attachmentsScrollPane;
|
||||
private javax.swing.JLabel ccLabel;
|
||||
@@ -421,6 +444,11 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
} else {
|
||||
resetComponent();
|
||||
}
|
||||
|
||||
msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, CentralRepository.isEnabled());
|
||||
if(CentralRepository.isEnabled()) {
|
||||
accountsPanel.setArtifact(artifact);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -655,7 +683,7 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
return doc.html();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates child nodes for message attachments.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.contentviewers;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Background task to search for a persona for a given account.
|
||||
*
|
||||
* When the search is complete, it updates the UI components
|
||||
* for the persona appropriately.
|
||||
*
|
||||
*/
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - Persona count",
|
||||
"PersonaDisplayTask_persona_count_suffix=(1 of {0})"
|
||||
})
|
||||
class PersonaSearchAndDisplayTask extends SwingWorker<Collection<Persona>, Void> {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(PersonaSearchAndDisplayTask.class.getName());
|
||||
|
||||
private final Component parentComponent;
|
||||
private final AccountPersonaSearcherData personaSearcherData;
|
||||
|
||||
PersonaSearchAndDisplayTask(Component parentComponent, AccountPersonaSearcherData personaSearcherData) {
|
||||
this.parentComponent = parentComponent;
|
||||
this.personaSearcherData = personaSearcherData;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Persona> doInBackground() throws Exception {
|
||||
|
||||
Collection<Persona> personas = new ArrayList<>();
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
Collection<CentralRepoAccount> accountCandidates
|
||||
= CentralRepoAccount.getAccountsWithIdentifier(personaSearcherData.getAccountIdentifer());
|
||||
|
||||
if (accountCandidates.isEmpty() == false) {
|
||||
CentralRepoAccount account = accountCandidates.iterator().next();
|
||||
|
||||
// get personas for the account
|
||||
Collection<PersonaAccount> personaAccountsList = PersonaAccount.getPersonaAccountsForAccount(account.getId());
|
||||
personas = personaAccountsList.stream().map(PersonaAccount::getPersona)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
return personas;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Collection<Persona> personas;
|
||||
try {
|
||||
personas = super.get();
|
||||
|
||||
if (this.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Update the Persona label and button based on the search result
|
||||
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
||||
String personaButtonText;
|
||||
ActionListener buttonActionListener;
|
||||
|
||||
if (personas.isEmpty()) {
|
||||
// No persona found
|
||||
personaLabelText += Bundle.CommunicationArtifactViewerHelper_persona_unknown();
|
||||
|
||||
// show a 'Create' button
|
||||
personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_create();
|
||||
buttonActionListener = new CreatePersonaButtonListener(parentComponent, personaSearcherData);
|
||||
} else {
|
||||
Persona persona = personas.iterator().next();
|
||||
personaLabelText += persona.getName();
|
||||
if (personas.size() > 1) {
|
||||
personaLabelText += Bundle.PersonaDisplayTask_persona_count_suffix(Integer.toString(personas.size()));
|
||||
}
|
||||
// Show a 'View' button
|
||||
personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_view();
|
||||
buttonActionListener = new ViewPersonaButtonListener(parentComponent, persona);
|
||||
}
|
||||
|
||||
personaSearcherData.getPersonaNameLabel().setText(personaLabelText);
|
||||
personaSearcherData.getPersonaActionButton().setText(personaButtonText);
|
||||
personaSearcherData.getPersonaActionButton().setEnabled(true);
|
||||
|
||||
// set button action
|
||||
personaSearcherData.getPersonaActionButton().addActionListener(buttonActionListener);
|
||||
} catch (CancellationException ex) {
|
||||
logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.INFO, "Persona searching was interrupted."); //NON-NLS
|
||||
} catch (ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Fatal error during Persona search.", ex); //NON-NLS
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action listener for Create persona button.
|
||||
*/
|
||||
private class CreatePersonaButtonListener implements ActionListener {
|
||||
|
||||
private final Component parentComponent;
|
||||
private final AccountPersonaSearcherData personaSearcherData;
|
||||
|
||||
CreatePersonaButtonListener(Component parentComponent, AccountPersonaSearcherData personaSearcherData) {
|
||||
this.parentComponent = parentComponent;
|
||||
this.personaSearcherData = personaSearcherData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
// Launch the Persona Create dialog
|
||||
new PersonaDetailsDialog(parentComponent,
|
||||
PersonaDetailsMode.CREATE, null, new PersonaCreateCallbackImpl(parentComponent, personaSearcherData));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action listener for View persona button.
|
||||
*/
|
||||
private class ViewPersonaButtonListener implements ActionListener {
|
||||
|
||||
private final Component parentComponent;
|
||||
private final Persona persona;
|
||||
|
||||
ViewPersonaButtonListener(Component parentComponent, Persona persona) {
|
||||
this.parentComponent = parentComponent;
|
||||
this.persona = persona;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
new PersonaDetailsDialog(parentComponent,
|
||||
PersonaDetailsMode.VIEW, persona, new PersonaViewCallbackImpl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method for the create mode of the PersonaDetailsDialog
|
||||
*/
|
||||
class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback {
|
||||
|
||||
private final Component parentComponent;
|
||||
private final AccountPersonaSearcherData personaSearcherData;
|
||||
|
||||
PersonaCreateCallbackImpl(Component parentComponent, AccountPersonaSearcherData personaSearcherData) {
|
||||
this.parentComponent = parentComponent;
|
||||
this.personaSearcherData = personaSearcherData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callback(Persona persona) {
|
||||
JButton personaButton = personaSearcherData.getPersonaActionButton();
|
||||
if (persona != null) {
|
||||
// update the persona name label with newly created persona,
|
||||
// and change the button to a "View" button
|
||||
personaSearcherData.getPersonaNameLabel().setText(Bundle.CommunicationArtifactViewerHelper_persona_label() + persona.getName());
|
||||
personaSearcherData.getPersonaActionButton().setText(Bundle.CommunicationArtifactViewerHelper_persona_button_view());
|
||||
|
||||
// replace action listener with a View button listener
|
||||
for (ActionListener act : personaButton.getActionListeners()) {
|
||||
personaButton.removeActionListener(act);
|
||||
}
|
||||
personaButton.addActionListener(new ViewPersonaButtonListener(parentComponent, persona));
|
||||
|
||||
}
|
||||
|
||||
personaButton.getParent().revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method for the view mode of the PersonaDetailsDialog
|
||||
*/
|
||||
class PersonaViewCallbackImpl implements PersonaDetailsDialogCallback {
|
||||
|
||||
@Override
|
||||
public void callback(Persona persona) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<name unique="discovery"/>
|
||||
<kind type="editor"/>
|
||||
<state type="separated"/>
|
||||
<bounds x="76" y="68" width="1400" height="900"/>
|
||||
<bounds x="76" y="68" width="1100" height="700"/>
|
||||
<frame state="0"/>
|
||||
|
||||
<empty-behavior permanent="false"/>
|
||||
|
||||
@@ -75,6 +75,9 @@
|
||||
<Component class="javax.swing.JTextArea" name="outputTextArea">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Font("Monospaced", Font.PLAIN, 11)" type="code"/>
|
||||
</Property>
|
||||
<Property name="tabSize" type="int" value="0"/>
|
||||
<Property name="inheritsPopupMenu" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.corecomponents;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
@@ -130,6 +131,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
|
||||
jScrollPane3.setPreferredSize(new java.awt.Dimension(300, 33));
|
||||
|
||||
outputTextArea.setEditable(false);
|
||||
outputTextArea.setFont(new Font("Monospaced", Font.PLAIN, 11));
|
||||
outputTextArea.setTabSize(0);
|
||||
outputTextArea.setInheritsPopupMenu(true);
|
||||
jScrollPane3.setViewportView(outputTextArea);
|
||||
|
||||
@@ -3,6 +3,5 @@ ExtractActionHelper.confDlg.destFileExist.msg=Destination file {0} already exist
|
||||
ExtractActionHelper.confDlg.destFileExist.title=File Exists
|
||||
ExtractActionHelper.msgDlg.cantOverwriteFile.msg=Could not overwrite existing file {0}
|
||||
ExtractActionHelper.notifyDlg.noFileToExtr.msg=No file(s) to extract.
|
||||
ExtractActionHelper.progress.extracting=Extracting
|
||||
ExtractActionHelper.progress.cancellingExtraction={0} (Cancelling...)
|
||||
ExtractActionHelper.done.notifyMsg.fileExtr.text=File(s) extracted.
|
||||
|
||||
@@ -4,6 +4,9 @@ ExtractActionHelper.confDlg.destFileExist.title=File Exists
|
||||
ExtractActionHelper.msgDlg.cantOverwriteFile.msg=Could not overwrite existing file {0}
|
||||
ExtractActionHelper.noOpenCase.errMsg=No open case available.
|
||||
ExtractActionHelper.notifyDlg.noFileToExtr.msg=No file(s) to extract.
|
||||
ExtractActionHelper.progress.extracting=Extracting
|
||||
ExtractActionHelper.progress.cancellingExtraction={0} (Cancelling...)
|
||||
ExtractActionHelper.done.notifyMsg.fileExtr.text=File(s) extracted.
|
||||
# {0} - outputFolderName
|
||||
ExtractActionHelper.progress.extracting=Extracting to {0}
|
||||
# {0} - fileName
|
||||
ExtractActionHelper.progress.fileExtracting=Extracting file: {0}
|
||||
|
||||
+21
-13
@@ -35,6 +35,7 @@ import javax.swing.SwingWorker;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.openide.util.Cancellable;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||
@@ -97,7 +98,7 @@ public class ExtractActionHelper {
|
||||
|
||||
ArrayList<FileExtractionTask> fileExtractionTasks = new ArrayList<>();
|
||||
fileExtractionTasks.add(new FileExtractionTask(selectedFile, fileChooser.getSelectedFile()));
|
||||
runExtractionTasks(event, fileExtractionTasks);
|
||||
runExtractionTasks(event, fileExtractionTasks, fileChooser.getSelectedFile().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +148,7 @@ public class ExtractActionHelper {
|
||||
// If there is an attribute name, change the ":". Otherwise the extracted file will be hidden
|
||||
fileExtractionTasks.add(new FileExtractionTask(source, new File(destinationFolder, source.getId() + "-" + FileUtil.escapeFileName(source.getName()))));
|
||||
}
|
||||
runExtractionTasks(event, fileExtractionTasks);
|
||||
runExtractionTasks(event, fileExtractionTasks, destinationFolder.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,8 +197,10 @@ public class ExtractActionHelper {
|
||||
* @param event ActionEvent whose source will be used for
|
||||
* centering popup dialogs.
|
||||
* @param fileExtractionTasks List of file extraction tasks.
|
||||
* @param destName Name of the destination used for progress
|
||||
* messages.
|
||||
*/
|
||||
private void runExtractionTasks(ActionEvent event, List<FileExtractionTask> fileExtractionTasks) {
|
||||
private void runExtractionTasks(ActionEvent event, List<FileExtractionTask> fileExtractionTasks, String destName) {
|
||||
|
||||
// verify all of the sources and destinations are OK
|
||||
for (Iterator<FileExtractionTask> it = fileExtractionTasks.iterator(); it.hasNext();) {
|
||||
@@ -231,7 +234,7 @@ public class ExtractActionHelper {
|
||||
// launch a thread to do the work
|
||||
if (!fileExtractionTasks.isEmpty()) {
|
||||
try {
|
||||
FileExtracter extracter = new FileExtracter(fileExtractionTasks);
|
||||
FileExtracter extracter = new FileExtracter(fileExtractionTasks, destName);
|
||||
extracter.execute();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Unable to start background file extraction thread", ex); //NON-NLS
|
||||
@@ -268,6 +271,7 @@ public class ExtractActionHelper {
|
||||
private class FileExtracter extends SwingWorker<Object, Void> {
|
||||
|
||||
private final Logger logger = Logger.getLogger(FileExtracter.class.getName());
|
||||
private final String destName;
|
||||
private ProgressHandle progress;
|
||||
private final List<FileExtractionTask> extractionTasks;
|
||||
|
||||
@@ -275,19 +279,28 @@ public class ExtractActionHelper {
|
||||
* Create an instance of the FileExtracter.
|
||||
*
|
||||
* @param extractionTasks List of file extraction tasks.
|
||||
* @param destName Name of the destination used for progress
|
||||
* messages.
|
||||
*/
|
||||
FileExtracter(List<FileExtractionTask> extractionTasks) {
|
||||
FileExtracter(List<FileExtractionTask> extractionTasks, String destName) {
|
||||
this.extractionTasks = extractionTasks;
|
||||
this.destName = destName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Messages({
|
||||
"# {0} - outputFolderName",
|
||||
"ExtractActionHelper.progress.extracting=Extracting to {0}",
|
||||
"# {0} - fileName",
|
||||
"ExtractActionHelper.progress.fileExtracting=Extracting file: {0}"
|
||||
})
|
||||
protected Object doInBackground() throws Exception {
|
||||
if (extractionTasks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Setup progress bar.
|
||||
final String displayName = NbBundle.getMessage(this.getClass(), "ExtractActionHelper.progress.extracting");
|
||||
final String displayName = Bundle.ExtractActionHelper_progress_extracting(destName);
|
||||
progress = ProgressHandle.createHandle(displayName, new Cancellable() {
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
@@ -301,15 +314,10 @@ public class ExtractActionHelper {
|
||||
progress.start();
|
||||
progress.switchToIndeterminate();
|
||||
|
||||
/*
|
||||
* @@@ Add back in -> Causes exceptions int workUnits = 0; for
|
||||
* (FileExtractionTask task : extractionTasks) { workUnits +=
|
||||
* calculateProgressBarWorkUnits(task.source); }
|
||||
* progress.switchToDeterminate(workUnits);
|
||||
*/
|
||||
// Do the extraction tasks.
|
||||
for (FileExtractionTask task : this.extractionTasks) {
|
||||
// @@@ Note, we are no longer passing in progress
|
||||
progress.progress(Bundle.ExtractActionHelper_progress_fileExtracting(task.destination.getName()));
|
||||
|
||||
ContentUtils.ExtractFscContentVisitor.extract(task.source, task.destination, null, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
/**
|
||||
* Abstract class extending JPanel for filter controls.
|
||||
*/
|
||||
abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Setup the file filter settings.
|
||||
*
|
||||
* @param selected Boolean indicating if the filter should be
|
||||
* selected.
|
||||
* @param indicesSelected Array of integers indicating which list items are
|
||||
* selected, null to indicate leaving selected items
|
||||
* unchanged or that there are no items to select.
|
||||
*/
|
||||
abstract void configurePanel(boolean selected, int[] indicesSelected);
|
||||
|
||||
/**
|
||||
* Get the checkbox which enables and disables this filter.
|
||||
*
|
||||
* @return The JCheckBox which enables and disables this filter.
|
||||
*/
|
||||
abstract JCheckBox getCheckbox();
|
||||
|
||||
/**
|
||||
* Get the list of values associated with this filter if one exists. If one
|
||||
* does not exist this should return null.
|
||||
*
|
||||
* @return The JList which contains the values available for selection for
|
||||
* this filter.
|
||||
*/
|
||||
abstract JList<?> getList();
|
||||
|
||||
/**
|
||||
* Get any additional text that should be displayed under the checkbox. If
|
||||
* no text should be displayed this should return null.
|
||||
*
|
||||
* @return The JLabel to display under the JCheckBox.
|
||||
*/
|
||||
abstract JLabel getAdditionalLabel();
|
||||
|
||||
/**
|
||||
* Check if this filter is configured to valid settings.
|
||||
*
|
||||
* @return If the settings are invalid returns the error that has occurred, otherwise returns empty string.
|
||||
*/
|
||||
abstract String checkForError();
|
||||
|
||||
/**
|
||||
* Add listeners to the checkbox/list set if listeners have not already been
|
||||
* added.
|
||||
*
|
||||
* @param actionlistener The listener for the checkbox selection events.
|
||||
* @param listListener The listener for the list selection events.
|
||||
*/
|
||||
void addListeners(ActionListener actionListener, ListSelectionListener listListener) {
|
||||
if (getCheckbox() != null) {
|
||||
getCheckbox().addActionListener(actionListener);
|
||||
}
|
||||
if (getList() != null) {
|
||||
getList().addListSelectionListener(listListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the FileFilter which is represented by this Panel.
|
||||
*
|
||||
* @return The FileFilter for the selected settings, null if the settings
|
||||
* are not in use.
|
||||
*/
|
||||
abstract FileSearchFiltering.FileFilter getFilter();
|
||||
|
||||
/**
|
||||
* Remove listeners from the checkbox and the list if they exist.
|
||||
*/
|
||||
void removeListeners() {
|
||||
if (getCheckbox() != null) {
|
||||
for (ActionListener listener : getCheckbox().getActionListeners()) {
|
||||
getCheckbox().removeActionListener(listener);
|
||||
}
|
||||
}
|
||||
if (getList() != null) {
|
||||
for (ListSelectionListener listener : getList().getListSelectionListeners()) {
|
||||
getList().removeListSelectionListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not this filter has a panel.
|
||||
*
|
||||
* @return True if there is a panel to display associated with this filter,
|
||||
* return false if the filter only has a checkbox.
|
||||
*/
|
||||
boolean hasPanel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Abstract class extending JPanel for displaying all the filters associated
|
||||
* with a type.
|
||||
*/
|
||||
abstract class AbstractFiltersPanel extends JPanel implements ActionListener, ListSelectionListener {
|
||||
|
||||
private boolean isInitialized = false;
|
||||
private static final double LABEL_WEIGHT = 0;
|
||||
private static final double PANEL_WEIGHT = .1;
|
||||
private static final int LABEL_WIDTH = 1;
|
||||
private static final int PANEL_WIDTH = 2;
|
||||
private static final int LABEL_HEIGHT = 1;
|
||||
private static final int PANEL_HEIGHT = 2;
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final GridBagConstraints constraints = new GridBagConstraints();
|
||||
private final List<AbstractDiscoveryFilterPanel> filters = new ArrayList<>();
|
||||
private final JPanel firstColumnPanel = new JPanel();
|
||||
private final JPanel secondColumnPanel = new JPanel();
|
||||
private int firstColumnY = 0;
|
||||
private int secondColumnY = 0;
|
||||
|
||||
/**
|
||||
* Setup necessary for implementations of this abstract class.
|
||||
*/
|
||||
AbstractFiltersPanel() {
|
||||
firstColumnPanel.setLayout(new GridBagLayout());
|
||||
secondColumnPanel.setLayout(new GridBagLayout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of results this filters panel is for.
|
||||
*
|
||||
* @return The type of results this panel filters.
|
||||
*/
|
||||
abstract FileSearchData.FileType getFileType();
|
||||
|
||||
/**
|
||||
* Add a DiscoveryFilterPanel to the specified column with the specified
|
||||
* settings.
|
||||
*
|
||||
* @param filterPanel The DiscoveryFilterPanel to add to this panel.
|
||||
* @param isSelected True if the checkbox should be selected, false
|
||||
* otherwise.
|
||||
* @param indicesSelected The array of indices that are selected in the
|
||||
* list, null if none are selected.
|
||||
* @param column The column to add the DiscoveryFilterPanel to.
|
||||
*/
|
||||
final synchronized void addFilter(AbstractDiscoveryFilterPanel filterPanel, boolean isSelected, int[] indicesSelected, int column) {
|
||||
if (!isInitialized) {
|
||||
constraints.gridy = 0;
|
||||
constraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||
constraints.insets = new Insets(8, 8, 8, 8);
|
||||
isInitialized = true;
|
||||
}
|
||||
if (column == 0) {
|
||||
constraints.gridy = firstColumnY;
|
||||
} else {
|
||||
constraints.gridy = secondColumnY;
|
||||
}
|
||||
constraints.gridx = 0;
|
||||
filterPanel.configurePanel(isSelected, indicesSelected);
|
||||
filterPanel.addListeners(this, this);
|
||||
filters.add(filterPanel);
|
||||
constraints.fill = GridBagConstraints.VERTICAL;
|
||||
constraints.gridheight = LABEL_HEIGHT;
|
||||
constraints.gridwidth = LABEL_WIDTH;
|
||||
constraints.weightx = LABEL_WEIGHT;
|
||||
constraints.weighty = LABEL_WEIGHT;
|
||||
constraints.gridwidth = LABEL_WIDTH;
|
||||
addToGridBagLayout(filterPanel.getCheckbox(), null, column);
|
||||
if (filterPanel.hasPanel()) {
|
||||
constraints.gridx += constraints.gridwidth;
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
constraints.gridheight = PANEL_HEIGHT;
|
||||
constraints.weightx = PANEL_WEIGHT;
|
||||
constraints.weighty = PANEL_WEIGHT;
|
||||
constraints.gridwidth = PANEL_WIDTH;
|
||||
addToGridBagLayout(filterPanel, null, column);
|
||||
}
|
||||
if (column == 0) {
|
||||
firstColumnY += constraints.gridheight;
|
||||
} else {
|
||||
secondColumnY += constraints.gridheight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the panels representing the two columns to the specified JSplitPane.
|
||||
*
|
||||
* @param splitPane The JSplitPane which the columns are added to.
|
||||
*/
|
||||
final void addPanelsToScrollPane(JSplitPane splitPane) {
|
||||
splitPane.setLeftComponent(firstColumnPanel);
|
||||
splitPane.setRightComponent(secondColumnPanel);
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the filters from the panel
|
||||
*/
|
||||
final synchronized void clearFilters() {
|
||||
for (AbstractDiscoveryFilterPanel filterPanel : filters) {
|
||||
filterPanel.removeListeners();
|
||||
}
|
||||
filters.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the constraints and add a component to one of the columns.
|
||||
*
|
||||
* @param componentToAdd The Component to add to the specified
|
||||
* column.
|
||||
* @param additionalComponentToAdd An additional Component which may appear
|
||||
* below the componentToAdd in the specified
|
||||
* column.
|
||||
* @param columnIndex The column to add the Component to.
|
||||
*/
|
||||
private void addToGridBagLayout(Component componentToAdd, Component additionalComponentToAdd, int columnIndex) {
|
||||
addToColumn(componentToAdd, columnIndex);
|
||||
if (additionalComponentToAdd != null) {
|
||||
constraints.gridy += constraints.gridheight;
|
||||
addToColumn(additionalComponentToAdd, columnIndex);
|
||||
constraints.gridy -= constraints.gridheight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the Component to the specified column with the current constraints.
|
||||
*
|
||||
* @param component The Component to add.
|
||||
* @param columnNumber The column to add the Component to.
|
||||
*/
|
||||
private void addToColumn(Component component, int columnNumber) {
|
||||
if (columnNumber == 0) {
|
||||
firstColumnPanel.add(component, constraints);
|
||||
} else {
|
||||
secondColumnPanel.add(component, constraints);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the fields are valid, and fire a property change event to
|
||||
* indicate any errors.
|
||||
*/
|
||||
synchronized void validateFields() {
|
||||
String errorString = null;
|
||||
for (AbstractDiscoveryFilterPanel filterPanel : filters) {
|
||||
errorString = filterPanel.checkForError();
|
||||
if (!StringUtils.isBlank(errorString)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
firePropertyChange("FilterError", null, errorString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
validateFields();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the Objects Detected Filter Supported.
|
||||
*
|
||||
* @return True if the ObjectsDetectedFilter is supported, false otherwise.
|
||||
*/
|
||||
boolean isObjectsFilterSupported() {
|
||||
for (AbstractDiscoveryFilterPanel filter : filters) {
|
||||
if (filter instanceof ObjectDetectedFilterPanel) {
|
||||
return filter.getList().getModel().getSize() > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the Hash Set Filter Supported.
|
||||
*
|
||||
* @return True if the HashSetFilter is supported, false otherwise.
|
||||
*/
|
||||
boolean isHashSetFilterSupported() {
|
||||
for (AbstractDiscoveryFilterPanel filter : filters) {
|
||||
if (filter instanceof HashSetFilterPanel) {
|
||||
return filter.getList().getModel().getSize() > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the Interesting Items Filter Supported.
|
||||
*
|
||||
* @return True if the InterestingItemsFilter is supported, false otherwise.
|
||||
*/
|
||||
boolean isInterestingItemsFilterSupported() {
|
||||
for (AbstractDiscoveryFilterPanel filter : filters) {
|
||||
if (filter instanceof InterestingItemsFilterPanel) {
|
||||
return filter.getList().getModel().getSize() > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all filters selected by the user.
|
||||
*
|
||||
* @return The list of filters selected by the user.
|
||||
*/
|
||||
synchronized List<FileSearchFiltering.FileFilter> getFilters() {
|
||||
List<FileSearchFiltering.FileFilter> filtersToUse = new ArrayList<>();
|
||||
filtersToUse.add(new FileSearchFiltering.FileTypeFilter(getFileType()));
|
||||
for (AbstractDiscoveryFilterPanel filterPanel : filters) {
|
||||
if (filterPanel.getCheckbox().isSelected()) {
|
||||
FileSearchFiltering.FileFilter filter = filterPanel.getFilter();
|
||||
if (filter != null) {
|
||||
filtersToUse.add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtersToUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent evt) {
|
||||
if (!evt.getValueIsAdjusting()) {
|
||||
validateFields();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+42
-8
@@ -16,7 +16,6 @@ FileSearchDialog.orderSizeRadioButton.text=Group Size
|
||||
FileSearchDialog.jLabel5.text=Order files by:
|
||||
FileSearchDialog.parentCheckBox.text=Parent
|
||||
FileSearchPanel.sortingPanel.border.title=Grouping
|
||||
FileSearchPanel.searchButton.text=Show
|
||||
FileSearchPanel.addButton.text=Add
|
||||
FileSearchPanel.substringRadioButton.text=Substring
|
||||
FileSearchPanel.fullRadioButton.text=Full
|
||||
@@ -39,7 +38,6 @@ FileSearchDialog.objCheckBox.text=Objects
|
||||
FileSearchDialog.exifCheckBox.text=Must contain EXIF data
|
||||
FileSearchDialog.notableCheckBox.text=Must have been tagged as notable
|
||||
FileSearchDialog.scoreCheckBox.text=Has score
|
||||
FileSearchPanel.cancelButton.text=Cancel
|
||||
FileSearchPanel.hashSetCheckbox.text=Hash Set:
|
||||
FileSearchPanel.tagsCheckbox.text=Tag:
|
||||
FileSearchPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||
@@ -50,20 +48,56 @@ ResultsPanel.currentPageLabel.text=Page: -
|
||||
ResultsPanel.pageControlsLabel.text=Pages:
|
||||
ResultsPanel.gotoPageLabel.text=Go to Page:
|
||||
ResultsPanel.pageSizeLabel.text=Page Size:
|
||||
ResultsPanel.instancesList.border.title=Instances
|
||||
DiscoveryExtractAction.title.extractFiles.text=Extract File
|
||||
FileSearchPanel.includeRadioButton.text=Include
|
||||
FileSearchPanel.excludeRadioButton.text=Exclude
|
||||
FileSearchPanel.knownFilesCheckbox.toolTipText=
|
||||
FileSearchPanel.knownFilesCheckbox.text=Hide known files
|
||||
GroupListPanel.groupKeyList.border.title=Groups
|
||||
DiscoveryTopComponent.imagesButton.text=Images
|
||||
DiscoveryTopComponent.videosButton.text=Videos
|
||||
ResultsPanel.resultsSplitPane.toolTipText=
|
||||
FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings
|
||||
DiscoveryTopComponent.stepOneLabel.text=Step 1: Pick File Type
|
||||
DiscoveryTopComponent.documentsButton.text=Documents
|
||||
DocumentPanel.fileSizeLabel.toolTipText=
|
||||
DocumentPanel.isDeletedLabel.toolTipText=
|
||||
ImageThumbnailPanel.isDeletedLabel.toolTipText=
|
||||
FileSearchPanel.userCreatedCheckbox.text=Possibly User Created
|
||||
DiscoveryDialog.documentsButton.text=Documents
|
||||
DiscoveryDialog.videosButton.text=Videos
|
||||
DiscoveryDialog.imagesButton.text=Images
|
||||
DiscoveryDialog.searchButton.text=Search
|
||||
DetailsPanel.instancesList.border.title=Instances
|
||||
SizeFilterPanel.sizeCheckbox.text=File Size:
|
||||
DataSourceFilterPanel.dataSourceCheckbox.text=Data Source:
|
||||
UserCreatedFilterPanel.userCreatedCheckbox.text=Possibly User Created
|
||||
# To change this license header, choose License Headers in Project Properties.
|
||||
# To change this template file, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
HashSetFilterPanel.hashSetCheckbox.text=Hash Set:
|
||||
InterestingItemFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||
ParentFolderFilterPanel.parentCheckbox.text=Parent Folder:
|
||||
ParentFolderFilterPanel.deleteButton.text=Delete
|
||||
ParentFolderFilterPanel.excludeRadioButton.text=Exclude
|
||||
ParentFolderFilterPanel.includeRadioButton.text=Include
|
||||
ParentFolderFilterPanel.substringRadioButton.text=Substring
|
||||
ParentFolderFilterPanel.fullRadioButton.text=Full
|
||||
ParentFolderFilterPanel.parentLabel.text=(All will be used)
|
||||
ParentFolderFilterPanel.addButton.text=Add
|
||||
ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder:
|
||||
ParentFolderFilterPanel.addButton.text_1=Add
|
||||
ParentFolderFilterPanel.deleteButton.text_1=Delete
|
||||
ParentFolderFilterPanel.excludeRadioButton.text_1=Exclude
|
||||
ParentFolderFilterPanel.substringRadioButton.text_1=Substring
|
||||
ParentFolderFilterPanel.includeRadioButton.text_1=Include
|
||||
ParentFolderFilterPanel.fullRadioButton.text_1=Full
|
||||
ParentFolderFilterPanel.parentLabel.text_1=(All will be used)
|
||||
InterestingItemsFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||
UserCreatedFilterPanel.userCreatedCheckbox.text_1=Possibly User Created
|
||||
PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text=Past Occurrences:
|
||||
ObjectDetectedFilterPanel.text=Object Detected:
|
||||
DiscoveryDialog.sortingPanel.border.title=Step 3: Choose display settings
|
||||
DiscoveryDialog.groupByLabel.text=Group By:
|
||||
DiscoveryDialog.orderByLabel.text=Order Within Groups By:
|
||||
DiscoveryDialog.orderGroupsByLabel.text=Order Groups By:
|
||||
ImageFilterPanel.imageFiltersSplitPane.toolTipText=
|
||||
DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which documents to show
|
||||
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
|
||||
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
|
||||
DiscoveryDialog.step1Label.text=Step 1: Choose result type
|
||||
+53
-15
@@ -1,11 +1,19 @@
|
||||
CTL_OpenFileDiscoveryAction=File Discovery
|
||||
CTL_OpenDiscoveryAction=Discovery
|
||||
# {0} - dataSourceName
|
||||
DataSourceModuleWrapper.exifModule.text=Exif Parser module was not run on data source: {0}\n
|
||||
# {0} - dataSourceName
|
||||
DataSourceModuleWrapper.fileTypeModule.text=File Type Identification module was not run on data source: {0}\n
|
||||
# {0} - dataSourceName
|
||||
DataSourceModuleWrapper.hashModule.text=Hash Lookup module was not run on data source: {0}\n
|
||||
DiscoveryTopComponent.name=\ File Discovery
|
||||
DiscoveryDialog.name.text=Discovery
|
||||
DiscoveryTopComponent.cancelButton.text=Cancel Search
|
||||
DiscoveryTopComponent.name=\ Discovery
|
||||
DiscoveryTopComponent.newSearch.text=New Search
|
||||
DiscoveryTopComponent.searchCancelled.text=Search has been cancelled.
|
||||
# {0} - search
|
||||
DiscoveryTopComponent.searchComplete.text=Results for {0}
|
||||
# {0} - searchType
|
||||
DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait.
|
||||
DiscoveryUiUtility.bytes.text=bytes
|
||||
DiscoveryUiUtility.gigaBytes.text=GB
|
||||
DiscoveryUiUtility.kiloBytes.text=KB
|
||||
@@ -137,13 +145,8 @@ FileSearchFiltering.SizeFilter.range=({0} to {1})
|
||||
FileSearchFiltering.TagsFilter.desc=Files that have been tagged {0}
|
||||
FileSearchFiltering.TagsFilter.or=\ or
|
||||
FileSearchFiltering.UserCreatedFilter.desc=Files that contain EXIF data
|
||||
FileSearchPanel.dialogTitle.text=Test file search
|
||||
FileSearchPanel.sortingPanel.border.title=Grouping
|
||||
FileSearchPanel.searchButton.text=Show
|
||||
FileSearchPanel.addButton.text=Add
|
||||
FileSearchPanel.steptwo.documents=Step 2: Filter which documents to show
|
||||
FileSearchPanel.steptwo.images=Step 2: Filter which images to show
|
||||
FileSearchPanel.steptwo.videos=Step 2: Filter which videos to show
|
||||
FileSearchPanel.substringRadioButton.text=Substring
|
||||
FileSearchPanel.fullRadioButton.text=Full
|
||||
FileSearchPanel.parentCheckbox.text=Parent Folder:
|
||||
@@ -165,7 +168,6 @@ FileSearchDialog.objCheckBox.text=Objects
|
||||
FileSearchDialog.exifCheckBox.text=Must contain EXIF data
|
||||
FileSearchDialog.notableCheckBox.text=Must have been tagged as notable
|
||||
FileSearchDialog.scoreCheckBox.text=Has score
|
||||
FileSearchPanel.cancelButton.text=Cancel
|
||||
FileSearchPanel.hashSetCheckbox.text=Hash Set:
|
||||
FileSearchPanel.tagsCheckbox.text=Tag:
|
||||
FileSearchPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||
@@ -184,7 +186,7 @@ GroupsListPanel.noResults.title.text=No results found
|
||||
ImageThumbnailPanel.isDeleted.text=All instances of file are deleted.
|
||||
# {0} - otherInstanceCount
|
||||
ImageThumbnailPanel.nameLabel.more.text=\ and {0} more
|
||||
OpenFileDiscoveryAction.resultsIncomplete.text=Results may be incomplete
|
||||
OpenDiscoveryAction.resultsIncomplete.text=Results may be incomplete
|
||||
ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.
|
||||
ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.
|
||||
ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag.
|
||||
@@ -202,25 +204,61 @@ ResultsPanel.openInExternalViewer.name=Open in External Viewer
|
||||
ResultsPanel.pageControlsLabel.text=Pages:
|
||||
ResultsPanel.gotoPageLabel.text=Go to Page:
|
||||
ResultsPanel.pageSizeLabel.text=Page Size:
|
||||
ResultsPanel.instancesList.border.title=Instances
|
||||
DiscoveryExtractAction.title.extractFiles.text=Extract File
|
||||
FileSearchPanel.includeRadioButton.text=Include
|
||||
FileSearchPanel.excludeRadioButton.text=Exclude
|
||||
FileSearchPanel.knownFilesCheckbox.toolTipText=
|
||||
FileSearchPanel.knownFilesCheckbox.text=Hide known files
|
||||
GroupListPanel.groupKeyList.border.title=Groups
|
||||
DiscoveryTopComponent.imagesButton.text=Images
|
||||
DiscoveryTopComponent.videosButton.text=Videos
|
||||
ResultsPanel.resultsSplitPane.toolTipText=
|
||||
FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings
|
||||
DiscoveryTopComponent.stepOneLabel.text=Step 1: Pick File Type
|
||||
DiscoveryTopComponent.documentsButton.text=Documents
|
||||
DocumentPanel.fileSizeLabel.toolTipText=
|
||||
DocumentPanel.isDeletedLabel.toolTipText=
|
||||
ImageThumbnailPanel.isDeletedLabel.toolTipText=
|
||||
FileSearchPanel.userCreatedCheckbox.text=Possibly User Created
|
||||
DiscoveryDialog.documentsButton.text=Documents
|
||||
DiscoveryDialog.videosButton.text=Videos
|
||||
DiscoveryDialog.imagesButton.text=Images
|
||||
DiscoveryDialog.searchButton.text=Search
|
||||
DetailsPanel.instancesList.border.title=Instances
|
||||
ResultsPanel.unableToCreate.text=Unable to create summary.
|
||||
ResultsPanel.viewFileInDir.name=View File in Directory
|
||||
SizeFilterPanel.sizeCheckbox.text=File Size:
|
||||
DataSourceFilterPanel.dataSourceCheckbox.text=Data Source:
|
||||
UserCreatedFilterPanel.userCreatedCheckbox.text=Possibly User Created
|
||||
# To change this license header, choose License Headers in Project Properties.
|
||||
# To change this template file, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
HashSetFilterPanel.hashSetCheckbox.text=Hash Set:
|
||||
InterestingItemFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||
ParentFolderFilterPanel.parentCheckbox.text=Parent Folder:
|
||||
ParentFolderFilterPanel.deleteButton.text=Delete
|
||||
ParentFolderFilterPanel.excludeRadioButton.text=Exclude
|
||||
ParentFolderFilterPanel.includeRadioButton.text=Include
|
||||
ParentFolderFilterPanel.substringRadioButton.text=Substring
|
||||
ParentFolderFilterPanel.fullRadioButton.text=Full
|
||||
ParentFolderFilterPanel.parentLabel.text=(All will be used)
|
||||
ParentFolderFilterPanel.addButton.text=Add
|
||||
ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder:
|
||||
ParentFolderFilterPanel.addButton.text_1=Add
|
||||
ParentFolderFilterPanel.deleteButton.text_1=Delete
|
||||
ParentFolderFilterPanel.excludeRadioButton.text_1=Exclude
|
||||
ParentFolderFilterPanel.substringRadioButton.text_1=Substring
|
||||
ParentFolderFilterPanel.includeRadioButton.text_1=Include
|
||||
ParentFolderFilterPanel.fullRadioButton.text_1=Full
|
||||
ParentFolderFilterPanel.parentLabel.text_1=(All will be used)
|
||||
InterestingItemsFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||
UserCreatedFilterPanel.userCreatedCheckbox.text_1=Possibly User Created
|
||||
PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text=Past Occurrences:
|
||||
ObjectDetectedFilterPanel.text=Object Detected:
|
||||
DiscoveryDialog.sortingPanel.border.title=Step 3: Choose display settings
|
||||
DiscoveryDialog.groupByLabel.text=Group By:
|
||||
DiscoveryDialog.orderByLabel.text=Order Within Groups By:
|
||||
DiscoveryDialog.orderGroupsByLabel.text=Order Groups By:
|
||||
ImageFilterPanel.imageFiltersSplitPane.toolTipText=
|
||||
DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which documents to show
|
||||
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
|
||||
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
|
||||
DiscoveryDialog.step1Label.text=Step 1: Choose result type
|
||||
VideoThumbnailPanel.bytes.text=bytes
|
||||
VideoThumbnailPanel.deleted.text=All instances of file are deleted.
|
||||
VideoThumbnailPanel.gigaBytes.text=GB
|
||||
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="dataSourceCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DataSourceFilterPanel.dataSourceCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dataSourceCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="requestFocusEnabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dataSourceScrollPane" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="dataSourceScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="dataSourceScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[27, 27]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="dataSourceList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<DataSourceItem>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="visibleRowCount" type="int" value="5"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<DataSourceItem>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A panel which displays the controls for the Data Source Filter.
|
||||
*/
|
||||
final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(DataSourceFilterPanel.class.getName());
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceFilterPanel.
|
||||
*/
|
||||
DataSourceFilterPanel() {
|
||||
initComponents();
|
||||
setUpDataSourceFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
dataSourceCheckbox = new javax.swing.JCheckBox();
|
||||
dataSourceScrollPane = new javax.swing.JScrollPane();
|
||||
dataSourceList = new javax.swing.JList<>();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dataSourceCheckbox, org.openide.util.NbBundle.getMessage(DataSourceFilterPanel.class, "DataSourceFilterPanel.dataSourceCheckbox.text")); // NOI18N
|
||||
dataSourceCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
dataSourceCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
dataSourceCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
dataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dataSourceCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
setRequestFocusEnabled(false);
|
||||
|
||||
dataSourceScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
|
||||
|
||||
dataSourceList.setModel(new DefaultListModel<DataSourceItem>());
|
||||
dataSourceList.setEnabled(false);
|
||||
dataSourceList.setVisibleRowCount(5);
|
||||
dataSourceScrollPane.setViewportView(dataSourceList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(dataSourceScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(dataSourceScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void dataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourceCheckboxActionPerformed
|
||||
dataSourceList.setEnabled(dataSourceCheckbox.isSelected());
|
||||
}//GEN-LAST:event_dataSourceCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox dataSourceCheckbox;
|
||||
private javax.swing.JList<DataSourceItem> dataSourceList;
|
||||
private javax.swing.JScrollPane dataSourceScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
dataSourceCheckbox.setSelected(selected);
|
||||
if (dataSourceCheckbox.isEnabled() && dataSourceCheckbox.isSelected()) {
|
||||
dataSourceScrollPane.setEnabled(true);
|
||||
dataSourceList.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
dataSourceList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
dataSourceScrollPane.setEnabled(false);
|
||||
dataSourceList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return dataSourceCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the data source filter.
|
||||
*/
|
||||
private void setUpDataSourceFilter() {
|
||||
int count = 0;
|
||||
try {
|
||||
DefaultListModel<DataSourceItem> dsListModel = (DefaultListModel<DataSourceItem>) dataSourceList.getModel();
|
||||
dsListModel.removeAllElements();
|
||||
for (DataSource ds : Case.getCurrentCase().getSleuthkitCase().getDataSources()) {
|
||||
dsListModel.add(count, new DataSourceItem(ds));
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error loading data sources", ex);
|
||||
dataSourceCheckbox.setEnabled(false);
|
||||
dataSourceList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return dataSourceList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to allow us to display the data source ID along with the
|
||||
* name
|
||||
*/
|
||||
private class DataSourceItem {
|
||||
|
||||
private final DataSource ds;
|
||||
|
||||
/**
|
||||
* Construct a new DataSourceItem.
|
||||
*
|
||||
* @param ds The data source being wrapped.
|
||||
*/
|
||||
DataSourceItem(DataSource ds) {
|
||||
this.ds = ds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data source represented by this data source item.
|
||||
*
|
||||
* @return The data source represented by this data source item.
|
||||
*/
|
||||
DataSource getDataSource() {
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ds.getName() + " (ID: " + ds.getId() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
if (dataSourceCheckbox.isSelected() && dataSourceList.getSelectedValuesList().isEmpty()) {
|
||||
return "At least one size must be selected";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (dataSourceCheckbox.isSelected()) {
|
||||
List<DataSource> dataSources = dataSourceList.getSelectedValuesList().stream().map(t -> t.getDataSource()).collect(Collectors.toList());
|
||||
return new FileSearchFiltering.DataSourceFilter(dataSources);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
||||
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.4" 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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="777" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="detailsSplitPane" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="402" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="detailsSplitPane" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="detailsSplitPane">
|
||||
<Properties>
|
||||
<Property name="dividerLocation" type="int" value="80"/>
|
||||
<Property name="orientation" type="int" value="0"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[200, 0]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[700, 500]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="instancesPanel">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 60]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[700, 80]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="top"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="775" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="instancesScrollPane" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="79" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="instancesScrollPane" pref="79" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="instancesScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[775, 60]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="instancesList">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Instances">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DetailsPanel.instancesList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="instancesListModel" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new InstancesCellRenderer()" type="code"/>
|
||||
</Property>
|
||||
<Property name="visibleRowCount" type="int" value="2"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<AbstractFile>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Panel to display the details of the selected result.
|
||||
*/
|
||||
final class DetailsPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final DataContentPanel dataContentPanel;
|
||||
private final DefaultListModel<AbstractFile> instancesListModel = new DefaultListModel<>();
|
||||
private final ListSelectionListener listener;
|
||||
|
||||
/**
|
||||
* Creates new form DetailsPanel.
|
||||
*/
|
||||
DetailsPanel() {
|
||||
initComponents();
|
||||
dataContentPanel = DataContentPanel.createInstance();
|
||||
detailsSplitPane.setBottomComponent(dataContentPanel);
|
||||
//Add the context menu when right clicking
|
||||
instancesList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint()));
|
||||
Set<AbstractFile> files = new HashSet<>();
|
||||
files.add(instancesList.getSelectedValue());
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
menu.add(new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue()));
|
||||
menu.add(new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(), new FileNode(instancesList.getSelectedValue())));
|
||||
menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue()));
|
||||
menu.add(new DiscoveryExtractAction(files));
|
||||
menu.add(AddContentTagAction.getInstance().getMenuForContent(files));
|
||||
menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files));
|
||||
menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files));
|
||||
menu.show(instancesList, e.getPoint().x, e.getPoint().y);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
listener = new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
AbstractFile file = getSelectedFile();
|
||||
if (file != null) {
|
||||
dataContentPanel.setNode(new TableFilterNode(new FileNode(file), false));
|
||||
} else {
|
||||
dataContentPanel.setNode(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
instancesList.addListSelectionListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the instances list in response to the clear instance selection
|
||||
* event.
|
||||
*
|
||||
* @param clearEvent The ClearInstanceSelectionEvent which has been
|
||||
* received.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleClearSelectionListener(DiscoveryEventUtils.ClearInstanceSelectionEvent clearEvent) {
|
||||
instancesList.clearSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the instances list.
|
||||
*
|
||||
* @param populateEvent The PopulateInstancesListEvent which indicates the
|
||||
* instances list should be populated
|
||||
*/
|
||||
@Subscribe
|
||||
synchronized void handlePopulateInstancesListEvent(DiscoveryEventUtils.PopulateInstancesListEvent populateEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
List<AbstractFile> files = populateEvent.getInstances();
|
||||
if (files.isEmpty()) {
|
||||
//if there are no files currently remove the current items without removing listener to cause content viewer to reset
|
||||
instancesListModel.removeAllElements();
|
||||
//send fade out event
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false));
|
||||
} else {
|
||||
//remove listener so content viewer node is not set multiple times
|
||||
instancesList.removeListSelectionListener(listener);
|
||||
instancesListModel.removeAllElements();
|
||||
for (AbstractFile file : files) {
|
||||
instancesListModel.addElement(file);
|
||||
}
|
||||
//add listener back to allow selection of first index to cause content viewer node to be set
|
||||
instancesList.addListSelectionListener(listener);
|
||||
if (!instancesListModel.isEmpty()) {
|
||||
instancesList.setSelectedIndex(0);
|
||||
}
|
||||
//send fade in event
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AbstractFile for the item currently selected in the instances
|
||||
* list.
|
||||
*
|
||||
* @return The AbstractFile which is currently selected.
|
||||
*/
|
||||
synchronized AbstractFile getSelectedFile() {
|
||||
if (instancesList.getSelectedIndex() == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return instancesListModel.getElementAt(instancesList.getSelectedIndex());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
detailsSplitPane = new javax.swing.JSplitPane();
|
||||
javax.swing.JPanel instancesPanel = new javax.swing.JPanel();
|
||||
javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane();
|
||||
instancesList = new javax.swing.JList<>();
|
||||
|
||||
detailsSplitPane.setDividerLocation(80);
|
||||
detailsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||
detailsSplitPane.setMinimumSize(new java.awt.Dimension(200, 0));
|
||||
detailsSplitPane.setPreferredSize(new java.awt.Dimension(700, 500));
|
||||
|
||||
instancesPanel.setMinimumSize(new java.awt.Dimension(0, 60));
|
||||
instancesPanel.setPreferredSize(new java.awt.Dimension(700, 80));
|
||||
|
||||
instancesScrollPane.setPreferredSize(new java.awt.Dimension(775, 60));
|
||||
|
||||
instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(DetailsPanel.class, "DetailsPanel.instancesList.border.title"))); // NOI18N
|
||||
instancesList.setModel(instancesListModel);
|
||||
instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
instancesList.setCellRenderer(new InstancesCellRenderer());
|
||||
instancesList.setVisibleRowCount(2);
|
||||
instancesScrollPane.setViewportView(instancesList);
|
||||
|
||||
javax.swing.GroupLayout instancesPanelLayout = new javax.swing.GroupLayout(instancesPanel);
|
||||
instancesPanel.setLayout(instancesPanelLayout);
|
||||
instancesPanelLayout.setHorizontalGroup(
|
||||
instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 775, Short.MAX_VALUE)
|
||||
.addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
instancesPanelLayout.setVerticalGroup(
|
||||
instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 79, Short.MAX_VALUE)
|
||||
.addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup()
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)))
|
||||
);
|
||||
|
||||
detailsSplitPane.setTopComponent(instancesPanel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 777, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 402, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JSplitPane detailsSplitPane;
|
||||
private javax.swing.JList<AbstractFile> instancesList;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Cell renderer for the instances list.
|
||||
*/
|
||||
private class InstancesCellRenderer extends DefaultListCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
String name = "";
|
||||
if (value instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) value;
|
||||
try {
|
||||
name = file.getUniquePath();
|
||||
} catch (TskCoreException ingored) {
|
||||
name = file.getParentPath() + "/" + file.getName();
|
||||
}
|
||||
|
||||
}
|
||||
setText(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[600, 300]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1000, 650]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<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,0,-35,0,0,2,-11"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="toolBarPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="First"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace pref="196" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="filler1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="step1Label" min="-2" pref="243" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="imagesButton" min="-2" pref="110" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="videosButton" min="-2" pref="110" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="documentsButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="196" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="filler1" min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="step1Label" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="videosButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="imagesButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="documentsButton" alignment="3" min="-2" pref="43" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="imagesButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/pictures-icon.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.imagesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/pictures-icon.png"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 43]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 43]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 43]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="imagesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="videosButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.videosButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
||||
</Property>
|
||||
<Property name="disabledSelectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 43]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 43]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 43]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="videosButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="documentsButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.documentsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
||||
</Property>
|
||||
<Property name="disabledSelectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="step1Label">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.step1Label.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.Box$Filler" name="filler1">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[104, 32767]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[104, 0]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[104, 0]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="displaySettingsPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Last"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="sortingPanel" pref="741" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="errorLabel" pref="575" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="65" max="-2" attributes="0"/>
|
||||
<Component id="searchButton" min="-2" pref="101" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="sortingPanel" min="-2" pref="89" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="errorLabel" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
<Component id="searchButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="searchButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.searchButton.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="searchButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="errorLabel">
|
||||
<Properties>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="0" green="0" red="ff" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="sortingPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Step 3: Choose display settings">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.sortingPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[345, 112]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="orderGroupsByLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="groupByLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="groupSortingComboBox" max="32767" attributes="0"/>
|
||||
<Component id="groupByCombobox" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="orderByLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="orderByCombobox" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" 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 min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="groupByCombobox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="groupByLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="orderByCombobox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="orderByLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="groupSortingComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="orderGroupsByLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JComboBox" name="groupByCombobox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<GroupingAttributeType>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="orderByCombobox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<SortingMethod>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="orderGroupsByLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.orderGroupsByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="orderByLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.orderByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="groupByLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.groupByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="groupSortingComboBox">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<GroupSortingAlgorithm>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import static java.awt.BorderLayout.CENTER;
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType;
|
||||
import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod;
|
||||
|
||||
/**
|
||||
* Dialog for displaying the controls and filters for configuration of a
|
||||
* Discovery search.
|
||||
*/
|
||||
final class DiscoveryDialog extends javax.swing.JDialog {
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
|
||||
Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED);
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(DiscoveryDialog.class.getName());
|
||||
private ImageFilterPanel imageFilterPanel = null;
|
||||
private VideoFilterPanel videoFilterPanel = null;
|
||||
private DocumentFilterPanel documentFilterPanel = null;
|
||||
private static final Color SELECTED_COLOR = new Color(216, 230, 242);
|
||||
private static final Color UNSELECTED_COLOR = new Color(240, 240, 240);
|
||||
private SearchWorker searchWorker = null;
|
||||
private static DiscoveryDialog discDialog;
|
||||
private FileSearchData.FileType fileType = FileSearchData.FileType.IMAGE;
|
||||
private final PropertyChangeListener listener;
|
||||
|
||||
/**
|
||||
* Get the Discovery dialog instance.
|
||||
*
|
||||
* @return The instance of the Discovery Dialog.
|
||||
*/
|
||||
static synchronized DiscoveryDialog getDiscoveryDialogInstance() {
|
||||
if (discDialog == null) {
|
||||
discDialog = new DiscoveryDialog();
|
||||
}
|
||||
return discDialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor to construct a new DiscoveryDialog
|
||||
*/
|
||||
@Messages("DiscoveryDialog.name.text=Discovery")
|
||||
private DiscoveryDialog() {
|
||||
super(WindowManager.getDefault().getMainWindow(), Bundle.DiscoveryDialog_name_text(), true);
|
||||
initComponents();
|
||||
listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals("FilterError") && evt.getNewValue() != null) {
|
||||
setValid(evt.getNewValue().toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
for (GroupSortingAlgorithm groupSortAlgorithm : GroupSortingAlgorithm.values()) {
|
||||
groupSortingComboBox.addItem(groupSortAlgorithm);
|
||||
}
|
||||
updateSearchSettings();
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the search settings to a default state.
|
||||
*/
|
||||
void updateSearchSettings() {
|
||||
removeAllPanels();
|
||||
imageFilterPanel = null;
|
||||
videoFilterPanel = null;
|
||||
documentFilterPanel = null;
|
||||
imageFilterPanel = new ImageFilterPanel();
|
||||
videoFilterPanel = new VideoFilterPanel();
|
||||
documentFilterPanel = new DocumentFilterPanel();
|
||||
imagesButton.setSelected(true);
|
||||
imagesButton.setEnabled(false);
|
||||
imagesButton.setBackground(SELECTED_COLOR);
|
||||
imagesButton.setForeground(Color.BLACK);
|
||||
videosButton.setSelected(false);
|
||||
videosButton.setEnabled(true);
|
||||
videosButton.setBackground(UNSELECTED_COLOR);
|
||||
documentsButton.setSelected(false);
|
||||
documentsButton.setEnabled(true);
|
||||
documentsButton.setBackground(UNSELECTED_COLOR);
|
||||
fileType = FileSearchData.FileType.IMAGE;
|
||||
add(imageFilterPanel, CENTER);
|
||||
imageFilterPanel.addPropertyChangeListener(listener);
|
||||
updateComboBoxes();
|
||||
pack();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper method to perform update of comboboxes update.
|
||||
*/
|
||||
private void updateComboBoxes() {
|
||||
groupByCombobox.removeAllItems();
|
||||
// Set up the grouping attributes
|
||||
for (FileSearch.GroupingAttributeType type : FileSearch.GroupingAttributeType.getOptionsForGrouping()) {
|
||||
addTypeToGroupByComboBox(type);
|
||||
}
|
||||
orderByCombobox.removeAllItems();
|
||||
// Set up the file order list
|
||||
for (FileSorter.SortingMethod method : FileSorter.SortingMethod.getOptionsForOrdering()) {
|
||||
if (method != SortingMethod.BY_FREQUENCY || CentralRepository.isEnabled()) {
|
||||
orderByCombobox.addItem(method);
|
||||
}
|
||||
}
|
||||
groupSortingComboBox.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper method to add GroupingAttributeType to the
|
||||
* groupByCombobox.
|
||||
*
|
||||
* @param type The Type of GroupingAttribute to add.
|
||||
*/
|
||||
private void addTypeToGroupByComboBox(GroupingAttributeType type) {
|
||||
switch (type) {
|
||||
case FREQUENCY:
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case OBJECT_DETECTED:
|
||||
if (!imageFilterPanel.isObjectsFilterSupported()) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case INTERESTING_ITEM_SET:
|
||||
if (!imageFilterPanel.isInterestingItemsFilterSupported()) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case HASH_LIST_NAME:
|
||||
if (!imageFilterPanel.isHashSetFilterSupported()) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
groupByCombobox.addItem(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the current filter settings of the selected type.
|
||||
*/
|
||||
synchronized void validateDialog() {
|
||||
switch (fileType) {
|
||||
case IMAGE:
|
||||
if (imageFilterPanel != null) {
|
||||
imageFilterPanel.validateFields();
|
||||
}
|
||||
return;
|
||||
case VIDEO:
|
||||
if (videoFilterPanel != null) {
|
||||
videoFilterPanel.validateFields();
|
||||
}
|
||||
return;
|
||||
case DOCUMENTS:
|
||||
if (documentFilterPanel != null) {
|
||||
documentFilterPanel.validateFields();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
javax.swing.JPanel toolBarPanel = new javax.swing.JPanel();
|
||||
imagesButton = new javax.swing.JButton();
|
||||
videosButton = new javax.swing.JButton();
|
||||
documentsButton = new javax.swing.JButton();
|
||||
javax.swing.JLabel step1Label = new javax.swing.JLabel();
|
||||
javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(104, 0), new java.awt.Dimension(104, 0), new java.awt.Dimension(104, 32767));
|
||||
javax.swing.JPanel displaySettingsPanel = new javax.swing.JPanel();
|
||||
searchButton = new javax.swing.JButton();
|
||||
errorLabel = new javax.swing.JLabel();
|
||||
javax.swing.JPanel sortingPanel = new javax.swing.JPanel();
|
||||
groupByCombobox = new javax.swing.JComboBox<>();
|
||||
orderByCombobox = new javax.swing.JComboBox<>();
|
||||
javax.swing.JLabel orderGroupsByLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel orderByLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel groupByLabel = new javax.swing.JLabel();
|
||||
groupSortingComboBox = new javax.swing.JComboBox<>();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setMinimumSize(new java.awt.Dimension(600, 300));
|
||||
setPreferredSize(new java.awt.Dimension(1000, 650));
|
||||
|
||||
imagesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/pictures-icon.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(imagesButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.imagesButton.text")); // NOI18N
|
||||
imagesButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/pictures-icon.png"))); // NOI18N
|
||||
imagesButton.setFocusable(false);
|
||||
imagesButton.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
imagesButton.setMaximumSize(new java.awt.Dimension(90, 43));
|
||||
imagesButton.setMinimumSize(new java.awt.Dimension(90, 43));
|
||||
imagesButton.setPreferredSize(new java.awt.Dimension(90, 43));
|
||||
imagesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
imagesButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
videosButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/video-icon.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(videosButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.videosButton.text")); // NOI18N
|
||||
videosButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/video-icon.png"))); // NOI18N
|
||||
videosButton.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/video-icon.png"))); // NOI18N
|
||||
videosButton.setFocusable(false);
|
||||
videosButton.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
videosButton.setMaximumSize(new java.awt.Dimension(90, 43));
|
||||
videosButton.setMinimumSize(new java.awt.Dimension(90, 43));
|
||||
videosButton.setPreferredSize(new java.awt.Dimension(90, 43));
|
||||
videosButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
videosButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
documentsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/documents-icon.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(documentsButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.documentsButton.text")); // NOI18N
|
||||
documentsButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/documents-icon.png"))); // NOI18N
|
||||
documentsButton.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/documents-icon.png"))); // NOI18N
|
||||
documentsButton.setFocusable(false);
|
||||
documentsButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
documentsButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(step1Label, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.step1Label.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout toolBarPanelLayout = new javax.swing.GroupLayout(toolBarPanel);
|
||||
toolBarPanel.setLayout(toolBarPanelLayout);
|
||||
toolBarPanelLayout.setHorizontalGroup(
|
||||
toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(toolBarPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(196, Short.MAX_VALUE)
|
||||
.addGroup(toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, toolBarPanelLayout.createSequentialGroup()
|
||||
.addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(step1Label, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(toolBarPanelLayout.createSequentialGroup()
|
||||
.addComponent(imagesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(videosButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(documentsButton)))
|
||||
.addContainerGap(196, Short.MAX_VALUE))
|
||||
);
|
||||
toolBarPanelLayout.setVerticalGroup(
|
||||
toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(toolBarPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(step1Label))
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(videosButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(imagesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(documentsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
getContentPane().add(toolBarPanel, java.awt.BorderLayout.PAGE_START);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.searchButton.text")); // NOI18N
|
||||
searchButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
searchButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
errorLabel.setForeground(new java.awt.Color(255, 0, 0));
|
||||
|
||||
sortingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.sortingPanel.border.title"))); // NOI18N
|
||||
sortingPanel.setPreferredSize(new java.awt.Dimension(345, 112));
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(orderGroupsByLabel, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.orderGroupsByLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(orderByLabel, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.orderByLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(groupByLabel, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.groupByLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout sortingPanelLayout = new javax.swing.GroupLayout(sortingPanel);
|
||||
sortingPanel.setLayout(sortingPanelLayout);
|
||||
sortingPanelLayout.setHorizontalGroup(
|
||||
sortingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(sortingPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(sortingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(orderGroupsByLabel)
|
||||
.addComponent(groupByLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(sortingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(groupSortingComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(groupByCombobox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(orderByLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(orderByCombobox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
sortingPanelLayout.setVerticalGroup(
|
||||
sortingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(sortingPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(sortingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(groupByCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(groupByLabel)
|
||||
.addComponent(orderByCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(orderByLabel))
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(sortingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(groupSortingComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(orderGroupsByLabel))
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout displaySettingsPanelLayout = new javax.swing.GroupLayout(displaySettingsPanel);
|
||||
displaySettingsPanel.setLayout(displaySettingsPanelLayout);
|
||||
displaySettingsPanelLayout.setHorizontalGroup(
|
||||
displaySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, displaySettingsPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(displaySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(sortingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 741, Short.MAX_VALUE)
|
||||
.addGroup(displaySettingsPanelLayout.createSequentialGroup()
|
||||
.addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 575, Short.MAX_VALUE)
|
||||
.addGap(65, 65, 65)
|
||||
.addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
displaySettingsPanelLayout.setVerticalGroup(
|
||||
displaySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, displaySettingsPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(sortingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(displaySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(errorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(searchButton))
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
getContentPane().add(displaySettingsPanel, java.awt.BorderLayout.PAGE_END);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void imagesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_imagesButtonActionPerformed
|
||||
removeAllPanels();
|
||||
add(imageFilterPanel, CENTER);
|
||||
imagesButton.setSelected(true);
|
||||
imagesButton.setEnabled(false);
|
||||
imagesButton.setBackground(SELECTED_COLOR);
|
||||
imagesButton.setForeground(Color.BLACK);
|
||||
videosButton.setSelected(false);
|
||||
videosButton.setEnabled(true);
|
||||
videosButton.setBackground(UNSELECTED_COLOR);
|
||||
documentsButton.setSelected(false);
|
||||
documentsButton.setEnabled(true);
|
||||
documentsButton.setBackground(UNSELECTED_COLOR);
|
||||
fileType = FileSearchData.FileType.IMAGE;
|
||||
imageFilterPanel.addPropertyChangeListener(listener);
|
||||
validateDialog();
|
||||
pack();
|
||||
repaint();
|
||||
}//GEN-LAST:event_imagesButtonActionPerformed
|
||||
|
||||
private void videosButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_videosButtonActionPerformed
|
||||
removeAllPanels();
|
||||
add(videoFilterPanel, CENTER);
|
||||
imagesButton.setSelected(false);
|
||||
imagesButton.setEnabled(true);
|
||||
imagesButton.setBackground(UNSELECTED_COLOR);
|
||||
videosButton.setSelected(true);
|
||||
videosButton.setEnabled(false);
|
||||
videosButton.setBackground(SELECTED_COLOR);
|
||||
videosButton.setForeground(Color.BLACK);
|
||||
documentsButton.setSelected(false);
|
||||
documentsButton.setEnabled(true);
|
||||
documentsButton.setBackground(UNSELECTED_COLOR);
|
||||
videoFilterPanel.addPropertyChangeListener(listener);
|
||||
fileType = FileSearchData.FileType.VIDEO;
|
||||
validateDialog();
|
||||
pack();
|
||||
repaint();
|
||||
}//GEN-LAST:event_videosButtonActionPerformed
|
||||
|
||||
private void documentsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsButtonActionPerformed
|
||||
removeAllPanels();
|
||||
add(documentFilterPanel, CENTER);
|
||||
documentsButton.setSelected(true);
|
||||
documentsButton.setEnabled(false);
|
||||
documentsButton.setBackground(SELECTED_COLOR);
|
||||
documentsButton.setForeground(Color.BLACK);
|
||||
videosButton.setSelected(false);
|
||||
videosButton.setEnabled(true);
|
||||
videosButton.setBackground(UNSELECTED_COLOR);
|
||||
imagesButton.setSelected(false);
|
||||
imagesButton.setEnabled(true);
|
||||
imagesButton.setBackground(UNSELECTED_COLOR);
|
||||
fileType = FileSearchData.FileType.DOCUMENTS;
|
||||
documentFilterPanel.addPropertyChangeListener(listener);
|
||||
validateDialog();
|
||||
pack();
|
||||
repaint();
|
||||
}//GEN-LAST:event_documentsButtonActionPerformed
|
||||
|
||||
/**
|
||||
* Helper method to remove all filter panels and their listeners
|
||||
*/
|
||||
private void removeAllPanels() {
|
||||
if (imageFilterPanel != null) {
|
||||
remove(imageFilterPanel);
|
||||
imageFilterPanel.removePropertyChangeListener(listener);
|
||||
}
|
||||
if (documentFilterPanel != null) {
|
||||
remove(documentFilterPanel);
|
||||
documentFilterPanel.removePropertyChangeListener(listener);
|
||||
}
|
||||
if (videoFilterPanel != null) {
|
||||
remove(videoFilterPanel);
|
||||
videoFilterPanel.removePropertyChangeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
|
||||
// Get the selected filters
|
||||
final DiscoveryTopComponent tc = DiscoveryTopComponent.getTopComponent();
|
||||
if (tc == null) {
|
||||
setValid("No Top Component Found");
|
||||
return;
|
||||
}
|
||||
if (tc.isOpened() == false) {
|
||||
tc.open();
|
||||
}
|
||||
tc.resetTopComponent();
|
||||
List<FileSearchFiltering.FileFilter> filters;
|
||||
if (videosButton.isSelected()) {
|
||||
filters = videoFilterPanel.getFilters();
|
||||
} else if (documentsButton.isSelected()) {
|
||||
filters = documentFilterPanel.getFilters();
|
||||
} else {
|
||||
filters = imageFilterPanel.getFilters();
|
||||
}
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.SearchStartedEvent(fileType));
|
||||
|
||||
// Get the grouping attribute and group sorting method
|
||||
FileSearch.AttributeType groupingAttr = groupByCombobox.getItemAt(groupByCombobox.getSelectedIndex()).getAttributeType();
|
||||
FileGroup.GroupSortingAlgorithm groupSortAlgorithm = groupSortingComboBox.getItemAt(groupSortingComboBox.getSelectedIndex());
|
||||
|
||||
// Get the file sorting method
|
||||
FileSorter.SortingMethod fileSort = (FileSorter.SortingMethod) orderByCombobox.getSelectedItem();
|
||||
CentralRepository centralRepoDb = null;
|
||||
if (CentralRepository.isEnabled()) {
|
||||
try {
|
||||
centralRepoDb = CentralRepository.getInstance();
|
||||
} catch (CentralRepoException ex) {
|
||||
centralRepoDb = null;
|
||||
logger.log(Level.SEVERE, "Error loading central repository database, no central repository options will be available for Discovery", ex);
|
||||
}
|
||||
}
|
||||
searchWorker = new SearchWorker(centralRepoDb, filters, groupingAttr, groupSortAlgorithm, fileSort);
|
||||
searchWorker.execute();
|
||||
dispose();
|
||||
tc.toFront();
|
||||
tc.requestActive();
|
||||
}//GEN-LAST:event_searchButtonActionPerformed
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the searchWorker if it exists.
|
||||
*/
|
||||
void cancelSearch() {
|
||||
if (searchWorker != null) {
|
||||
searchWorker.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The adjust the controls to reflect whether the settings are valid based
|
||||
* on the error.
|
||||
*
|
||||
* @param error The error message to display, empty string if there is no error.
|
||||
*/
|
||||
private void setValid(String error) {
|
||||
if (StringUtils.isBlank(error)) {
|
||||
errorLabel.setText("");
|
||||
searchButton.setEnabled(true);
|
||||
} else {
|
||||
errorLabel.setText(error);
|
||||
searchButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton documentsButton;
|
||||
private javax.swing.JLabel errorLabel;
|
||||
private javax.swing.JComboBox<GroupingAttributeType> groupByCombobox;
|
||||
private javax.swing.JComboBox<GroupSortingAlgorithm> groupSortingComboBox;
|
||||
private javax.swing.JButton imagesButton;
|
||||
private javax.swing.JComboBox<SortingMethod> orderByCombobox;
|
||||
private javax.swing.JButton searchButton;
|
||||
private javax.swing.JButton videosButton;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* PropertyChangeListener to listen to case level events that may modify the
|
||||
* filters available.
|
||||
*/
|
||||
private class CasePropertyChangeListener implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("fallthrough")
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
switch (Case.Events.valueOf(evt.getPropertyName())) {
|
||||
case CURRENT_CASE: {
|
||||
if (evt.getNewValue() == null) {
|
||||
//do not refresh when a case is closed only when it is opened.
|
||||
break;
|
||||
}
|
||||
//else fallthrough
|
||||
}
|
||||
case DATA_SOURCE_ADDED:
|
||||
//fallthrough
|
||||
case DATA_SOURCE_DELETED:
|
||||
updateSearchSettings();
|
||||
break;
|
||||
default:
|
||||
//do nothing if the event is not one of the above events.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -16,32 +16,37 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Class to handle event bus and events for file discovery tool.
|
||||
* Class to handle event bus and events for discovery tool.
|
||||
*/
|
||||
final class DiscoveryEventUtils {
|
||||
|
||||
private final static EventBus discoveryEventBus = new EventBus();
|
||||
|
||||
/**
|
||||
* Get the file discovery event bus.
|
||||
* Get the discovery event bus.
|
||||
*
|
||||
* @return The file discovery event bus.
|
||||
* @return The discovery event bus.
|
||||
*/
|
||||
static EventBus getDiscoveryEventBus() {
|
||||
return discoveryEventBus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private no arg constructor for Utility class.
|
||||
*/
|
||||
private DiscoveryEventUtils() {
|
||||
//Utility class private constructor intentionally left blank.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +75,41 @@ final class DiscoveryEventUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to signal that the Instances list should have selection cleared.
|
||||
*/
|
||||
static final class ClearInstanceSelectionEvent {
|
||||
|
||||
/**
|
||||
* Construct a new ClearInstanceSelectionEvent.
|
||||
*/
|
||||
ClearInstanceSelectionEvent() {
|
||||
//no arg constructor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to signal that the Instances list should be populated.
|
||||
*/
|
||||
static final class PopulateInstancesListEvent {
|
||||
|
||||
private final List<AbstractFile> instances;
|
||||
|
||||
/**
|
||||
* Construct a new PopulateInstancesListEvent.
|
||||
*/
|
||||
PopulateInstancesListEvent(List<AbstractFile> files) {
|
||||
instances = files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the instances
|
||||
*/
|
||||
List<AbstractFile> getInstances() {
|
||||
return Collections.unmodifiableList(instances);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to signal the completion of a search being performed.
|
||||
*/
|
||||
@@ -332,4 +372,32 @@ final class DiscoveryEventUtils {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to signal that the visibility of the Details area should change.
|
||||
*/
|
||||
static class DetailsVisibleEvent {
|
||||
|
||||
private final boolean showDetailsArea;
|
||||
|
||||
/**
|
||||
* Construct a new DetailsVisibleEvent.
|
||||
*
|
||||
* @param isVisible True if the details area should be visible, false
|
||||
* otherwise.
|
||||
*/
|
||||
DetailsVisibleEvent(boolean isVisible) {
|
||||
showDetailsArea = isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visibility of the Details area.
|
||||
*
|
||||
* @return True if the details area should be visible, false otherwise.
|
||||
*/
|
||||
boolean isShowDetailsArea() {
|
||||
return showDetailsArea;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import org.sleuthkit.autopsy.directorytree.actionhelpers.ExtractActionHelper;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -29,7 +29,7 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
/**
|
||||
* Extracts AbstractFiles to a location selected by the user.
|
||||
*/
|
||||
public final class DiscoveryExtractAction extends AbstractAction {
|
||||
final class DiscoveryExtractAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Collection<AbstractFile> files = new HashSet<>();
|
||||
@@ -40,7 +40,7 @@ public final class DiscoveryExtractAction extends AbstractAction {
|
||||
*
|
||||
* @param selectedFiles The files to extract from the current case.
|
||||
*/
|
||||
public DiscoveryExtractAction(Collection<AbstractFile> selectedFiles) {
|
||||
DiscoveryExtractAction(Collection<AbstractFile> selectedFiles) {
|
||||
super(NbBundle.getMessage(DiscoveryExtractAction.class, "DiscoveryExtractAction.title.extractFiles.text"));
|
||||
files.addAll(selectedFiles);
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[199, 200]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1100, 700]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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,2,-68,0,0,4,76"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="mainSplitPane">
|
||||
<Properties>
|
||||
<Property name="dividerLocation" type="int" value="250"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1100, 700]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="rightSplitPane">
|
||||
<Properties>
|
||||
<Property name="dividerSize" type="int" value="15"/>
|
||||
<Property name="orientation" type="int" value="0"/>
|
||||
<Property name="resizeWeight" type="double" value="1.0"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[800, 700]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new AnimatedSplitPane()"/>
|
||||
</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>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="searchDetailsPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="First"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="newSearchButton" min="-2" pref="110" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="progressMessageScrollPane" pref="954" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="progressMessageScrollPane" min="-2" pref="44" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
|
||||
<Component id="newSearchButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="newSearchButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="FileSearchDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[110, 26]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[110, 26]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[110, 26]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newSearchButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="progressMessageScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="progressMessageTextArea">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="2"/>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2019-2020 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.discovery;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JSplitPane;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.Mode;
|
||||
import org.openide.windows.RetainLocation;
|
||||
import org.openide.windows.TopComponent;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchFiltering.FileFilter;
|
||||
|
||||
/**
|
||||
* Create a dialog for displaying the Discovery results.
|
||||
*/
|
||||
@TopComponent.Description(preferredID = "DiscoveryTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||
@TopComponent.Registration(mode = "discovery", openAtStartup = false)
|
||||
@RetainLocation("discovery")
|
||||
@NbBundle.Messages("DiscoveryTopComponent.name= Discovery")
|
||||
public final class DiscoveryTopComponent extends TopComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String PREFERRED_ID = "DiscoveryTopComponent"; // NON-NLS
|
||||
private final GroupListPanel groupListPanel;
|
||||
private final DetailsPanel detailsPanel;
|
||||
private final ResultsPanel resultsPanel;
|
||||
private int dividerLocation = -1;
|
||||
|
||||
private static final int ANIMATION_INCREMENT = 10;
|
||||
private static final int RESULTS_AREA_SMALL_SIZE = 250;
|
||||
|
||||
private SwingAnimator animator = null;
|
||||
|
||||
/**
|
||||
* Creates new form DiscoveryTopComponent.
|
||||
*/
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
public DiscoveryTopComponent() {
|
||||
initComponents();
|
||||
setName(Bundle.DiscoveryTopComponent_name());
|
||||
groupListPanel = new GroupListPanel();
|
||||
resultsPanel = new ResultsPanel();
|
||||
detailsPanel = new DetailsPanel();
|
||||
mainSplitPane.setLeftComponent(groupListPanel);
|
||||
rightSplitPane.setTopComponent(resultsPanel);
|
||||
rightSplitPane.setBottomComponent(detailsPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current DiscoveryTopComponent if it is open.
|
||||
*
|
||||
* @return The open DiscoveryTopComponent or null if it has not been opened.
|
||||
*/
|
||||
public static DiscoveryTopComponent getTopComponent() {
|
||||
return (DiscoveryTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the top component so it isn't displaying any results.
|
||||
*/
|
||||
public void resetTopComponent() {
|
||||
resultsPanel.resetResultViewer();
|
||||
groupListPanel.resetGroupList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentOpened() {
|
||||
super.componentOpened();
|
||||
WindowManager.getDefault().setTopComponentFloating(this, true);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(this);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(resultsPanel);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(groupListPanel);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(detailsPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void componentClosed() {
|
||||
DiscoveryDialog.getDiscoveryDialogInstance().cancelSearch();
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().unregister(this);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel);
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().unregister(detailsPanel);
|
||||
super.componentClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
mainSplitPane = new javax.swing.JSplitPane();
|
||||
rightSplitPane = new AnimatedSplitPane();
|
||||
javax.swing.JPanel searchDetailsPanel = new javax.swing.JPanel();
|
||||
newSearchButton = new javax.swing.JButton();
|
||||
javax.swing.JScrollPane progressMessageScrollPane = new javax.swing.JScrollPane();
|
||||
progressMessageTextArea = new javax.swing.JTextArea();
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(199, 200));
|
||||
setPreferredSize(new java.awt.Dimension(1100, 700));
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
mainSplitPane.setDividerLocation(250);
|
||||
mainSplitPane.setPreferredSize(new java.awt.Dimension(1100, 700));
|
||||
|
||||
rightSplitPane.setDividerSize(15);
|
||||
rightSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||
rightSplitPane.setResizeWeight(1.0);
|
||||
rightSplitPane.setPreferredSize(new java.awt.Dimension(800, 700));
|
||||
mainSplitPane.setRightComponent(rightSplitPane);
|
||||
|
||||
add(mainSplitPane, java.awt.BorderLayout.CENTER);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(newSearchButton, org.openide.util.NbBundle.getMessage(DiscoveryTopComponent.class, "FileSearchDialog.cancelButton.text")); // NOI18N
|
||||
newSearchButton.setMaximumSize(new java.awt.Dimension(110, 26));
|
||||
newSearchButton.setMinimumSize(new java.awt.Dimension(110, 26));
|
||||
newSearchButton.setPreferredSize(new java.awt.Dimension(110, 26));
|
||||
newSearchButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
newSearchButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
progressMessageScrollPane.setBorder(null);
|
||||
|
||||
progressMessageTextArea.setBackground(new java.awt.Color(240, 240, 240));
|
||||
progressMessageTextArea.setColumns(20);
|
||||
progressMessageTextArea.setLineWrap(true);
|
||||
progressMessageTextArea.setRows(2);
|
||||
progressMessageTextArea.setWrapStyleWord(true);
|
||||
progressMessageTextArea.setBorder(null);
|
||||
progressMessageScrollPane.setViewportView(progressMessageTextArea);
|
||||
|
||||
javax.swing.GroupLayout searchDetailsPanelLayout = new javax.swing.GroupLayout(searchDetailsPanel);
|
||||
searchDetailsPanel.setLayout(searchDetailsPanelLayout);
|
||||
searchDetailsPanelLayout.setHorizontalGroup(
|
||||
searchDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(searchDetailsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(newSearchButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(progressMessageScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 954, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
searchDetailsPanelLayout.setVerticalGroup(
|
||||
searchDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(searchDetailsPanelLayout.createSequentialGroup()
|
||||
.addGroup(searchDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(searchDetailsPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(progressMessageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(searchDetailsPanelLayout.createSequentialGroup()
|
||||
.addGap(17, 17, 17)
|
||||
.addComponent(newSearchButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
add(searchDetailsPanel, java.awt.BorderLayout.PAGE_START);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void newSearchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newSearchButtonActionPerformed
|
||||
close();
|
||||
final DiscoveryDialog discDialog = DiscoveryDialog.getDiscoveryDialogInstance();
|
||||
discDialog.cancelSearch();
|
||||
discDialog.setVisible(true);
|
||||
discDialog.validateDialog();
|
||||
}//GEN-LAST:event_newSearchButtonActionPerformed
|
||||
|
||||
@Override
|
||||
public List<Mode> availableModes(List<Mode> modes) {
|
||||
/*
|
||||
* This looks like the right thing to do, but online discussions seems
|
||||
* to indicate this method is effectively deprecated. A break point
|
||||
* placed here was never hit.
|
||||
*/
|
||||
return modes.stream().filter(mode -> mode.getName().equals("discovery"))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the DetailsVisible event and animate the panel as it changes
|
||||
* visibility.
|
||||
*
|
||||
* @param detailsVisibleEvent The DetailsVisibleEvent which indicates if the
|
||||
* panel should be made visible or hidden.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleDetailsVisibleEvent(DiscoveryEventUtils.DetailsVisibleEvent detailsVisibleEvent) {
|
||||
if (animator != null && animator.isRunning()) {
|
||||
animator.stop();
|
||||
}
|
||||
dividerLocation = rightSplitPane.getDividerLocation();
|
||||
if (detailsVisibleEvent.isShowDetailsArea()) {
|
||||
animator = new SwingAnimator(new ShowDetailsAreaCallback());
|
||||
} else {
|
||||
animator = new SwingAnimator(new HideDetailsAreaCallback());
|
||||
}
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the SearchStartedEvent for updating the UI accordingly.
|
||||
*
|
||||
* @param searchStartedEvent The event which indicates the start of a
|
||||
* search.
|
||||
*/
|
||||
@Messages({"DiscoveryTopComponent.cancelButton.text=Cancel Search",
|
||||
"# {0} - searchType",
|
||||
"DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait."})
|
||||
@Subscribe
|
||||
void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
|
||||
newSearchButton.setText(Bundle.DiscoveryTopComponent_cancelButton_text());
|
||||
progressMessageTextArea.setForeground(Color.red);
|
||||
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchInProgress_text(searchStartedEvent.getType().name()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the SearchCompleteEvent for updating the UI accordingly.
|
||||
*
|
||||
* @param searchCompleteEvent The event which indicates the completion of a
|
||||
* search.
|
||||
*/
|
||||
@Subscribe
|
||||
@Messages({"DiscoveryTopComponent.newSearch.text=New Search",
|
||||
"# {0} - search",
|
||||
"DiscoveryTopComponent.searchComplete.text=Results for {0}"})
|
||||
void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
|
||||
newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text());
|
||||
progressMessageTextArea.setForeground(Color.black);
|
||||
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(searchCompleteEvent.getFilters().stream().map(FileFilter::getDesc).collect(Collectors.joining(", "))));
|
||||
progressMessageTextArea.setCaretPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the SearchCancelledEvent for updating the UI accordingly.
|
||||
*
|
||||
* @param searchCancelledEvent The event which indicates the cancellation of
|
||||
* a search.
|
||||
*/
|
||||
@Messages({"DiscoveryTopComponent.searchCancelled.text=Search has been cancelled."})
|
||||
@Subscribe
|
||||
void handleSearchCancelledEvent(DiscoveryEventUtils.SearchCancelledEvent searchCancelledEvent) {
|
||||
newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text());
|
||||
progressMessageTextArea.setForeground(Color.red);
|
||||
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchCancelled_text());
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for animating the details area into a visible position.
|
||||
*/
|
||||
private final class ShowDetailsAreaCallback implements SwingAnimatorCallback {
|
||||
|
||||
@Override
|
||||
public void callback(Object caller) {
|
||||
dividerLocation -= ANIMATION_INCREMENT;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTerminated() {
|
||||
if (dividerLocation != JSplitPane.UNDEFINED_CONDITION && dividerLocation < RESULTS_AREA_SMALL_SIZE) {
|
||||
dividerLocation = RESULTS_AREA_SMALL_SIZE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for animating the details area into a hidden position.
|
||||
*/
|
||||
private final class HideDetailsAreaCallback implements SwingAnimatorCallback {
|
||||
|
||||
@Override
|
||||
public void callback(Object caller) {
|
||||
dividerLocation += ANIMATION_INCREMENT;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTerminated() {
|
||||
if (dividerLocation > rightSplitPane.getHeight() || dividerLocation == JSplitPane.UNDEFINED_CONDITION) {
|
||||
dividerLocation = rightSplitPane.getHeight();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JSplitPane mainSplitPane;
|
||||
private javax.swing.JButton newSearchButton;
|
||||
private javax.swing.JTextArea progressMessageTextArea;
|
||||
private javax.swing.JSplitPane rightSplitPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Class for the split pane which will be animated.
|
||||
*/
|
||||
private final class AnimatedSplitPane extends JSplitPane {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
if ((dividerLocation == JSplitPane.UNDEFINED_CONDITION) || (dividerLocation <= rightSplitPane.getHeight() && dividerLocation >= RESULTS_AREA_SMALL_SIZE)) {
|
||||
rightSplitPane.setDividerLocation(dividerLocation);
|
||||
}
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+77
-2
@@ -16,20 +16,37 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.openide.util.ImageUtilities;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Utility class for the various user interface elements used by File Discovery.
|
||||
* Utility class for the various user interface elements used by Discovery.
|
||||
*/
|
||||
final class DiscoveryUiUtils {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(DiscoveryUiUtils.class.getName());
|
||||
private static final int BYTE_UNIT_CONVERSION = 1000;
|
||||
private static final int ICON_SIZE = 16;
|
||||
private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png";
|
||||
@@ -95,6 +112,35 @@ final class DiscoveryUiUtils {
|
||||
return UNSUPPORTED_DOCUMENT_THUMBNAIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of the sets which exist in the case database for the
|
||||
* specified artifact and attribute types.
|
||||
*
|
||||
* @param artifactType The artifact type to get the list of sets for.
|
||||
* @param setNameAttribute The attribute type which contains the set names.
|
||||
*
|
||||
* @return A list of set names which exist in the case for the specified
|
||||
* artifact and attribute types.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
static List<String> getSetNames(BlackboardArtifact.ARTIFACT_TYPE artifactType, BlackboardAttribute.ATTRIBUTE_TYPE setNameAttribute) throws TskCoreException {
|
||||
List<BlackboardArtifact> arts = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(artifactType);
|
||||
List<String> setNames = new ArrayList<>();
|
||||
for (BlackboardArtifact art : arts) {
|
||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
||||
if (attr.getAttributeType().getTypeID() == setNameAttribute.getTypeID()) {
|
||||
String setName = attr.getValueString();
|
||||
if (!setNames.contains(setName)) {
|
||||
setNames.add(setName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(setNames);
|
||||
return setNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to see if point is on the icon.
|
||||
*
|
||||
@@ -157,6 +203,35 @@ final class DiscoveryUiUtils {
|
||||
return ICON_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to display an error message when the results of the
|
||||
* Discovery Top component may be incomplete.
|
||||
*/
|
||||
static void displayErrorMessage(DiscoveryDialog dialog) {
|
||||
//check if modules run and assemble message
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
Map<Long, DataSourceModulesWrapper> dataSourceIngestModules = new HashMap<>();
|
||||
for (DataSource dataSource : skCase.getDataSources()) {
|
||||
dataSourceIngestModules.put(dataSource.getId(), new DataSourceModulesWrapper(dataSource.getName()));
|
||||
}
|
||||
|
||||
for (IngestJobInfo jobInfo : skCase.getIngestJobs()) {
|
||||
dataSourceIngestModules.get(jobInfo.getObjectId()).updateModulesRun(jobInfo);
|
||||
}
|
||||
String message = "";
|
||||
for (DataSourceModulesWrapper dsmodulesWrapper : dataSourceIngestModules.values()) {
|
||||
message += dsmodulesWrapper.getMessage();
|
||||
}
|
||||
if (!message.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(dialog, message, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex);
|
||||
}
|
||||
dialog.validateDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor for DiscoveryUiUtils utility class.
|
||||
*/
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.4" 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,0,102,0,0,1,56"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="documentFiltersScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="documentFiltersPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="documentsFiltersSplitPane" pref="294" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" 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 min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="documentsFiltersSplitPane" pref="84" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="documentsFiltersSplitPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Step 2: Filter which documents to show">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DocumentFilterPanel.documentsFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
* Class which displays all filters available for the Documents search type.
|
||||
*/
|
||||
final class DocumentFilterPanel extends AbstractFiltersPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final FileSearchData.FileType FILE_TYPE = FileSearchData.FileType.DOCUMENTS;
|
||||
|
||||
/**
|
||||
* Constructs a new DocumentFilterPanel.
|
||||
*/
|
||||
DocumentFilterPanel() {
|
||||
super();
|
||||
initComponents();
|
||||
addFilter(new SizeFilterPanel(FileSearchData.FileType.DOCUMENTS), false, null, 0);
|
||||
addFilter(new DataSourceFilterPanel(), false, null, 0);
|
||||
int[] pastOccurrencesIndices;
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
pastOccurrencesIndices = new int[]{0};
|
||||
} else {
|
||||
pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7};
|
||||
}
|
||||
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
|
||||
addFilter(new HashSetFilterPanel(), false, null, 1);
|
||||
addFilter(new InterestingItemsFilterPanel(), false, null, 1);
|
||||
addFilter(new ObjectDetectedFilterPanel(), false, null, 1);
|
||||
addFilter(new ParentFolderFilterPanel(), false, null, 1);
|
||||
addPanelsToScrollPane(documentsFiltersSplitPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
javax.swing.JScrollPane documentFiltersScrollPane = new javax.swing.JScrollPane();
|
||||
javax.swing.JPanel documentFiltersPanel = new javax.swing.JPanel();
|
||||
documentsFiltersSplitPane = new javax.swing.JSplitPane();
|
||||
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
documentsFiltersSplitPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(DocumentFilterPanel.class, "DocumentFilterPanel.documentsFiltersSplitPane.border.title"))); // NOI18N
|
||||
documentsFiltersSplitPane.setResizeWeight(0.5);
|
||||
|
||||
javax.swing.GroupLayout documentFiltersPanelLayout = new javax.swing.GroupLayout(documentFiltersPanel);
|
||||
documentFiltersPanel.setLayout(documentFiltersPanelLayout);
|
||||
documentFiltersPanelLayout.setHorizontalGroup(
|
||||
documentFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(documentFiltersPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(documentsFiltersSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
documentFiltersPanelLayout.setVerticalGroup(
|
||||
documentFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(documentFiltersPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(documentsFiltersSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 84, Short.MAX_VALUE)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
documentFiltersScrollPane.setViewportView(documentFiltersPanel);
|
||||
|
||||
add(documentFiltersScrollPane, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
@Override
|
||||
FileSearchData.FileType getFileType() {
|
||||
return FILE_TYPE;
|
||||
}
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JSplitPane documentsFiltersSplitPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
+8
-8
@@ -80,16 +80,16 @@
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="DocumentPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DocumentPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@@ -100,20 +100,20 @@
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fileSizeLabel">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="DocumentPanel.fileSizeLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DocumentPanel.fileSizeLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
+10
-10
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
@@ -33,16 +33,16 @@ import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane;
|
||||
/**
|
||||
* Class which displays a preview and details about a document.
|
||||
*/
|
||||
public class DocumentPanel extends javax.swing.JPanel implements ListCellRenderer<DocumentWrapper> {
|
||||
class DocumentPanel extends javax.swing.JPanel implements ListCellRenderer<DocumentWrapper> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Color SELECTION_COLOR = new Color(0, 120, 215);
|
||||
private static final int MAX_NAME_STRING = 90;
|
||||
|
||||
/**
|
||||
* Creates new form DocumentPanel
|
||||
* Creates new form DocumentPanel.
|
||||
*/
|
||||
public DocumentPanel() {
|
||||
DocumentPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
@@ -67,15 +67,15 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere
|
||||
|
||||
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
||||
isDeletedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.isDeletedLabel.toolTipText")); // NOI18N
|
||||
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
|
||||
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
||||
scoreLabel.setToolTipText("");
|
||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
|
||||
fileSizeLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.fileSizeLabel.toolTipText")); // NOI18N
|
||||
|
||||
+4
-4
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -27,15 +27,15 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
/**
|
||||
* A JPanel to display document previews.
|
||||
*/
|
||||
public class DocumentPreviewViewer extends javax.swing.JPanel {
|
||||
final class DocumentPreviewViewer extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DefaultListModel<DocumentWrapper> documentListModel = new DefaultListModel<>();
|
||||
|
||||
/**
|
||||
* Creates new form DocumentViewer
|
||||
* Creates new form DocumentViewer.
|
||||
*/
|
||||
public DocumentPreviewViewer() {
|
||||
DocumentPreviewViewer() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||
@@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||
* Class to wrap all the information necessary for a document summary to be
|
||||
* displayed.
|
||||
*/
|
||||
public class DocumentWrapper {
|
||||
final class DocumentWrapper {
|
||||
|
||||
private TextSummary summary;
|
||||
private final ResultFile resultFile;
|
||||
+2
-2
@@ -16,13 +16,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
|
||||
/**
|
||||
* Class for storing files that belong to a particular group.
|
||||
+4
-4
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
@@ -66,9 +66,9 @@ import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import static org.sleuthkit.autopsy.coreutils.VideoUtils.getVideoFileInTempDir;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileSize;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.Frequency;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
+14
-12
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.ArrayList;
|
||||
@@ -28,7 +28,7 @@ import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
||||
|
||||
/**
|
||||
* Utility enums for FileSearch
|
||||
* Utility enums for FileSearch.
|
||||
*/
|
||||
final class FileSearchData {
|
||||
|
||||
@@ -250,11 +250,12 @@ final class FileSearchData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of enums that are valid for image sizes.
|
||||
* Get the list of enums that are valid for most file sizes.
|
||||
*
|
||||
* @return enums that can be used to filter images by size.
|
||||
* @return Enums that can be used to filter most file including images
|
||||
* by size.
|
||||
*/
|
||||
static List<FileSize> getOptionsForImages() {
|
||||
static List<FileSize> getDefaultSizeOptions() {
|
||||
return Arrays.asList(XXLARGE_IMAGE, XLARGE_IMAGE, LARGE_IMAGE, MEDIUM_IMAGE, SMALL_IMAGE, XSMALL_IMAGE);
|
||||
}
|
||||
|
||||
@@ -268,7 +269,7 @@ final class FileSearchData {
|
||||
}
|
||||
}
|
||||
|
||||
//File discovery uses a different list of document mime types than FileTypeUtils.FileTypeCategory.DOCUMENTS
|
||||
//Discovery uses a different list of document mime types than FileTypeUtils.FileTypeCategory.DOCUMENTS
|
||||
private static final ImmutableSet<String> DOCUMENT_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.add("text/html", //NON-NLS
|
||||
@@ -291,14 +292,15 @@ final class FileSearchData {
|
||||
"application/vnd.oasis.opendocument.text" //NON-NLS
|
||||
).build();
|
||||
|
||||
private static final ImmutableSet<String> IMAGE_UNSUPPORTED_DOC_TYPES
|
||||
private static final ImmutableSet<String> IMAGE_UNSUPPORTED_DOC_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.add("application/pdf", //NON-NLS
|
||||
"application/xhtml+xml").build(); //NON-NLS
|
||||
|
||||
static Collection<String> getDocTypesWithoutImageExtraction(){
|
||||
return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES);
|
||||
}
|
||||
"application/xhtml+xml").build(); //NON-NLS
|
||||
|
||||
static Collection<String> getDocTypesWithoutImageExtraction() {
|
||||
return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing the file type. We don't simply use
|
||||
* FileTypeUtils.FileTypeCategory because: - Some file types categories
|
||||
+15
-14
@@ -16,30 +16,31 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
/**
|
||||
* Exception type used for FileSearch
|
||||
* Exception type used for FileSearch.
|
||||
*/
|
||||
public class FileSearchException extends Exception {
|
||||
final public class FileSearchException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Create exception from a string
|
||||
*
|
||||
* @param message
|
||||
* Create exception from a string.
|
||||
*
|
||||
* @param message The message to associate with this exception.
|
||||
*/
|
||||
public FileSearchException(String message) {
|
||||
FileSearchException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create exception for a string and cause
|
||||
*
|
||||
* @param message
|
||||
* @param cause
|
||||
* Create exception for a string and cause.
|
||||
*
|
||||
* @param message The message to associate with this exception.
|
||||
* @param cause The Throwable cause of the exception.
|
||||
*/
|
||||
public FileSearchException(String message, Throwable cause) {
|
||||
FileSearchException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -16,15 +16,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileSize;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.Frequency;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.Score;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Score;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@@ -842,7 +842,8 @@ class FileSearchFiltering {
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter for specifying that the file must have user content suspected data.
|
||||
* A filter for specifying that the file must have user content suspected
|
||||
* data.
|
||||
*/
|
||||
static class UserCreatedFilter extends FileFilter {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
+1
-1
@@ -46,7 +46,7 @@
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Groups">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="GroupListPanel.groupKeyList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="GroupListPanel.groupKeyList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
+39
-18
@@ -16,23 +16,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Cursor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
||||
|
||||
/**
|
||||
* Panel to display the list of groups which are provided by a search
|
||||
* Panel to display the list of groups which are provided by a search.
|
||||
*/
|
||||
class GroupListPanel extends javax.swing.JPanel {
|
||||
final class GroupListPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private FileType resultType = null;
|
||||
@@ -44,16 +46,16 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
private GroupKey selectedGroupKey;
|
||||
|
||||
/**
|
||||
* Creates new form GroupListPanel
|
||||
* Creates new form GroupListPanel.
|
||||
*/
|
||||
GroupListPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to and reset the panel in response to SearchStartedEvents
|
||||
* Subscribe to and reset the panel in response to SearchStartedEvents.
|
||||
*
|
||||
* @param searchStartedEvent the SearchStartedEvent which was received
|
||||
* @param searchStartedEvent The SearchStartedEvent which was received.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
|
||||
@@ -65,9 +67,9 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
"GroupsListPanel.noResults.title.text=No results found"})
|
||||
/**
|
||||
* Subscribe to and update list of groups in response to
|
||||
* SearchCompleteEvents
|
||||
* SearchCompleteEvents.
|
||||
*
|
||||
* @param searchCompleteEvent the SearchCompleteEvent which was received
|
||||
* @param searchCompleteEvent The SearchCompleteEvent which was received.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
|
||||
@@ -77,14 +79,29 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
groupSort = searchCompleteEvent.getGroupSort();
|
||||
fileSortMethod = searchCompleteEvent.getFileSort();
|
||||
groupKeyList.setListData(groupMap.keySet().toArray(new GroupKey[groupMap.keySet().size()]));
|
||||
if (groupKeyList.getModel().getSize() > 0) {
|
||||
groupKeyList.setSelectedIndex(0);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(DiscoveryTopComponent.getTopComponent(),
|
||||
Bundle.GroupsListPanel_noResults_message_text(),
|
||||
Bundle.GroupsListPanel_noResults_title_text(),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (groupKeyList.getModel().getSize() > 0) {
|
||||
groupKeyList.setSelectedIndex(0);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(DiscoveryTopComponent.getTopComponent(),
|
||||
Bundle.GroupsListPanel_noResults_message_text(),
|
||||
Bundle.GroupsListPanel_noResults_title_text(),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to SearchCancelledEvent and reset the panel in response to it.
|
||||
*
|
||||
* @param searchCancelledEvent The SearchCancelledEvent which was received.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleSearchCancelledEvent(DiscoveryEventUtils.SearchCancelledEvent searchCancelledEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +147,9 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
* Reset the group list to be empty.
|
||||
*/
|
||||
void resetGroupList() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
});
|
||||
groupKeyList.setListData(new GroupKey[0]);
|
||||
}
|
||||
|
||||
@@ -152,6 +172,7 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
}
|
||||
} else {
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.NoResultsEvent());
|
||||
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_groupSelected
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="hashSetCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="HashSetFilterPanel.hashSetCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hashSetCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="hashSetScrollPane" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="hashSetScrollPane" alignment="0" pref="60" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="hashSetScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="hashSetList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<String>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="visibleRowCount" type="int" value="3"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Panel for displaying the Hash Set filter controls.
|
||||
*/
|
||||
final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(HashSetFilterPanel.class.getName());
|
||||
|
||||
/**
|
||||
* Creates new form HashSetFilterPaenl.
|
||||
*/
|
||||
HashSetFilterPanel() {
|
||||
initComponents();
|
||||
setUpHashFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the hash filter.
|
||||
*/
|
||||
private void setUpHashFilter() {
|
||||
int count = 0;
|
||||
try {
|
||||
DefaultListModel<String> hashListModel = (DefaultListModel<String>) hashSetList.getModel();
|
||||
hashListModel.removeAllElements();
|
||||
List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
|
||||
for (String name : setNames) {
|
||||
hashListModel.add(count, name);
|
||||
count++;
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error loading hash set names", ex);
|
||||
hashSetCheckbox.setEnabled(false);
|
||||
hashSetList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
hashSetCheckbox = new javax.swing.JCheckBox();
|
||||
hashSetScrollPane = new javax.swing.JScrollPane();
|
||||
hashSetList = new javax.swing.JList<>();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(hashSetCheckbox, org.openide.util.NbBundle.getMessage(HashSetFilterPanel.class, "HashSetFilterPanel.hashSetCheckbox.text")); // NOI18N
|
||||
hashSetCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
hashSetCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
hashSetCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
hashSetCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
hashSetCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
|
||||
hashSetList.setModel(new DefaultListModel<String>());
|
||||
hashSetList.setEnabled(false);
|
||||
hashSetList.setVisibleRowCount(3);
|
||||
hashSetScrollPane.setViewportView(hashSetList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(hashSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(hashSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void hashSetCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hashSetCheckboxActionPerformed
|
||||
hashSetList.setEnabled(hashSetCheckbox.isSelected());
|
||||
}//GEN-LAST:event_hashSetCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox hashSetCheckbox;
|
||||
private javax.swing.JList<String> hashSetList;
|
||||
private javax.swing.JScrollPane hashSetScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
boolean hasHashSets = hashSetList.getModel().getSize() > 0;
|
||||
hashSetCheckbox.setEnabled(hasHashSets);
|
||||
hashSetCheckbox.setSelected(selected && hasHashSets);
|
||||
if (hashSetCheckbox.isEnabled() && hashSetCheckbox.isSelected()) {
|
||||
hashSetScrollPane.setEnabled(true);
|
||||
hashSetList.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
hashSetList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
hashSetScrollPane.setEnabled(false);
|
||||
hashSetList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return hashSetCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
if (hashSetCheckbox.isSelected() && hashSetList.getSelectedValuesList().isEmpty()) {
|
||||
return "At least one hash set name must be selected";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return hashSetList;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (hashSetCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.HashSetFilter(hashSetList.getSelectedValuesList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?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,0,68,0,0,0,-31"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="imageFiltersScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="imageFiltersPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="imageFiltersSplitPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" 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 min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="imageFiltersSplitPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="imageFiltersSplitPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Step 2: Filter which images to show">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ImageFilterPanel.imageFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ImageFilterPanel.imageFiltersSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
* Panel for displaying all the filters associated with the Image type.
|
||||
*/
|
||||
final class ImageFilterPanel extends AbstractFiltersPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final FileSearchData.FileType FILE_TYPE = FileSearchData.FileType.IMAGE;
|
||||
|
||||
/**
|
||||
* Creates new form ImageFilterPanel.
|
||||
*/
|
||||
ImageFilterPanel() {
|
||||
super();
|
||||
initComponents();
|
||||
SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE);
|
||||
int[] sizeIndicesSelected = {1, 2, 3, 4, 5};
|
||||
addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0);
|
||||
addFilter(new DataSourceFilterPanel(), false, null, 0);
|
||||
int[] pastOccurrencesIndices;
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
pastOccurrencesIndices = new int[]{0};
|
||||
} else {
|
||||
pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7};
|
||||
}
|
||||
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
|
||||
addFilter(new UserCreatedFilterPanel(), false, null, 1);
|
||||
addFilter(new HashSetFilterPanel(), false, null, 1);
|
||||
addFilter(new InterestingItemsFilterPanel(), false, null, 1);
|
||||
addFilter(new ObjectDetectedFilterPanel(), false, null, 1);
|
||||
addFilter(new ParentFolderFilterPanel(), false, null, 1);
|
||||
addPanelsToScrollPane(imageFiltersSplitPane);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
javax.swing.JScrollPane imageFiltersScrollPane = new javax.swing.JScrollPane();
|
||||
javax.swing.JPanel imageFiltersPanel = new javax.swing.JPanel();
|
||||
imageFiltersSplitPane = new javax.swing.JSplitPane();
|
||||
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
imageFiltersSplitPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ImageFilterPanel.class, "ImageFilterPanel.imageFiltersSplitPane.border.title"))); // NOI18N
|
||||
imageFiltersSplitPane.setResizeWeight(0.5);
|
||||
imageFiltersSplitPane.setToolTipText(org.openide.util.NbBundle.getMessage(ImageFilterPanel.class, "ImageFilterPanel.imageFiltersSplitPane.toolTipText")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout imageFiltersPanelLayout = new javax.swing.GroupLayout(imageFiltersPanel);
|
||||
imageFiltersPanel.setLayout(imageFiltersPanelLayout);
|
||||
imageFiltersPanelLayout.setHorizontalGroup(
|
||||
imageFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(imageFiltersPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(imageFiltersSplitPane)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
imageFiltersPanelLayout.setVerticalGroup(
|
||||
imageFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(imageFiltersPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(imageFiltersSplitPane)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
imageFiltersScrollPane.setViewportView(imageFiltersPanel);
|
||||
|
||||
add(imageFiltersScrollPane, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@Override
|
||||
FileSearchData.FileType getFileType() {
|
||||
return FILE_TYPE;
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JSplitPane imageFiltersSplitPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
+7
-7
@@ -102,16 +102,16 @@
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ImageThumbnailPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ImageThumbnailPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@@ -122,13 +122,13 @@
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
+9
-9
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
@@ -32,7 +32,7 @@ import org.openide.util.NbBundle;
|
||||
/**
|
||||
* Class which displays a thumbnail and information for an image file.
|
||||
*/
|
||||
public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellRenderer<ImageThumbnailWrapper> {
|
||||
final class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellRenderer<ImageThumbnailWrapper> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Color SELECTION_COLOR = new Color(0, 120, 215);
|
||||
@@ -41,7 +41,7 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR
|
||||
/**
|
||||
* Creates new form ImageThumbnailPanel
|
||||
*/
|
||||
public ImageThumbnailPanel() {
|
||||
ImageThumbnailPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
@@ -76,15 +76,15 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR
|
||||
|
||||
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
||||
isDeletedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ImageThumbnailPanel.class, "ImageThumbnailPanel.isDeletedLabel.toolTipText")); // NOI18N
|
||||
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
|
||||
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
||||
scoreLabel.setToolTipText("");
|
||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
+4
-4
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -28,16 +28,16 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
* A JPanel to display image thumbnails.
|
||||
*
|
||||
*/
|
||||
public class ImageThumbnailViewer extends javax.swing.JPanel {
|
||||
final class ImageThumbnailViewer extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final DefaultListModel<ImageThumbnailWrapper> thumbnailListModel = new DefaultListModel<>();
|
||||
|
||||
/**
|
||||
* Creates new form ImageThumbnailViewer
|
||||
* Creates new form ImageThumbnailViewer.
|
||||
*/
|
||||
public ImageThumbnailViewer() {
|
||||
ImageThumbnailViewer() {
|
||||
initComponents();
|
||||
|
||||
}
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.awt.Image;
|
||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
@@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
* Class to wrap all the information necessary for an image thumbnail to be
|
||||
* displayed.
|
||||
*/
|
||||
public class ImageThumbnailWrapper {
|
||||
final class ImageThumbnailWrapper {
|
||||
|
||||
private Image thumbnail;
|
||||
private final ResultFile resultFile;
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="interestingItemsCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="InterestingItemsFilterPanel.interestingItemsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="interestingItemsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="interestingItemsScrollPane" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="interestingItemsScrollPane" alignment="0" pref="88" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="interestingItemsScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[27, 27]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="interestingItemsList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<String>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="visibleRowCount" type="int" value="2"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Class to allow configuration of the Interesting Items filter.
|
||||
*/
|
||||
final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(InterestingItemsFilterPanel.class.getName());
|
||||
|
||||
/**
|
||||
* Creates new form InterestingItemsFilterPanel.
|
||||
*/
|
||||
InterestingItemsFilterPanel() {
|
||||
initComponents();
|
||||
setUpInterestingItemsFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the interesting items filter.
|
||||
*/
|
||||
private void setUpInterestingItemsFilter() {
|
||||
int count = 0;
|
||||
try {
|
||||
DefaultListModel<String> intListModel = (DefaultListModel<String>) interestingItemsList.getModel();
|
||||
intListModel.removeAllElements();
|
||||
List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
|
||||
for (String name : setNames) {
|
||||
intListModel.add(count, name);
|
||||
count++;
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error loading interesting file set names", ex);
|
||||
interestingItemsCheckbox.setEnabled(false);
|
||||
interestingItemsList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
interestingItemsCheckbox = new javax.swing.JCheckBox();
|
||||
interestingItemsScrollPane = new javax.swing.JScrollPane();
|
||||
interestingItemsList = new javax.swing.JList<>();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(interestingItemsCheckbox, org.openide.util.NbBundle.getMessage(InterestingItemsFilterPanel.class, "InterestingItemsFilterPanel.interestingItemsCheckbox.text")); // NOI18N
|
||||
interestingItemsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
interestingItemsCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
interestingItemsCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
interestingItemsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
interestingItemsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
|
||||
interestingItemsScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
|
||||
|
||||
interestingItemsList.setModel(new DefaultListModel<String>());
|
||||
interestingItemsList.setEnabled(false);
|
||||
interestingItemsList.setVisibleRowCount(2);
|
||||
interestingItemsScrollPane.setViewportView(interestingItemsList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(interestingItemsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(interestingItemsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 88, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void interestingItemsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interestingItemsCheckboxActionPerformed
|
||||
interestingItemsList.setEnabled(interestingItemsCheckbox.isSelected());
|
||||
}//GEN-LAST:event_interestingItemsCheckboxActionPerformed
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
boolean hasInterestingItems = interestingItemsList.getModel().getSize() > 0;
|
||||
interestingItemsCheckbox.setEnabled(hasInterestingItems);
|
||||
interestingItemsCheckbox.setSelected(selected && hasInterestingItems);
|
||||
if (interestingItemsCheckbox.isEnabled() && interestingItemsCheckbox.isSelected()) {
|
||||
interestingItemsScrollPane.setEnabled(true);
|
||||
interestingItemsList.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
interestingItemsList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
interestingItemsScrollPane.setEnabled(false);
|
||||
interestingItemsList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return interestingItemsCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
if (interestingItemsCheckbox.isSelected() && interestingItemsList.getSelectedValuesList().isEmpty()) {
|
||||
return "At least one interesting file set name must be selected";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox interestingItemsCheckbox;
|
||||
private javax.swing.JList<String> interestingItemsList;
|
||||
private javax.swing.JScrollPane interestingItemsScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return interestingItemsList;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (interestingItemsCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.InterestingFileSetFilter(interestingItemsList.getSelectedValuesList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="objectsCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ObjectDetectedFilterPanel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="verticalAlignment" type="int" value="1"/>
|
||||
<Property name="verticalTextPosition" type="int" value="1"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="objectsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="objectsScrollPane" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="objectsScrollPane" pref="64" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="objectsScrollPane">
|
||||
<Properties>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[27, 27]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="objectsList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<String>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 32767]"/>
|
||||
</Property>
|
||||
<Property name="visibleRowCount" type="int" value="2"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Class to allow configuration of the Objects Detected filter.
|
||||
*/
|
||||
final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(ObjectDetectedFilterPanel.class.getName());
|
||||
|
||||
/**
|
||||
* Creates new form ObjectDetectedFilter.
|
||||
*/
|
||||
ObjectDetectedFilterPanel() {
|
||||
initComponents();
|
||||
setUpObjectFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the object filter.
|
||||
*/
|
||||
private void setUpObjectFilter() {
|
||||
int count = 0;
|
||||
try {
|
||||
DefaultListModel<String> objListModel = (DefaultListModel<String>) objectsList.getModel();
|
||||
objListModel.removeAllElements();
|
||||
List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION);
|
||||
for (String name : setNames) {
|
||||
objListModel.add(count, name);
|
||||
count++;
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error loading object detected set names", ex);
|
||||
objectsCheckbox.setEnabled(false);
|
||||
objectsList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
objectsCheckbox = new javax.swing.JCheckBox();
|
||||
objectsScrollPane = new javax.swing.JScrollPane();
|
||||
objectsList = new javax.swing.JList<>();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(objectsCheckbox, org.openide.util.NbBundle.getMessage(ObjectDetectedFilterPanel.class, "ObjectDetectedFilterPanel.text")); // NOI18N
|
||||
objectsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
objectsCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
objectsCheckbox.setName(""); // NOI18N
|
||||
objectsCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
objectsCheckbox.setVerticalAlignment(javax.swing.SwingConstants.TOP);
|
||||
objectsCheckbox.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
|
||||
objectsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
objectsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
|
||||
objectsScrollPane.setName(""); // NOI18N
|
||||
objectsScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
|
||||
|
||||
objectsList.setModel(new DefaultListModel<String>());
|
||||
objectsList.setEnabled(false);
|
||||
objectsList.setMaximumSize(new java.awt.Dimension(32767, 32767));
|
||||
objectsList.setVisibleRowCount(2);
|
||||
objectsScrollPane.setViewportView(objectsList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(objectsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(objectsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void objectsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_objectsCheckboxActionPerformed
|
||||
objectsList.setEnabled(objectsCheckbox.isSelected());
|
||||
}//GEN-LAST:event_objectsCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox objectsCheckbox;
|
||||
private javax.swing.JList<String> objectsList;
|
||||
private javax.swing.JScrollPane objectsScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
boolean hasObjects = objectsList.getModel().getSize() > 0;
|
||||
objectsCheckbox.setEnabled(hasObjects);
|
||||
objectsCheckbox.setSelected(selected && hasObjects);
|
||||
if (objectsCheckbox.isEnabled() && objectsCheckbox.isSelected()) {
|
||||
objectsScrollPane.setEnabled(true);
|
||||
objectsList.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
objectsList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
objectsScrollPane.setEnabled(false);
|
||||
objectsList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return objectsCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
if (objectsCheckbox.isSelected() && objectsList.getSelectedValuesList().isEmpty()) {
|
||||
return "At least one object type name must be selected";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return objectsList;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (objectsCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.ObjectDetectionFilter(objectsList.getSelectedValuesList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2019-2020 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.discovery;
|
||||
|
||||
import java.awt.Component;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.util.actions.Presenter;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
|
||||
/**
|
||||
* Class to open the Discovery dialog. Allows the user to run searches and see
|
||||
* results in the DiscoveryTopComponent.
|
||||
*/
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.newpackage.OpenDiscoveryAction")
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Menu/Tools", position = 103)
|
||||
,
|
||||
@ActionReference(path = "Toolbars/Case", position = 105)})
|
||||
@ActionRegistration(displayName = "#CTL_OpenDiscoveryAction", lazy = false)
|
||||
@NbBundle.Messages({"CTL_OpenDiscoveryAction=Discovery"})
|
||||
public final class OpenDiscoveryAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||
|
||||
private static final String DISPLAY_NAME = Bundle.CTL_OpenDiscoveryAction();
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final JButton toolbarButton = new JButton();
|
||||
|
||||
/**
|
||||
* Construct a new OpenDiscoveryAction.
|
||||
*/
|
||||
public OpenDiscoveryAction() {
|
||||
toolbarButton.addActionListener(OpenDiscoveryAction.this::actionPerformed);
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return Case.isCaseOpen();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"OpenDiscoveryAction.resultsIncomplete.text=Results may be incomplete"})
|
||||
|
||||
@Override
|
||||
public void performAction() {
|
||||
final DiscoveryDialog discDialog = DiscoveryDialog.getDiscoveryDialogInstance();
|
||||
discDialog.cancelSearch();
|
||||
discDialog.setVisible(true);
|
||||
DiscoveryUiUtils.displayErrorMessage(discDialog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the toolbar component of this action.
|
||||
*
|
||||
* @return The toolbar button
|
||||
*/
|
||||
@Override
|
||||
public Component getToolbarPresenter() {
|
||||
ImageIcon icon = new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/discovery-icon-24.png")); //NON-NLS
|
||||
toolbarButton.setIcon(icon);
|
||||
toolbarButton.setText(this.getName());
|
||||
return toolbarButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this action to be enabled/disabled
|
||||
*
|
||||
* @param value whether to enable this action or not
|
||||
*/
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
super.setEnabled(value);
|
||||
toolbarButton.setEnabled(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return DISPLAY_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asynchronous() {
|
||||
return false; // run on edt
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
@@ -24,7 +24,7 @@ import java.util.logging.Level;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,224 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="parentCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.parentCheckbox.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="parentCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="parentLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.parentLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 120]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 120]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="includeRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fullRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="substringRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="excludeRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="103" alignment="0" groupAlignment="1" attributes="0">
|
||||
<Component id="parentScrollPane" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="parentTextField" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deleteButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="addButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="parentScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="fullRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="substringRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="includeRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="excludeRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="parentTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="addButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="parentScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[27, 27]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="parentList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<ParentSearchTerm>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="visibleRowCount" type="int" value="4"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="parentListValueChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<ParentSearchTerm>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JRadioButton" name="fullRadioButton">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.fullRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="includeRadioButton">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.includeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="substringRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.substringRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="excludeRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.excludeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.deleteButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[70, 23]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[70, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[70, 23]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="addButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.addButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[70, 23]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[70, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[70, 23]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="parentTextField">
|
||||
<Properties>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchFiltering.ParentSearchTerm;
|
||||
|
||||
/**
|
||||
* Panel to allow configuration of the Parent Folder filter.
|
||||
*/
|
||||
final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private DefaultListModel<FileSearchFiltering.ParentSearchTerm> parentListModel;
|
||||
private static final String[] DEFAULT_IGNORED_PATHS = {"/Windows/", "/Program Files/"}; //NON-NLS
|
||||
|
||||
/**
|
||||
* Creates new form ParentFolderFilterPanel.
|
||||
*/
|
||||
ParentFolderFilterPanel() {
|
||||
initComponents();
|
||||
setUpParentPathFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the parent path filter.
|
||||
*/
|
||||
private void setUpParentPathFilter() {
|
||||
fullRadioButton.setSelected(true);
|
||||
includeRadioButton.setSelected(true);
|
||||
parentListModel = (DefaultListModel<FileSearchFiltering.ParentSearchTerm>) parentList.getModel();
|
||||
for (String ignorePath : DEFAULT_IGNORED_PATHS) {
|
||||
parentListModel.add(parentListModel.size(), new ParentSearchTerm(ignorePath, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
parentCheckbox = new javax.swing.JCheckBox();
|
||||
parentLabel = new javax.swing.JLabel();
|
||||
parentScrollPane = new javax.swing.JScrollPane();
|
||||
parentList = new javax.swing.JList<>();
|
||||
fullRadioButton = new javax.swing.JRadioButton();
|
||||
includeRadioButton = new javax.swing.JRadioButton();
|
||||
substringRadioButton = new javax.swing.JRadioButton();
|
||||
excludeRadioButton = new javax.swing.JRadioButton();
|
||||
deleteButton = new javax.swing.JButton();
|
||||
addButton = new javax.swing.JButton();
|
||||
parentTextField = new javax.swing.JTextField();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(parentCheckbox, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.parentCheckbox.text_1")); // NOI18N
|
||||
parentCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
parentCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
parentCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
parentCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
parentCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(parentLabel, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.parentLabel.text_1")); // NOI18N
|
||||
parentLabel.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
parentLabel.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
parentLabel.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 120));
|
||||
setPreferredSize(new java.awt.Dimension(250, 120));
|
||||
|
||||
parentScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
|
||||
|
||||
parentList.setModel(new DefaultListModel<ParentSearchTerm>());
|
||||
parentList.setEnabled(false);
|
||||
parentList.setVisibleRowCount(4);
|
||||
parentList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
|
||||
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
|
||||
parentListValueChanged(evt);
|
||||
}
|
||||
});
|
||||
parentScrollPane.setViewportView(parentList);
|
||||
|
||||
fullRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fullRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.fullRadioButton.text_1")); // NOI18N
|
||||
fullRadioButton.setEnabled(false);
|
||||
|
||||
includeRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.includeRadioButton.text_1")); // NOI18N
|
||||
includeRadioButton.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(substringRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.substringRadioButton.text_1")); // NOI18N
|
||||
substringRadioButton.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(excludeRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.excludeRadioButton.text_1")); // NOI18N
|
||||
excludeRadioButton.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.deleteButton.text_1")); // NOI18N
|
||||
deleteButton.setEnabled(false);
|
||||
deleteButton.setMaximumSize(new java.awt.Dimension(70, 23));
|
||||
deleteButton.setMinimumSize(new java.awt.Dimension(70, 23));
|
||||
deleteButton.setPreferredSize(new java.awt.Dimension(70, 23));
|
||||
deleteButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deleteButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.addButton.text_1")); // NOI18N
|
||||
addButton.setEnabled(false);
|
||||
addButton.setMaximumSize(new java.awt.Dimension(70, 23));
|
||||
addButton.setMinimumSize(new java.awt.Dimension(70, 23));
|
||||
addButton.setPreferredSize(new java.awt.Dimension(70, 23));
|
||||
addButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
addButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
parentTextField.setEnabled(false);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(includeRadioButton)
|
||||
.addComponent(fullRadioButton))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(substringRadioButton)
|
||||
.addComponent(excludeRadioButton)))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(parentScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||
.addComponent(parentTextField)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(parentScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(fullRadioButton)
|
||||
.addComponent(substringRadioButton))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(includeRadioButton)
|
||||
.addComponent(excludeRadioButton)
|
||||
.addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(parentTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void parentCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_parentCheckboxActionPerformed
|
||||
// parentFilterSettings(true, true, parentCheckbox.isSelected(), null);
|
||||
}//GEN-LAST:event_parentCheckboxActionPerformed
|
||||
|
||||
private void parentListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_parentListValueChanged
|
||||
if (parentList.getSelectedValuesList().isEmpty()) {
|
||||
deleteButton.setEnabled(false);
|
||||
} else {
|
||||
deleteButton.setEnabled(true);
|
||||
}
|
||||
}//GEN-LAST:event_parentListValueChanged
|
||||
|
||||
private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
|
||||
int index = parentList.getSelectedIndex();
|
||||
if (index >= 0) {
|
||||
parentListModel.remove(index);
|
||||
}
|
||||
}//GEN-LAST:event_deleteButtonActionPerformed
|
||||
|
||||
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
|
||||
if (!parentTextField.getText().isEmpty()) {
|
||||
ParentSearchTerm searchTerm;
|
||||
searchTerm = new ParentSearchTerm(parentTextField.getText(), fullRadioButton.isSelected(), includeRadioButton.isSelected());
|
||||
parentListModel.add(parentListModel.size(), searchTerm);
|
||||
parentTextField.setText("");
|
||||
}
|
||||
}//GEN-LAST:event_addButtonActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton addButton;
|
||||
private javax.swing.JButton deleteButton;
|
||||
private javax.swing.JRadioButton excludeRadioButton;
|
||||
private javax.swing.JRadioButton fullRadioButton;
|
||||
private javax.swing.JRadioButton includeRadioButton;
|
||||
private javax.swing.JCheckBox parentCheckbox;
|
||||
private javax.swing.JLabel parentLabel;
|
||||
private javax.swing.JList<ParentSearchTerm> parentList;
|
||||
private javax.swing.JScrollPane parentScrollPane;
|
||||
private javax.swing.JTextField parentTextField;
|
||||
private javax.swing.JRadioButton substringRadioButton;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
parentCheckbox.setSelected(selected);
|
||||
if (parentCheckbox.isEnabled() && parentCheckbox.isSelected()) {
|
||||
parentScrollPane.setEnabled(true);
|
||||
includeRadioButton.setEnabled(true);
|
||||
excludeRadioButton.setEnabled(true);
|
||||
fullRadioButton.setEnabled(true);
|
||||
substringRadioButton.setEnabled(true);
|
||||
addButton.setEnabled(true);
|
||||
deleteButton.setEnabled(!parentListModel.isEmpty());
|
||||
parentList.setEnabled(true);
|
||||
parentTextField.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
parentList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
parentScrollPane.setEnabled(false);
|
||||
parentList.setEnabled(false);
|
||||
includeRadioButton.setEnabled(false);
|
||||
excludeRadioButton.setEnabled(false);
|
||||
fullRadioButton.setEnabled(false);
|
||||
substringRadioButton.setEnabled(false);
|
||||
addButton.setEnabled(false);
|
||||
deleteButton.setEnabled(false);
|
||||
parentTextField.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return parentCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return parentLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
// Parent uses everything in the box
|
||||
if (parentCheckbox.isSelected() && getParentPaths().isEmpty()) {
|
||||
return "At least one parent path must be entered";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get the parent path objects out of the JList.
|
||||
*
|
||||
* @return The list of entered ParentSearchTerm objects
|
||||
*/
|
||||
private List<FileSearchFiltering.ParentSearchTerm> getParentPaths() {
|
||||
List<FileSearchFiltering.ParentSearchTerm> results = new ArrayList<>();
|
||||
for (int i = 0; i < parentListModel.getSize(); i++) {
|
||||
results.add(parentListModel.get(i));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return parentList;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (parentCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.ParentFilter(getParentPaths());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="pastOccurrencesCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pastOccurrencesCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="crFrequencyScrollPane" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="crFrequencyScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="crFrequencyScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[27, 27]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="crFrequencyList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<Frequency>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="visibleRowCount" type="int" value="5"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<Frequency>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency;
|
||||
|
||||
/**
|
||||
* Panel to allow configuration of the Past Occurrences filter.
|
||||
*/
|
||||
final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates new form PastOccurrencesFilterPanel.
|
||||
*/
|
||||
PastOccurrencesFilterPanel() {
|
||||
initComponents();
|
||||
setUpFrequencyFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
pastOccurrencesCheckbox = new javax.swing.JCheckBox();
|
||||
crFrequencyScrollPane = new javax.swing.JScrollPane();
|
||||
crFrequencyList = new javax.swing.JList<>();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(pastOccurrencesCheckbox, org.openide.util.NbBundle.getMessage(PastOccurrencesFilterPanel.class, "PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text")); // NOI18N
|
||||
pastOccurrencesCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
pastOccurrencesCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
pastOccurrencesCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
pastOccurrencesCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
pastOccurrencesCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
|
||||
crFrequencyScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
|
||||
|
||||
crFrequencyList.setModel(new DefaultListModel<Frequency>());
|
||||
crFrequencyList.setEnabled(false);
|
||||
crFrequencyList.setVisibleRowCount(5);
|
||||
crFrequencyScrollPane.setViewportView(crFrequencyList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(crFrequencyScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(crFrequencyScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void pastOccurrencesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pastOccurrencesCheckboxActionPerformed
|
||||
crFrequencyList.setEnabled(pastOccurrencesCheckbox.isSelected());
|
||||
}//GEN-LAST:event_pastOccurrencesCheckboxActionPerformed
|
||||
|
||||
/**
|
||||
* Initialize the frequency filter.
|
||||
*/
|
||||
private void setUpFrequencyFilter() {
|
||||
int count = 0;
|
||||
DefaultListModel<FileSearchData.Frequency> frequencyListModel = (DefaultListModel<FileSearchData.Frequency>) crFrequencyList.getModel();
|
||||
frequencyListModel.removeAllElements();
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
for (FileSearchData.Frequency freq : FileSearchData.Frequency.getOptionsForFilteringWithoutCr()) {
|
||||
frequencyListModel.add(count, freq);
|
||||
}
|
||||
} else {
|
||||
for (FileSearchData.Frequency freq : FileSearchData.Frequency.getOptionsForFilteringWithCr()) {
|
||||
frequencyListModel.add(count, freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JList<Frequency> crFrequencyList;
|
||||
private javax.swing.JScrollPane crFrequencyScrollPane;
|
||||
private javax.swing.JCheckBox pastOccurrencesCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
pastOccurrencesCheckbox.setSelected(selected);
|
||||
if (pastOccurrencesCheckbox.isEnabled() && pastOccurrencesCheckbox.isSelected()) {
|
||||
crFrequencyScrollPane.setEnabled(true);
|
||||
crFrequencyList.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
crFrequencyList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
crFrequencyScrollPane.setEnabled(false);
|
||||
crFrequencyList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return pastOccurrencesCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
if (pastOccurrencesCheckbox.isSelected() && crFrequencyList.getSelectedValuesList().isEmpty()) {
|
||||
return "At least one value in the past occurrence filter must be selected";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return crFrequencyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (pastOccurrencesCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.FrequencyFilter(crFrequencyList.getSelectedValuesList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -16,9 +16,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -37,7 +37,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Container for files that holds all necessary data for grouping and sorting
|
||||
* Container for files that holds all necessary data for grouping and sorting.
|
||||
*/
|
||||
class ResultFile {
|
||||
|
||||
+35
-131
@@ -2,8 +2,11 @@
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[700, 200]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[777, 475]"/>
|
||||
<Dimension value="[700, 700]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@@ -16,26 +19,10 @@
|
||||
<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,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="pagingPanel" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="resultsSplitPane" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="pagingPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="resultsSplitPane" pref="436" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pagingPanel">
|
||||
<Properties>
|
||||
@@ -44,11 +31,22 @@
|
||||
<EtchetBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[400, 39]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[700, 39]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="First"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
@@ -81,7 +79,7 @@
|
||||
<Component class="javax.swing.JLabel" name="currentPageLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ResultsPanel.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[190, 23]"/>
|
||||
@@ -129,7 +127,7 @@
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ResultsPanel.pageControlsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.pageControlsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[133, 23]"/>
|
||||
@@ -155,7 +153,7 @@
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ResultsPanel.gotoPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.gotoPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[170, 23]"/>
|
||||
@@ -180,6 +178,10 @@
|
||||
<Component class="javax.swing.JTextField" name="gotoPageField">
|
||||
<Properties>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[30, 22]"/>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[26, 22]"/>
|
||||
</Property>
|
||||
@@ -197,7 +199,7 @@
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ResultsPanel.pageSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.pageSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[160, 23]"/>
|
||||
@@ -310,120 +312,22 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JSplitPane" name="resultsSplitPane">
|
||||
<Container class="javax.swing.JPanel" name="resultsViewerPanel">
|
||||
<Properties>
|
||||
<Property name="dividerLocation" type="int" value="380"/>
|
||||
<Property name="orientation" type="int" value="0"/>
|
||||
<Property name="resizeWeight" type="double" value="1.0"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ResultsPanel.resultsSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 160]"/>
|
||||
</Property>
|
||||
<Property name="lastDividerLocation" type="int" value="180"/>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[777, 440]"/>
|
||||
<Dimension value="[700, 700]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="instancesPanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[775, 68]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</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>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="779" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="instancesScrollPane" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="68" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="instancesScrollPane" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="instancesScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[775, 60]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="instancesList">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Instances">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ResultsPanel.instancesList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="instancesListModel" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new InstancesCellRenderer()" type="code"/>
|
||||
</Property>
|
||||
<Property name="visibleRowCount" type="int" value="2"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<AbstractFile>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="resultsViewerPanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 380]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="left"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
+70
-196
@@ -16,52 +16,35 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||
|
||||
/**
|
||||
* Panel for displaying of file discovery results and handling the paging of
|
||||
* those results.
|
||||
* Panel for displaying of Discovery results and handling the paging of those
|
||||
* results.
|
||||
*/
|
||||
public class ResultsPanel extends javax.swing.JPanel {
|
||||
final class ResultsPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger logger = Logger.getLogger(ResultsPanel.class.getName());
|
||||
@@ -79,15 +62,13 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
private int groupSize = 0;
|
||||
private PageWorker pageWorker;
|
||||
private final List<SwingWorker<Void, Void>> resultContentWorkers = new ArrayList<>();
|
||||
private final DefaultListModel<AbstractFile> instancesListModel = new DefaultListModel<>();
|
||||
private ListSelectionListener listener = null;
|
||||
|
||||
/**
|
||||
* Creates new form ResultsPanel.
|
||||
*/
|
||||
@Messages({"ResultsPanel.viewFileInDir.name=View File in Directory",
|
||||
"ResultsPanel.openInExternalViewer.name=Open in External Viewer"})
|
||||
public ResultsPanel() {
|
||||
ResultsPanel() {
|
||||
initComponents();
|
||||
imageThumbnailViewer = new ImageThumbnailViewer();
|
||||
videoThumbnailViewer = new VideoThumbnailViewer();
|
||||
@@ -95,103 +76,37 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
videoThumbnailViewer.addListSelectionListener((e) -> {
|
||||
if (resultType == FileSearchData.FileType.VIDEO) {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
populateInstancesList();
|
||||
//send populateMesage
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
|
||||
} else {
|
||||
instancesList.clearSelection();
|
||||
//send clearSelection message
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
|
||||
}
|
||||
}
|
||||
});
|
||||
imageThumbnailViewer.addListSelectionListener((e) -> {
|
||||
if (resultType == FileSearchData.FileType.IMAGE) {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
populateInstancesList();
|
||||
//send populateMesage
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
|
||||
} else {
|
||||
instancesList.clearSelection();
|
||||
//send clearSelection message
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
documentPreviewViewer.addListSelectionListener((e) -> {
|
||||
if (resultType == FileSearchData.FileType.DOCUMENTS) {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
populateInstancesList();
|
||||
//send populateMesage
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
|
||||
} else {
|
||||
instancesList.clearSelection();
|
||||
//send clearSelection message
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
|
||||
}
|
||||
}
|
||||
});
|
||||
//Add the context menu when right clicking
|
||||
instancesList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint()));
|
||||
Set<AbstractFile> files = new HashSet<>();
|
||||
files.add(instancesList.getSelectedValue());
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
menu.add(new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue()));
|
||||
menu.add(new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(), new FileNode(instancesList.getSelectedValue())));
|
||||
menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue()));
|
||||
menu.add(new DiscoveryExtractAction(files));
|
||||
menu.add(AddContentTagAction.getInstance().getMenuForContent(files));
|
||||
menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files));
|
||||
menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files));
|
||||
menu.show(instancesList, e.getPoint().x, e.getPoint().y);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list selection listener to the instances list.
|
||||
*
|
||||
* @param listener The ListSelectionListener to add to the instances list.
|
||||
*/
|
||||
void addListSelectionListener(ListSelectionListener newListener) {
|
||||
instancesList.removeListSelectionListener(listener);
|
||||
listener = newListener;
|
||||
instancesList.addListSelectionListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the instances list.
|
||||
*/
|
||||
synchronized void populateInstancesList() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
List<AbstractFile> files = getInstancesForSelected();
|
||||
if (files.isEmpty()) {
|
||||
//if there are no files currently remove the current items without removing listener to cause content viewer to reset
|
||||
instancesListModel.removeAllElements();
|
||||
} else {
|
||||
//remove listener so content viewer node is not set multiple times
|
||||
instancesList.removeListSelectionListener(listener);
|
||||
instancesListModel.removeAllElements();
|
||||
for (AbstractFile file : files) {
|
||||
instancesListModel.addElement(file);
|
||||
}
|
||||
//add listener back to allow selection of first index to cause content viewer node to be set
|
||||
instancesList.addListSelectionListener(listener);
|
||||
if (!instancesListModel.isEmpty()) {
|
||||
instancesList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AbstractFile for the item currently selected in the instances
|
||||
* list.
|
||||
*
|
||||
* @return The AbstractFile which is currently selected.
|
||||
*/
|
||||
synchronized AbstractFile getSelectedFile() {
|
||||
if (instancesList.getSelectedIndex() == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return instancesListModel.getElementAt(instancesList.getSelectedIndex());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,6 +132,18 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to and reset the panel in response to SearchStartedEvents.
|
||||
*
|
||||
* @param searchStartedEvent The SearchStartedEvent which was received.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe and respond to PageRetrievedEvents.
|
||||
*
|
||||
@@ -225,7 +152,9 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
@Subscribe
|
||||
void handlePageRetrievedEvent(DiscoveryEventUtils.PageRetrievedEvent pageRetrievedEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
populateInstancesList();
|
||||
//send populateMesage
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
|
||||
|
||||
currentPage = pageRetrievedEvent.getPageNumber();
|
||||
updateControls();
|
||||
resetResultViewer();
|
||||
@@ -358,13 +287,27 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to and update cursor in response to SearchCompleteEvents.
|
||||
*
|
||||
* @param searchCompleteEvent The SearchCompleteEvent which was received.
|
||||
*/
|
||||
@Subscribe
|
||||
void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the page number and retrieve its contents.
|
||||
*
|
||||
* @param startingEntry The index of the first file in the group to include
|
||||
* in this page.
|
||||
*/
|
||||
private synchronized void setPage(int startingEntry) {
|
||||
@Subscribe
|
||||
private synchronized void setPage(int startingEntry
|
||||
) {
|
||||
int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
|
||||
synchronized (this) {
|
||||
if (pageWorker != null && !pageWorker.isDone()) {
|
||||
@@ -376,11 +319,17 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
centralRepo = CentralRepository.getInstance();
|
||||
} catch (CentralRepoException ex) {
|
||||
centralRepo = null;
|
||||
logger.log(Level.SEVERE, "Error loading central repository database, no central repository options will be available for File Discovery", ex);
|
||||
logger.log(Level.SEVERE, "Error loading central repository database, no central repository options will be available for Discovery", ex);
|
||||
}
|
||||
}
|
||||
pageWorker = new PageWorker(searchFilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupKey, startingEntry, pageSize, resultType, centralRepo);
|
||||
pageWorker.execute();
|
||||
if (groupSize != 0) {
|
||||
pageWorker = new PageWorker(searchFilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupKey, startingEntry, pageSize, resultType, centralRepo);
|
||||
pageWorker.execute();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
pageSizeComboBox.setEnabled(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,15 +374,15 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
||||
javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
||||
javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
||||
javax.swing.JSplitPane resultsSplitPane = new javax.swing.JSplitPane();
|
||||
javax.swing.JPanel instancesPanel = new javax.swing.JPanel();
|
||||
javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane();
|
||||
instancesList = new javax.swing.JList<>();
|
||||
resultsViewerPanel = new javax.swing.JPanel();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(777, 475));
|
||||
setMinimumSize(new java.awt.Dimension(700, 200));
|
||||
setPreferredSize(new java.awt.Dimension(700, 700));
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
pagingPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
pagingPanel.setMinimumSize(new java.awt.Dimension(400, 39));
|
||||
pagingPanel.setPreferredSize(new java.awt.Dimension(700, 39));
|
||||
pagingPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
previousPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
|
||||
@@ -516,6 +465,8 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
pagingPanel.add(gotoPageLabel, gridBagConstraints);
|
||||
|
||||
gotoPageField.setEnabled(false);
|
||||
gotoPageField.setMinimumSize(new java.awt.Dimension(30, 22));
|
||||
gotoPageField.setName(""); // NOI18N
|
||||
gotoPageField.setPreferredSize(new java.awt.Dimension(26, 22));
|
||||
gotoPageField.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
@@ -580,63 +531,12 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
pagingPanel.add(filler4, gridBagConstraints);
|
||||
|
||||
resultsSplitPane.setDividerLocation(380);
|
||||
resultsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||
resultsSplitPane.setResizeWeight(1.0);
|
||||
resultsSplitPane.setToolTipText(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.resultsSplitPane.toolTipText")); // NOI18N
|
||||
resultsSplitPane.setLastDividerLocation(180);
|
||||
resultsSplitPane.setOpaque(false);
|
||||
resultsSplitPane.setPreferredSize(new java.awt.Dimension(777, 440));
|
||||
add(pagingPanel, java.awt.BorderLayout.PAGE_START);
|
||||
|
||||
instancesPanel.setPreferredSize(new java.awt.Dimension(775, 68));
|
||||
|
||||
instancesScrollPane.setPreferredSize(new java.awt.Dimension(775, 60));
|
||||
|
||||
instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.instancesList.border.title"))); // NOI18N
|
||||
instancesList.setModel(instancesListModel);
|
||||
instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
instancesList.setCellRenderer(new InstancesCellRenderer());
|
||||
instancesList.setVisibleRowCount(2);
|
||||
instancesScrollPane.setViewportView(instancesList);
|
||||
|
||||
javax.swing.GroupLayout instancesPanelLayout = new javax.swing.GroupLayout(instancesPanel);
|
||||
instancesPanel.setLayout(instancesPanelLayout);
|
||||
instancesPanelLayout.setHorizontalGroup(
|
||||
instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 779, Short.MAX_VALUE)
|
||||
.addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
instancesPanelLayout.setVerticalGroup(
|
||||
instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 68, Short.MAX_VALUE)
|
||||
.addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup()
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
);
|
||||
|
||||
resultsSplitPane.setRightComponent(instancesPanel);
|
||||
|
||||
resultsViewerPanel.setPreferredSize(new java.awt.Dimension(0, 380));
|
||||
resultsViewerPanel.setMinimumSize(new java.awt.Dimension(0, 160));
|
||||
resultsViewerPanel.setPreferredSize(new java.awt.Dimension(700, 700));
|
||||
resultsViewerPanel.setLayout(new java.awt.BorderLayout());
|
||||
resultsSplitPane.setLeftComponent(resultsViewerPanel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
.addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 436, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
add(resultsViewerPanel, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
/**
|
||||
@@ -719,7 +619,6 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel currentPageLabel;
|
||||
private javax.swing.JTextField gotoPageField;
|
||||
private javax.swing.JList<AbstractFile> instancesList;
|
||||
private javax.swing.JButton nextPageButton;
|
||||
private javax.swing.JComboBox<Integer> pageSizeComboBox;
|
||||
private javax.swing.JButton previousPageButton;
|
||||
@@ -853,29 +752,4 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cell renderer for the instances list.
|
||||
*/
|
||||
private class InstancesCellRenderer extends DefaultListCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
String name = "";
|
||||
if (value instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) value;
|
||||
try {
|
||||
name = file.getUniquePath();
|
||||
} catch (TskCoreException ingored) {
|
||||
name = file.getParentPath() + "/" + file.getName();
|
||||
}
|
||||
|
||||
}
|
||||
setText(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+14
-14
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -25,10 +25,10 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
|
||||
/**
|
||||
* Class to hold the results of the filtering/grouping/sorting operations
|
||||
* Class to hold the results of the filtering/grouping/sorting operations.
|
||||
*/
|
||||
class SearchResults {
|
||||
|
||||
@@ -42,13 +42,13 @@ class SearchResults {
|
||||
private static final long MAX_OUTPUT_FILES = 2000; // For debug UI - maximum number of lines to print
|
||||
|
||||
/**
|
||||
* Create an empty SearchResults object
|
||||
* Create an empty SearchResults object.
|
||||
*
|
||||
* @param groupSortingType The method that should be used to
|
||||
* sortGroupsAndFiles the groups
|
||||
* @param attrType The attribute type to use for grouping
|
||||
* sortGroupsAndFiles the groups.
|
||||
* @param attrType The attribute type to use for grouping.
|
||||
* @param fileSortingMethod The method that should be used to
|
||||
* sortGroupsAndFiles the files in each group
|
||||
* sortGroupsAndFiles the files in each group.
|
||||
*/
|
||||
SearchResults(FileGroup.GroupSortingAlgorithm groupSortingType, FileSearch.AttributeType attrType,
|
||||
FileSorter.SortingMethod fileSortingMethod) {
|
||||
@@ -68,9 +68,9 @@ class SearchResults {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list of ResultFile to the results
|
||||
* Add a list of ResultFile to the results.
|
||||
*
|
||||
* @param files the ResultFiles
|
||||
* @param files The list of ResultFiles to add.
|
||||
*/
|
||||
void add(List<ResultFile> files) {
|
||||
for (ResultFile file : files) {
|
||||
@@ -124,20 +124,20 @@ class SearchResults {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of the groups with counts
|
||||
* Get the names of the groups with counts.
|
||||
*
|
||||
* @return the group names
|
||||
* @return The list of group names.
|
||||
*/
|
||||
List<String> getGroupNamesWithCounts() {
|
||||
return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getFiles().size() + ")").collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result files for the selected group
|
||||
* Get the result files for the selected group.
|
||||
*
|
||||
* @param groupName The name of the group. Can have the size appended.
|
||||
*
|
||||
* @return the list of result files
|
||||
* @return The list of result files.
|
||||
*/
|
||||
List<ResultFile> getResultFilesInGroup(String groupName) {
|
||||
if (groupName != null) {
|
||||
@@ -154,7 +154,7 @@ class SearchResults {
|
||||
/**
|
||||
* Transform the results into a LinkedHashMap with result files.
|
||||
*
|
||||
* @return the grouped and sorted results
|
||||
* @return The grouped and sorted results.
|
||||
*/
|
||||
Map<GroupKey, List<ResultFile>> toLinkedHashMap() throws FileSearchException {
|
||||
Map<GroupKey, List<ResultFile>> map = new LinkedHashMap<>();
|
||||
+10
-9
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import javax.swing.SwingWorker;
|
||||
@@ -25,11 +25,11 @@ import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
* SwingWorker to perform search on a background thread
|
||||
* SwingWorker to perform search on a background thread.
|
||||
*/
|
||||
final class SearchWorker extends SwingWorker<Void, Void> {
|
||||
|
||||
@@ -43,13 +43,14 @@ final class SearchWorker extends SwingWorker<Void, Void> {
|
||||
private final Map<GroupKey, Integer> results = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Create a SwingWorker which performs a search
|
||||
* Create a SwingWorker which performs a search.
|
||||
*
|
||||
* @param centralRepo the central repository being used for the search
|
||||
* @param searchfilters the FileFilters to use for the search
|
||||
* @param groupingAttribute the AttributeType to group by
|
||||
* @param groupSort the Algorithm to sort groups by
|
||||
* @param fileSortMethod the SortingMethod to use for files
|
||||
* @param centralRepo The central repository being used for the
|
||||
* search.
|
||||
* @param searchfilters The FileFilters to use for the search.
|
||||
* @param groupingAttribute The AttributeType to group by.
|
||||
* @param groupSort The Algorithm to sort groups by.
|
||||
* @param fileSortMethod The SortingMethod to use for files.
|
||||
*/
|
||||
SearchWorker(CentralRepository centralRepo, List<FileSearchFiltering.FileFilter> searchfilters, FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod) {
|
||||
centralRepoDb = centralRepo;
|
||||
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="sizeCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="SizeFilterPanel.sizeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="verticalAlignment" type="int" value="1"/>
|
||||
<Property name="verticalTextPosition" type="int" value="1"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="sizeCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="sizeScrollPane" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="sizeScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="sizeScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[27, 27]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="sizeList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<FileSize>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 32767]"/>
|
||||
</Property>
|
||||
<Property name="visibleRowCount" type="int" value="5"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<FileSize>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize;
|
||||
|
||||
/**
|
||||
* Panel to allow configuration of the Size Filter.
|
||||
*/
|
||||
final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates new form SizeFilterPanel.
|
||||
*
|
||||
* @param type The type of result being searched for.
|
||||
*/
|
||||
SizeFilterPanel(FileSearchData.FileType type) {
|
||||
initComponents();
|
||||
setUpSizeFilter(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
sizeCheckbox = new javax.swing.JCheckBox();
|
||||
sizeScrollPane = new javax.swing.JScrollPane();
|
||||
sizeList = new javax.swing.JList<>();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sizeCheckbox, org.openide.util.NbBundle.getMessage(SizeFilterPanel.class, "SizeFilterPanel.sizeCheckbox.text")); // NOI18N
|
||||
sizeCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
sizeCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
sizeCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
sizeCheckbox.setVerticalAlignment(javax.swing.SwingConstants.TOP);
|
||||
sizeCheckbox.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
|
||||
sizeCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
sizeCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setName(""); // NOI18N
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
|
||||
sizeScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
|
||||
|
||||
sizeList.setModel(new DefaultListModel<FileSize>());
|
||||
sizeList.setEnabled(false);
|
||||
sizeList.setMaximumSize(new java.awt.Dimension(32767, 32767));
|
||||
sizeList.setVisibleRowCount(5);
|
||||
sizeScrollPane.setViewportView(sizeList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(sizeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(sizeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void sizeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sizeCheckboxActionPerformed
|
||||
sizeList.setEnabled(sizeCheckbox.isSelected());
|
||||
}//GEN-LAST:event_sizeCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox sizeCheckbox;
|
||||
private javax.swing.JList<FileSize> sizeList;
|
||||
private javax.swing.JScrollPane sizeScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
sizeCheckbox.setSelected(selected);
|
||||
if (sizeCheckbox.isEnabled() && sizeCheckbox.isSelected()) {
|
||||
sizeScrollPane.setEnabled(true);
|
||||
sizeList.setEnabled(true);
|
||||
if (indicesSelected != null) {
|
||||
sizeList.setSelectedIndices(indicesSelected);
|
||||
}
|
||||
} else {
|
||||
sizeScrollPane.setEnabled(false);
|
||||
sizeList.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return sizeCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the file size filter.
|
||||
*/
|
||||
private void setUpSizeFilter(FileSearchData.FileType fileType) {
|
||||
int count = 0;
|
||||
DefaultListModel<FileSize> sizeListModel = (DefaultListModel<FileSize>) sizeList.getModel();
|
||||
sizeListModel.removeAllElements();
|
||||
if (null == fileType) {
|
||||
for (FileSize size : FileSize.values()) {
|
||||
sizeListModel.add(count, size);
|
||||
}
|
||||
} else {
|
||||
List<FileSearchData.FileSize> sizes;
|
||||
switch (fileType) {
|
||||
case VIDEO:
|
||||
sizes = FileSize.getOptionsForVideos();
|
||||
break;
|
||||
case IMAGE:
|
||||
sizes = FileSize.getDefaultSizeOptions();
|
||||
break;
|
||||
case DOCUMENTS:
|
||||
sizes = FileSize.getDefaultSizeOptions();
|
||||
break;
|
||||
default:
|
||||
sizes = new ArrayList<>();
|
||||
break;
|
||||
}
|
||||
for (FileSize size : sizes) {
|
||||
sizeListModel.add(count, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
if (sizeCheckbox.isSelected() && sizeList.getSelectedValuesList().isEmpty()) {
|
||||
return "At least one size must be selected";
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return sizeList;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (sizeCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.SizeFilter(sizeList.getSelectedValuesList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.Timer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class to animate Layouts for a given component.
|
||||
*
|
||||
* @author Greg Cope
|
||||
* https://www.algosome.com/articles/java-swing-panel-animation.html
|
||||
*
|
||||
*/
|
||||
final class SwingAnimator {
|
||||
|
||||
//callback object
|
||||
private final SwingAnimatorCallback callback;
|
||||
|
||||
//Timer to animate on the EDT
|
||||
private Timer timer = null;
|
||||
|
||||
//duration in milliseconds betweeen each firing of the Timer
|
||||
private static final int INITIAL_TIMING = 10;
|
||||
private int timing = INITIAL_TIMING;
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new SwingAnimator.
|
||||
*
|
||||
* @param callback The SwingAnimatorCallback to call.
|
||||
*
|
||||
*/
|
||||
SwingAnimator(SwingAnimatorCallback callback) {
|
||||
this(callback, INITIAL_TIMING);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new SwingAnimator.
|
||||
*
|
||||
* @param callback The SwingAnimatorCallback to call.
|
||||
* @param frameTiming Timing between each call to callback.
|
||||
*
|
||||
*/
|
||||
SwingAnimator(SwingAnimatorCallback callback, int frameTiming) {
|
||||
this.callback = callback;
|
||||
timing = frameTiming;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Checks if this animator is running.
|
||||
*
|
||||
* @return True if the animator is running, false otherwise.
|
||||
*
|
||||
*/
|
||||
boolean isRunning() {
|
||||
if (timer == null) {
|
||||
return false;
|
||||
}
|
||||
return timer.isRunning();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Stops the timer
|
||||
*
|
||||
*/
|
||||
void stop() {
|
||||
if (timer != null) {
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Starts the timer to fire. If the current timer is non-null and running,
|
||||
* this method will first stop the timer before beginning a new one.
|
||||
*/
|
||||
void start() {
|
||||
if (timer != null && timer.isRunning()) {
|
||||
stop();
|
||||
}
|
||||
timer = new Timer(timing, new CallbackListener());
|
||||
timer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ActionListener implements to be passed to the internal timer instance.
|
||||
*
|
||||
*/
|
||||
private class CallbackListener implements ActionListener {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (callback.hasTerminated()) {
|
||||
if (timer == null) {
|
||||
throw new IllegalStateException("Callback listener should not be fired outside of SwingAnimator timer control");
|
||||
}
|
||||
timer.stop();
|
||||
}
|
||||
callback.callback(SwingAnimator.this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
/**
|
||||
*
|
||||
* Callback interface to be notified by a SwingAnimator of a new time frame.
|
||||
*
|
||||
*
|
||||
* @author Greg Cope
|
||||
* https://www.algosome.com/articles/java-swing-panel-animation.html
|
||||
*
|
||||
*/
|
||||
interface SwingAnimatorCallback {
|
||||
|
||||
/**
|
||||
*
|
||||
* Callback method for the SwingAnimator.
|
||||
*
|
||||
* @param caller The object which is calling the Callback.
|
||||
*
|
||||
*/
|
||||
void callback(Object caller);
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns true if the SwingAnimator has terminated.
|
||||
*
|
||||
* @return True if the animator has terminated, false otherwise.
|
||||
*
|
||||
*/
|
||||
boolean hasTerminated();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="userCreatedCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="UserCreatedFilterPanel.userCreatedCheckbox.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 30]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="42" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Form>
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
|
||||
/**
|
||||
* Panel to allow configuration of the User Created Filter.
|
||||
*/
|
||||
final class UserCreatedFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates new form UserCreatedFilterPanel.
|
||||
*/
|
||||
UserCreatedFilterPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
userCreatedCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(userCreatedCheckbox, org.openide.util.NbBundle.getMessage(UserCreatedFilterPanel.class, "UserCreatedFilterPanel.userCreatedCheckbox.text_1")); // NOI18N
|
||||
userCreatedCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
|
||||
userCreatedCheckbox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
userCreatedCheckbox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(250, 30));
|
||||
setPreferredSize(new java.awt.Dimension(250, 30));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 300, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 42, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@Override
|
||||
void configurePanel(boolean selected, int[] indicesSelected) {
|
||||
userCreatedCheckbox.setSelected(selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
JCheckBox getCheckbox() {
|
||||
return userCreatedCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
JLabel getAdditionalLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
String checkForError() {
|
||||
//this filter currently has no errors it generates
|
||||
return "";
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox userCreatedCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
JList<?> getList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
FileSearchFiltering.FileFilter getFilter() {
|
||||
if (userCreatedCheckbox.isSelected()) {
|
||||
return new FileSearchFiltering.UserCreatedFilter();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasPanel() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.4" 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,0,73,0,0,1,24"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="videoFiltersScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="videoFiltersPanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[223, 66]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="videoFiltersSplitPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" 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 min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="videoFiltersSplitPane" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="videoFiltersSplitPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Step 2: Filter which videos to show">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="VideoFilterPanel.videoFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 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.discovery;
|
||||
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
/**
|
||||
* Panel for displaying all filters available for the searches of type Video.
|
||||
*/
|
||||
final class VideoFilterPanel extends AbstractFiltersPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final FileSearchData.FileType FILE_TYPE = FileSearchData.FileType.VIDEO;
|
||||
|
||||
/**
|
||||
* Creates new form VideoFilterPanel.
|
||||
*/
|
||||
VideoFilterPanel() {
|
||||
super();
|
||||
initComponents();
|
||||
addFilter(new SizeFilterPanel(FileSearchData.FileType.VIDEO), false, null, 0);
|
||||
addFilter(new DataSourceFilterPanel(), false, null, 0);
|
||||
int[] pastOccurrencesIndices;
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
pastOccurrencesIndices = new int[]{0};
|
||||
} else {
|
||||
pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7};
|
||||
}
|
||||
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
|
||||
addFilter(new UserCreatedFilterPanel(), false, null, 1);
|
||||
addFilter(new HashSetFilterPanel(), false, null, 1);
|
||||
addFilter(new InterestingItemsFilterPanel(), false, null, 1);
|
||||
addFilter(new ObjectDetectedFilterPanel(), false, null, 1);
|
||||
addFilter(new ParentFolderFilterPanel(), false, null, 1);
|
||||
addPanelsToScrollPane(videoFiltersSplitPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
javax.swing.JScrollPane videoFiltersScrollPane = new javax.swing.JScrollPane();
|
||||
javax.swing.JPanel videoFiltersPanel = new javax.swing.JPanel();
|
||||
videoFiltersSplitPane = new javax.swing.JSplitPane();
|
||||
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
videoFiltersPanel.setPreferredSize(new java.awt.Dimension(223, 66));
|
||||
|
||||
videoFiltersSplitPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(VideoFilterPanel.class, "VideoFilterPanel.videoFiltersSplitPane.border.title"))); // NOI18N
|
||||
videoFiltersSplitPane.setResizeWeight(0.5);
|
||||
|
||||
javax.swing.GroupLayout videoFiltersPanelLayout = new javax.swing.GroupLayout(videoFiltersPanel);
|
||||
videoFiltersPanel.setLayout(videoFiltersPanelLayout);
|
||||
videoFiltersPanelLayout.setHorizontalGroup(
|
||||
videoFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(videoFiltersPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(videoFiltersSplitPane)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
videoFiltersPanelLayout.setVerticalGroup(
|
||||
videoFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(videoFiltersPanelLayout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(videoFiltersSplitPane)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
videoFiltersScrollPane.setViewportView(videoFiltersPanel);
|
||||
|
||||
add(videoFiltersScrollPane, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
@Override
|
||||
FileSearchData.FileType getFileType() {
|
||||
return FILE_TYPE;
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JSplitPane videoFiltersSplitPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
+6
-6
@@ -78,13 +78,13 @@
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/red-circle-exclamation.png"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@@ -94,13 +94,13 @@
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
+11
-10
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
@@ -43,9 +43,9 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
|
||||
private static final int BYTE_UNIT_CONVERSION = 1000;
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final int MAX_NAME_STRING = 120;
|
||||
|
||||
|
||||
/**
|
||||
* Creates new form VideoThumbnailPanel
|
||||
* Creates new form VideoThumbnailPanel.
|
||||
*/
|
||||
VideoThumbnailPanel() {
|
||||
initComponents();
|
||||
@@ -55,7 +55,8 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
|
||||
/**
|
||||
* Add the thumbnails to the panel.
|
||||
*
|
||||
* @param thumbnailWrapper
|
||||
* @param thumbnailWrapper The object which contains the video thumbnails to
|
||||
* add.
|
||||
*/
|
||||
private void addThumbnails(VideoThumbnailsWrapper thumbnailWrapper) {
|
||||
imagePanel.removeAll();
|
||||
@@ -112,14 +113,14 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
|
||||
imagePanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
|
||||
deletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
||||
deletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
deletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
deletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.filequery.DiscoveryUiUtils.getIconSize()));
|
||||
deletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
deletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
deletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
+2
-2
@@ -35,11 +35,11 @@
|
||||
</Property>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new org.sleuthkit.autopsy.filequery.VideoThumbnailPanel()" type="code"/>
|
||||
<Connection code="new org.sleuthkit.autopsy.discovery.VideoThumbnailPanel()" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.filequery.VideoThumbnailsWrapper>"/>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.discovery.VideoThumbnailsWrapper>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
+6
-6
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -28,15 +28,15 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
* A JPanel to display video thumbnails.
|
||||
*
|
||||
*/
|
||||
public class VideoThumbnailViewer extends javax.swing.JPanel {
|
||||
final class VideoThumbnailViewer extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DefaultListModel<VideoThumbnailsWrapper> thumbnailListModel = new DefaultListModel<>();
|
||||
|
||||
/**
|
||||
* Creates new form VideoThumbnailViewer
|
||||
* Creates new form VideoThumbnailViewer.
|
||||
*/
|
||||
public VideoThumbnailViewer() {
|
||||
VideoThumbnailViewer() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class VideoThumbnailViewer extends javax.swing.JPanel {
|
||||
|
||||
thumbnailList.setModel(thumbnailListModel);
|
||||
thumbnailList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
thumbnailList.setCellRenderer(new VideoThumbnailPanel());
|
||||
thumbnailList.setCellRenderer(new org.sleuthkit.autopsy.discovery.VideoThumbnailPanel());
|
||||
thumbnailListScrollPane.setViewportView(thumbnailList);
|
||||
|
||||
add(thumbnailListScrollPane, java.awt.BorderLayout.CENTER);
|
||||
@@ -112,7 +112,7 @@ public class VideoThumbnailViewer extends javax.swing.JPanel {
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JList<VideoThumbnailsWrapper> thumbnailList;
|
||||
private javax.swing.JList<org.sleuthkit.autopsy.discovery.VideoThumbnailsWrapper> thumbnailList;
|
||||
private javax.swing.JScrollPane thumbnailListScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.util.ArrayList;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user