Merge branch 'develop' of github.com:sleuthkit/autopsy into 7187-translationMap

This commit is contained in:
Greg DiCristofaro 2021-01-11 12:11:12 -05:00
commit c2a4ececfb
35 changed files with 459 additions and 212 deletions

View File

@ -11,30 +11,27 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,0,0,0,0,0"/>
</AuxValues> </AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> <Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="detailsScrollPane" alignment="1" pref="62" 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="detailsScrollPane" pref="93" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="detailsPanel"> <Container class="javax.swing.JScrollPane" name="detailsScrollPane">
<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> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container> </Container>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -37,7 +37,6 @@ import java.util.logging.Level;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -82,6 +81,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private final GridBagLayout gridBagLayout = new GridBagLayout(); private final GridBagLayout gridBagLayout = new GridBagLayout();
private final GridBagConstraints gridBagConstraints = new GridBagConstraints(); private final GridBagConstraints gridBagConstraints = new GridBagConstraints();
private final Map<Integer, Integer[]> orderingMap = new HashMap<>(); private final Map<Integer, Integer[]> orderingMap = new HashMap<>();
private final javax.swing.JPanel detailsPanel = new javax.swing.JPanel();
/** /**
* Creates new form GeneralPurposeArtifactViewer. * Creates new form GeneralPurposeArtifactViewer.
@ -90,6 +90,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
public GeneralPurposeArtifactViewer() { public GeneralPurposeArtifactViewer() {
addOrderings(); addOrderings();
initComponents(); initComponents();
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
detailsPanel.setLayout(gridBagLayout); detailsPanel.setLayout(gridBagLayout);
} }
@ -161,8 +162,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
} }
updateView(artifact, attributeMap, dataSourceName, sourceFileName); updateView(artifact, attributeMap, dataSourceName, sourceFileName);
} }
detailsScrollPane.setViewportView(detailsPanel);
detailsScrollPane.revalidate();
revalidate(); revalidate();
repaint();
} }
/** /**
@ -172,7 +174,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private void resetComponent() { private void resetComponent() {
// clear the panel // clear the panel
detailsPanel.removeAll(); detailsPanel.removeAll();
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START; detailsPanel.setLayout(gridBagLayout);
detailsPanel.revalidate();
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.gridx = LABEL_COLUMN; gridBagConstraints.gridx = LABEL_COLUMN;
gridBagConstraints.weighty = 0.0; gridBagConstraints.weighty = 0.0;
@ -183,14 +186,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
public Component getComponent() {
// Slap a vertical scrollbar on the panel
return new JScrollPane(this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
public boolean isSupported(BlackboardArtifact artifact) { public boolean isSupported(BlackboardArtifact artifact) {
return (artifact != null) return (artifact != null)
&& (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() && (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()
@ -218,22 +213,20 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
detailsPanel = new javax.swing.JPanel(); detailsScrollPane = new javax.swing.JScrollPane();
setLayout(new java.awt.BorderLayout()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel); layout.setHorizontalGroup(
detailsPanel.setLayout(detailsPanelLayout); layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
detailsPanelLayout.setHorizontalGroup( .addComponent(detailsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 62, Short.MAX_VALUE)
detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
); );
detailsPanelLayout.setVerticalGroup( layout.setVerticalGroup(
detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup()
.addComponent(detailsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE)
.addGap(0, 0, 0))
); );
add(detailsPanel, java.awt.BorderLayout.PAGE_START);
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
/** /**
@ -257,7 +250,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFilePath) { private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFilePath) {
final Integer artifactTypeId = artifact.getArtifactTypeID(); final Integer artifactTypeId = artifact.getArtifactTypeID();
if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) { if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) {
addDetailsHeader(artifactTypeId); JTextPane firstTextPane = addDetailsHeader(artifactTypeId);
Integer[] orderingArray = orderingMap.get(artifactTypeId); Integer[] orderingArray = orderingMap.get(artifactTypeId);
if (orderingArray == null) { if (orderingArray == null) {
orderingArray = DEFAULT_ORDERING; orderingArray = DEFAULT_ORDERING;
@ -282,7 +275,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
addNameValueRow(bba.getAttributeType().getDisplayName(), displayString); addNameValueRow(bba.getAttributeType().getDisplayName(), displayString);
} else { } else {
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString()); addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
} }
} }
} }
@ -311,7 +303,11 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath); addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath);
// add veritcal glue at the end // add veritcal glue at the end
addPageEndGlue(); addPageEndGlue();
if (firstTextPane != null) {
firstTextPane.setCaretPosition(0);
}
} }
detailsPanel.revalidate();
} }
/** /**
@ -353,7 +349,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
"GeneralPurposeArtifactViewer.details.searchHeader=Web Search", "GeneralPurposeArtifactViewer.details.searchHeader=Web Search",
"GeneralPurposeArtifactViewer.details.cachedHeader=Cached File", "GeneralPurposeArtifactViewer.details.cachedHeader=Cached File",
"GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",}) "GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",})
private void addDetailsHeader(int artifactTypeId) { private JTextPane addDetailsHeader(int artifactTypeId) {
String header; String header;
if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) { if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader(); header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader();
@ -370,7 +366,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
} else { } else {
header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader(); header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader();
} }
addHeader(header); return addHeader(header);
} }
/** /**
@ -381,16 +377,21 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
* @return JLabel Heading label added. * @return JLabel Heading label added.
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private JLabel addHeader(String headerString) { private JTextPane addHeader(String headerString) {
// create label for heading // create label for heading
javax.swing.JLabel headingLabel = new javax.swing.JLabel(); javax.swing.JTextPane headingLabel = new javax.swing.JTextPane();
headingLabel.setOpaque(false);
headingLabel.setFocusable(false);
headingLabel.setEditable(false);
// add a blank line before the start of new section, unless it's // add a blank line before the start of new section, unless it's
// the first section // the first section
if (gridBagConstraints.gridy != 0) { if (gridBagConstraints.gridy != 0) {
gridBagConstraints.gridy++; gridBagConstraints.gridy++;
detailsPanel.add(new javax.swing.JLabel(" "), gridBagConstraints); // add to panel
addToPanel(new javax.swing.JLabel(" "));
addLineEndGlue(); addLineEndGlue();
} headingLabel.setFocusable(false);
}
gridBagConstraints.gridy++; gridBagConstraints.gridy++;
gridBagConstraints.gridx = LABEL_COLUMN;; gridBagConstraints.gridx = LABEL_COLUMN;;
// let the header span all of the row // let the header span all of the row
@ -401,7 +402,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
// make it large and bold // make it large and bold
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2)); headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
// add to panel // add to panel
detailsPanel.add(headingLabel, gridBagConstraints); addToPanel(headingLabel);
// reset constraints to normal // reset constraints to normal
gridBagConstraints.gridwidth = LABEL_WIDTH; gridBagConstraints.gridwidth = LABEL_WIDTH;
// add line end glue // add line end glue
@ -417,9 +418,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
* @param keyString Key name to display. * @param keyString Key name to display.
* @param valueString Value string to display. * @param valueString Value string to display.
*/ */
private void addNameValueRow(String keyString, String valueString) { private JTextPane addNameValueRow(String keyString, String valueString) {
addKeyAtCol(keyString); addKeyAtCol(keyString);
addValueAtCol(valueString); return addValueAtCol(valueString);
} }
/** /**
@ -432,7 +433,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
gridBagConstraints.weightx = GLUE_WEIGHT_X; // take up all the horizontal space gridBagConstraints.weightx = GLUE_WEIGHT_X; // take up all the horizontal space
gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.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)); javax.swing.Box.Filler horizontalFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 0));
detailsPanel.add(horizontalFiller, gridBagConstraints); // add to panel
addToPanel(horizontalFiller);
// restore fill & weight // restore fill & weight
gridBagConstraints.fill = GridBagConstraints.NONE; gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = TEXT_WEIGHT_X; gridBagConstraints.weightx = TEXT_WEIGHT_X;
@ -446,7 +448,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
gridBagConstraints.weighty = 1.0; // take up all the vertical space gridBagConstraints.weighty = 1.0; // take up all the vertical space
gridBagConstraints.fill = GridBagConstraints.VERTICAL; gridBagConstraints.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)); javax.swing.Box.Filler vertFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(0, 32767));
detailsPanel.add(vertFiller, gridBagConstraints); // add to panel
addToPanel(vertFiller);
} }
/** /**
@ -459,16 +462,22 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private JLabel addKeyAtCol(String keyString) { private JLabel addKeyAtCol(String keyString) {
// create label // create label
javax.swing.JLabel keyLabel = new javax.swing.JLabel(); javax.swing.JLabel keyLabel = new javax.swing.JLabel();
keyLabel.setFocusable(false);
gridBagConstraints.gridy++; gridBagConstraints.gridy++;
gridBagConstraints.gridx = LABEL_COLUMN; gridBagConstraints.gridx = LABEL_COLUMN;
gridBagConstraints.gridwidth = LABEL_WIDTH; gridBagConstraints.gridwidth = LABEL_WIDTH;
// set text // set text
keyLabel.setText(keyString + ": "); keyLabel.setText(keyString + ": ");
// add to panel // add to panel
detailsPanel.add(keyLabel, gridBagConstraints); addToPanel(keyLabel);
return keyLabel; return keyLabel;
} }
private void addToPanel(Component comp) {
detailsPanel.add(comp, gridBagConstraints);
detailsPanel.revalidate();
}
/** /**
* Adds a value string to the panel at specified column. * Adds a value string to the panel at specified column.
* *
@ -479,6 +488,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private JTextPane addValueAtCol(String valueString) { private JTextPane addValueAtCol(String valueString) {
// create label, // create label,
JTextPane valueField = new JTextPane(); JTextPane valueField = new JTextPane();
valueField.setFocusable(false);
valueField.setEditable(false); valueField.setEditable(false);
valueField.setOpaque(false); valueField.setOpaque(false);
gridBagConstraints.gridx = VALUE_COLUMN; gridBagConstraints.gridx = VALUE_COLUMN;
@ -488,8 +498,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
cloneConstraints.fill = GridBagConstraints.BOTH; cloneConstraints.fill = GridBagConstraints.BOTH;
// set text // set text
valueField.setText(valueString); valueField.setText(valueString);
// scroll to start of text
valueField.setCaretPosition(0);
// attach a right click menu with Copy option // attach a right click menu with Copy option
valueField.addMouseListener(new java.awt.event.MouseAdapter() { valueField.addMouseListener(new java.awt.event.MouseAdapter() {
@Override @Override
@ -497,8 +505,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
valueLabelMouseClicked(evt, valueField); valueLabelMouseClicked(evt, valueField);
} }
}); });
// add label to panel // add label to panel with cloned contraintsF
detailsPanel.add(valueField, cloneConstraints); detailsPanel.add(valueField, cloneConstraints);
revalidate();
// end the line // end the line
addLineEndGlue(); addLineEndGlue();
return valueField; return valueField;
@ -531,6 +540,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel detailsPanel; private javax.swing.JScrollPane detailsScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -201,7 +201,7 @@ public class DomainSearch {
* @throws DiscoveryException if unable to get the artifacts or the date * @throws DiscoveryException if unable to get the artifacts or the date
* attributes from an artifact. * attributes from an artifact.
*/ */
public List<MiniTimelineResult> getAllArtifactsForDomain(SleuthkitCase sleuthkitCase, String domain) throws DiscoveryException, InterruptedException { public List<MiniTimelineResult> getAllArtifactsForDomain(SleuthkitCase sleuthkitCase, String domain) throws DiscoveryException {
List<BlackboardArtifact> artifacts = new ArrayList<>(); List<BlackboardArtifact> artifacts = new ArrayList<>();
Map<String, List<BlackboardArtifact>> dateMap = new HashMap<>(); Map<String, List<BlackboardArtifact>> dateMap = new HashMap<>();
if (!StringUtils.isBlank(domain)) { if (!StringUtils.isBlank(domain)) {

View File

@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.discovery.ui;
import java.awt.Component; import java.awt.Component;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
@ -30,14 +29,13 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
*/ */
public abstract class AbstractArtifactDetailsPanel extends JPanel { public abstract class AbstractArtifactDetailsPanel extends JPanel {
private static final long serialVersionUID = 1L;
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public Component getComponent() { public Component getComponent() {
// Slap a vertical scrollbar on the panel. return this;
return new JScrollPane(this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
} }
private static final long serialVersionUID = 1L;
/** /**
* Called to display the contents of the given artifact. * Called to display the contents of the given artifact.
* *

View File

@ -4,7 +4,7 @@
<Properties> <Properties>
<Property name="opaque" type="boolean" value="false"/> <Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 0]"/> <Dimension value="[350, 10]"/>
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
@ -22,12 +22,12 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" pref="400" max="32767" attributes="0"/> <Component id="jScrollPane1" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="0" max="32767" attributes="0"/> <Component id="jScrollPane1" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
@ -37,9 +37,13 @@
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/> <Border info="null"/>
</Property> </Property>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/> <Dimension value="[0, 0]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[350, 10]"/>
</Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>

View File

@ -94,11 +94,15 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
@Override @Override
BlackboardArtifact getSelectedArtifact() { BlackboardArtifact getSelectedArtifact() {
int selectedIndex = artifactsTable.getSelectionModel().getLeadSelectionIndex(); if (artifactsTable.getModel() instanceof DomainArtifactTableModel) {
if (selectedIndex < artifactsTable.getSelectionModel().getMinSelectionIndex() || artifactsTable.getSelectionModel().getMaxSelectionIndex() < 0 || selectedIndex > artifactsTable.getSelectionModel().getMaxSelectionIndex()) { int selectedIndex = artifactsTable.getSelectionModel().getLeadSelectionIndex();
if (selectedIndex < artifactsTable.getSelectionModel().getMinSelectionIndex() || artifactsTable.getSelectionModel().getMaxSelectionIndex() < 0 || selectedIndex > artifactsTable.getSelectionModel().getMaxSelectionIndex()) {
return null;
}
return tableModel.getArtifactByRow(artifactsTable.convertRowIndexToModel(selectedIndex));
} else {
return null; return null;
} }
return tableModel.getArtifactByRow(artifactsTable.convertRowIndexToModel(selectedIndex));
} }
@Override @Override
@ -124,7 +128,12 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
void addArtifacts(List<BlackboardArtifact> artifactList) { void addArtifacts(List<BlackboardArtifact> artifactList) {
tableModel.setContents(artifactList); if (!artifactList.isEmpty()) {
artifactsTable.setModel(tableModel);
tableModel.setContents(artifactList);
} else {
artifactsTable.setModel(new EmptyTableModel());
}
artifactsTable.validate(); artifactsTable.validate();
artifactsTable.repaint(); artifactsTable.repaint();
tableModel.fireTableDataChanged(); tableModel.fireTableDataChanged();
@ -152,10 +161,12 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
artifactsTable = new javax.swing.JTable(); artifactsTable = new javax.swing.JTable();
setOpaque(false); setOpaque(false);
setPreferredSize(new java.awt.Dimension(300, 0)); setPreferredSize(new java.awt.Dimension(350, 10));
jScrollPane1.setBorder(null); jScrollPane1.setBorder(null);
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0)); jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0));
jScrollPane1.setPreferredSize(new java.awt.Dimension(350, 10));
artifactsTable.setAutoCreateRowSorter(true); artifactsTable.setAutoCreateRowSorter(true);
artifactsTable.setModel(tableModel); artifactsTable.setModel(tableModel);
@ -166,11 +177,11 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 0, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -357,6 +368,45 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
} }
} }
} }
/**
* Table model which displays only that no results were found.
*/
private class EmptyTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
@Override
public int getRowCount() {
return 1;
}
@Override
public int getColumnCount() {
return 1;
}
@NbBundle.Messages({"ArtifactsListPanel.noResultsFound.text=No results found"})
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return Bundle.ArtifactsListPanel_noResultsFound_text();
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return Bundle.ArtifactsListPanel_dateColumn_name();
case 1:
return Bundle.ArtifactsListPanel_titleColumn_name();
case 2:
return Bundle.ArtifactsListPanel_mimeTypeColumn_name();
default:
return "";
}
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTable artifactsTable; private javax.swing.JTable artifactsTable;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables

View File

@ -61,7 +61,8 @@ class ArtifactsWorker extends SwingWorker<List<BlackboardArtifact>, Void> {
return domainSearch.getArtifacts(new DomainSearchArtifactsRequest(Case.getCurrentCase().getSleuthkitCase(), domain, artifactType)); return domainSearch.getArtifacts(new DomainSearchArtifactsRequest(Case.getCurrentCase().getSleuthkitCase(), domain, artifactType));
} catch (DiscoveryException ex) { } catch (DiscoveryException ex) {
if (ex.getCause() instanceof InterruptedException) { if (ex.getCause() instanceof InterruptedException) {
logger.log(Level.INFO, "MiniTimeline search was cancelled or interrupted for domain: {0}", domain); this.cancel(true);
//ignore the exception as it was cancelled while the cache was performing its get and we support cancellation
} else { } else {
throw ex; throw ex;
} }
@ -84,6 +85,6 @@ class ArtifactsWorker extends SwingWorker<List<BlackboardArtifact>, Void> {
//Worker was cancelled after previously finishing its background work, exception ignored to cut down on non-helpful logging //Worker was cancelled after previously finishing its background work, exception ignored to cut down on non-helpful logging
} }
} }
} }
} }

View File

@ -61,4 +61,5 @@ FileDetailsPanel.instancesList.border.title=Instances
CookieDetailsPanel.jLabel1.text=Artifact: CookieDetailsPanel.jLabel1.text=Artifact:
CookieDetailsPanel.jLabel2.text= CookieDetailsPanel.jLabel2.text=
PreviouslyNotableFilterPanel.text_1=Include only previously notable domains PreviouslyNotableFilterPanel.text_1=Include only previously notable domains
KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type
LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel

View File

@ -3,6 +3,7 @@ ArtifactMenuMouseAdapter_label=Extract Files
ArtifactsListPanel.dateColumn.name=Date/Time ArtifactsListPanel.dateColumn.name=Date/Time
ArtifactsListPanel.fileNameColumn.name=Name ArtifactsListPanel.fileNameColumn.name=Name
ArtifactsListPanel.mimeTypeColumn.name=MIME Type ArtifactsListPanel.mimeTypeColumn.name=MIME Type
ArtifactsListPanel.noResultsFound.text=No results found
ArtifactsListPanel.termColumn.name=Term ArtifactsListPanel.termColumn.name=Term
ArtifactsListPanel.titleColumn.name=Title ArtifactsListPanel.titleColumn.name=Title
ArtifactsListPanel.urlColumn.name=URL ArtifactsListPanel.urlColumn.name=URL
@ -52,7 +53,7 @@ DocumentPanel.numberOfImages.noImages=No images
# {0} - numberOfImages # {0} - numberOfImages
DocumentPanel.numberOfImages.text=1 of {0} images DocumentPanel.numberOfImages.text=1 of {0} images
DocumentWrapper.previewInitialValue=Preview not generated yet. DocumentWrapper.previewInitialValue=Preview not generated yet.
DomainDetailsPanel.miniTimelineTitle.text=Mini Timeline DomainDetailsPanel.miniTimelineTitle.text=Timeline
# {0} - startDate # {0} - startDate
# {1} - endDate # {1} - endDate
DomainSummaryPanel.activity.text=Activity: {0} to {1} DomainSummaryPanel.activity.text=Activity: {0} to {1}
@ -68,12 +69,16 @@ ImageThumbnailPanel.isDeleted.text=All instances of file are deleted.
# {0} - otherInstanceCount # {0} - otherInstanceCount
ImageThumbnailPanel.nameLabel.more.text=\ and {0} more ImageThumbnailPanel.nameLabel.more.text=\ and {0} more
InterestingItemsFilterPanel.error.text=At least one interesting file set name must be selected. InterestingItemsFilterPanel.error.text=At least one interesting file set name must be selected.
LoadingPanel.loading.text=Loading, please wait.
# {0} - resultInfo
LoadingPanel.retrieving.text=Retrieving results for {0}.
MiniTimelineArtifactListPanel.descriptionColumn.name=\ Description MiniTimelineArtifactListPanel.descriptionColumn.name=\ Description
MiniTimelineArtifactListPanel.typeColumn.name=Result Type MiniTimelineArtifactListPanel.typeColumn.name=Result Type
MiniTimelineArtifactListPanel.value.noValue=No value available. MiniTimelineArtifactListPanel.value.noValue=No value available.
MiniTimelineDateListPanel.countColumn.name=Count MiniTimelineDateListPanel.countColumn.name=Count
MiniTimelineDateListPanel.dateColumn.name=Date MiniTimelineDateListPanel.dateColumn.name=Date
MiniTimelineDateListPanel.value.noValue=No value available. MiniTimelineDateListPanel.value.noValue=No value available.
MiniTimelinePanel.loadingPanel.details=the Timeline view
MonthAbbreviation.aprilAbbrev=Apr MonthAbbreviation.aprilAbbrev=Apr
MonthAbbreviation.augustAbbrev=Aug MonthAbbreviation.augustAbbrev=Aug
MonthAbbreviation.decemberAbbrev=Dec MonthAbbreviation.decemberAbbrev=Dec
@ -165,6 +170,7 @@ CookieDetailsPanel.jLabel1.text=Artifact:
CookieDetailsPanel.jLabel2.text= CookieDetailsPanel.jLabel2.text=
PreviouslyNotableFilterPanel.text_1=Include only previously notable domains PreviouslyNotableFilterPanel.text_1=Include only previously notable domains
KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type
LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel
VideoThumbnailPanel.bytes.text=bytes VideoThumbnailPanel.bytes.text=bytes
VideoThumbnailPanel.deleted.text=All instances of file are deleted. VideoThumbnailPanel.deleted.text=All instances of file are deleted.
VideoThumbnailPanel.gigaBytes.text=GB VideoThumbnailPanel.gigaBytes.text=GB

View File

@ -60,9 +60,11 @@ public final class DiscoveryTopComponent extends TopComponent {
private volatile static int previousDividerLocation = 250; private volatile static int previousDividerLocation = 250;
private final GroupListPanel groupListPanel; private final GroupListPanel groupListPanel;
private final ResultsPanel resultsPanel; private final ResultsPanel resultsPanel;
private JPanel detailsPanel = new JPanel();
private String selectedDomainTabName; private String selectedDomainTabName;
private Type searchType; private Type searchType;
private int dividerLocation = JSplitPane.UNDEFINED_CONDITION; private int dividerLocation = JSplitPane.UNDEFINED_CONDITION;
private SwingAnimator animator = null; private SwingAnimator animator = null;
/** /**
@ -83,25 +85,25 @@ public final class DiscoveryTopComponent extends TopComponent {
} }
}); });
rightSplitPane.setTopComponent(resultsPanel);
resetBottomComponent();
rightSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { rightSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)) { if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)
&& ((animator == null || !animator.isRunning())
&& evt.getNewValue() instanceof Integer
&& evt.getOldValue() instanceof Integer
&& ((int) evt.getNewValue() + 5) < (rightSplitPane.getHeight() - rightSplitPane.getDividerSize())
&& (JSplitPane.UNDEFINED_CONDITION != (int) evt.getNewValue())
&& ((int) evt.getOldValue() != JSplitPane.UNDEFINED_CONDITION))) {
//Only change the saved location when it was a manual change by the user and not the animation or the window opening initially //Only change the saved location when it was a manual change by the user and not the animation or the window opening initially
if ((animator == null || !animator.isRunning()) previousDividerLocation = (int) evt.getNewValue();
&& evt.getNewValue() instanceof Integer
&& evt.getOldValue() instanceof Integer
&& ((int) evt.getNewValue() + 5) < (rightSplitPane.getHeight() - rightSplitPane.getDividerSize())
&& (JSplitPane.UNDEFINED_CONDITION != (int) evt.getNewValue())
&& ((int) evt.getOldValue() != JSplitPane.UNDEFINED_CONDITION)) {
previousDividerLocation = (int) evt.getNewValue();
}
} }
} }
}); }
rightSplitPane.setTopComponent(resultsPanel); );
rightSplitPane.setBottomComponent(new JPanel());
} }
/** /**
@ -131,7 +133,8 @@ public final class DiscoveryTopComponent extends TopComponent {
* @return The open DiscoveryTopComponent or null if it has not been opened. * @return The open DiscoveryTopComponent or null if it has not been opened.
*/ */
public static DiscoveryTopComponent getTopComponent() { public static DiscoveryTopComponent getTopComponent() {
return (DiscoveryTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID); DiscoveryTopComponent discoveryTopComp = (DiscoveryTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
return discoveryTopComp;
} }
/** /**
@ -153,6 +156,11 @@ public final class DiscoveryTopComponent extends TopComponent {
DiscoveryEventUtils.getDiscoveryEventBus().register(groupListPanel); DiscoveryEventUtils.getDiscoveryEventBus().register(groupListPanel);
} }
private void resetBottomComponent() {
rightSplitPane.setBottomComponent(new JPanel());
rightSplitPane.setDividerLocation(JSplitPane.UNDEFINED_CONDITION);
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
protected void componentClosed() { protected void componentClosed() {
@ -162,11 +170,11 @@ public final class DiscoveryTopComponent extends TopComponent {
DiscoveryEventUtils.getDiscoveryEventBus().unregister(this); DiscoveryEventUtils.getDiscoveryEventBus().unregister(this);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel); DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel); DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(rightSplitPane.getBottomComponent()); DiscoveryEventUtils.getDiscoveryEventBus().unregister(detailsPanel);
if (rightSplitPane.getBottomComponent() instanceof DomainDetailsPanel) { if (detailsPanel instanceof DomainDetailsPanel) {
selectedDomainTabName = ((DomainDetailsPanel) rightSplitPane.getBottomComponent()).getSelectedTabName(); selectedDomainTabName = ((DomainDetailsPanel) detailsPanel).getSelectedTabName();
} }
rightSplitPane.setDividerLocation(JSplitPane.UNDEFINED_CONDITION); resetBottomComponent();
super.componentClosed(); super.componentClosed();
} }
@ -336,12 +344,13 @@ public final class DiscoveryTopComponent extends TopComponent {
} }
selectedDomainTabName = validateLastSelectedType(searchCompleteEvent); selectedDomainTabName = validateLastSelectedType(searchCompleteEvent);
DomainDetailsPanel domainDetailsPanel = new DomainDetailsPanel(); DomainDetailsPanel domainDetailsPanel = new DomainDetailsPanel();
rightSplitPane.setBottomComponent(domainDetailsPanel);
domainDetailsPanel.configureArtifactTabs(selectedDomainTabName); domainDetailsPanel.configureArtifactTabs(selectedDomainTabName);
detailsPanel = domainDetailsPanel;
} else { } else {
rightSplitPane.setBottomComponent(new FileDetailsPanel()); detailsPanel = new FileDetailsPanel();
} }
DiscoveryEventUtils.getDiscoveryEventBus().register(rightSplitPane.getBottomComponent()); rightSplitPane.setBottomComponent(detailsPanel);
DiscoveryEventUtils.getDiscoveryEventBus().register(detailsPanel);
descriptionText += searchCompleteEvent.getFilters().stream().map(AbstractFilter::getDesc).collect(Collectors.joining("; ")); descriptionText += searchCompleteEvent.getFilters().stream().map(AbstractFilter::getDesc).collect(Collectors.joining("; "));
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(descriptionText)); progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(descriptionText));
progressMessageTextArea.setCaretPosition(0); progressMessageTextArea.setCaretPosition(0);

View File

@ -1,13 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Container class="javax.swing.JSplitPane" name="mainSplitPane">
<Properties>
<Property name="dividerLocation" type="int" value="350"/>
<Property name="resizeWeight" type="double" value="0.1"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
</Container>
</NonVisualComponents>
<Properties> <Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/> <Dimension value="[0, 0]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
@ -23,23 +30,4 @@
</AuxValues> </AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</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"/>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -22,7 +22,6 @@ import org.sleuthkit.autopsy.contentviewers.artifactviewers.GeneralPurposeArtifa
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
@ -64,7 +63,8 @@ final class DomainArtifactsTabPanel extends JPanel {
this.artifactType = type; this.artifactType = type;
listPanel = new ArtifactsListPanel(artifactType); listPanel = new ArtifactsListPanel(artifactType);
listPanel.addMouseListener(new ArtifactMenuMouseAdapter(listPanel)); listPanel.addMouseListener(new ArtifactMenuMouseAdapter(listPanel));
jSplitPane1.setLeftComponent(listPanel); mainSplitPane.setLeftComponent(listPanel);
add(mainSplitPane);
setRightComponent(); setRightComponent();
listPanel.addSelectionListener(listener); listPanel.addSelectionListener(listener);
} }
@ -91,7 +91,7 @@ final class DomainArtifactsTabPanel extends JPanel {
break; break;
} }
if (rightPanel != null) { if (rightPanel != null) {
jSplitPane1.setRightComponent(rightPanel.getComponent()); mainSplitPane.setRightComponent(rightPanel.getComponent());
} }
} }
@ -115,10 +115,14 @@ final class DomainArtifactsTabPanel extends JPanel {
this.status = status; this.status = status;
if (status == ArtifactRetrievalStatus.UNPOPULATED) { if (status == ArtifactRetrievalStatus.UNPOPULATED) {
listPanel.clearList(); listPanel.clearList();
if (rightPanel != null){ removeAll();
add(mainSplitPane);
if (rightPanel != null) {
rightPanel.setArtifact(null); rightPanel.setArtifact(null);
} }
} else if (status == ArtifactRetrievalStatus.POPULATING) {
removeAll();
add(new LoadingPanel(artifactType.getDisplayName()));
} }
} }
@ -130,7 +134,7 @@ final class DomainArtifactsTabPanel extends JPanel {
*/ */
@Subscribe @Subscribe
void handleArtifactSearchResultEvent(DiscoveryEventUtils.ArtifactSearchResultEvent artifactresultEvent) { void handleArtifactSearchResultEvent(DiscoveryEventUtils.ArtifactSearchResultEvent artifactresultEvent) {
if (artifactType == artifactresultEvent.getArtifactType()) { if (artifactType == artifactresultEvent.getArtifactType() && status == ArtifactRetrievalStatus.POPULATING) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
listPanel.removeSelectionListener(listener); listPanel.removeSelectionListener(listener);
listPanel.addArtifacts(artifactresultEvent.getListOfArtifacts()); listPanel.addArtifacts(artifactresultEvent.getListOfArtifacts());
@ -138,6 +142,8 @@ final class DomainArtifactsTabPanel extends JPanel {
setEnabled(!listPanel.isEmpty()); setEnabled(!listPanel.isEmpty());
listPanel.addSelectionListener(listener); listPanel.addSelectionListener(listener);
listPanel.selectFirst(); listPanel.selectFirst();
removeAll();
add(mainSplitPane);
revalidate(); revalidate();
repaint(); repaint();
try { try {
@ -169,20 +175,18 @@ final class DomainArtifactsTabPanel extends JPanel {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
jSplitPane1 = new javax.swing.JSplitPane(); mainSplitPane = new javax.swing.JSplitPane();
mainSplitPane.setDividerLocation(350);
mainSplitPane.setResizeWeight(0.1);
setMinimumSize(new java.awt.Dimension(0, 0)); setMinimumSize(new java.awt.Dimension(0, 0));
setPreferredSize(new java.awt.Dimension(0, 0));
setLayout(new java.awt.BorderLayout()); setLayout(new java.awt.BorderLayout());
jSplitPane1.setMinimumSize(new java.awt.Dimension(0, 0));
jSplitPane1.setPreferredSize(new java.awt.Dimension(0, 0));
add(jSplitPane1, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JSplitPane jSplitPane1; private javax.swing.JSplitPane mainSplitPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
/** /**

View File

@ -2,13 +2,13 @@
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties> <Properties>
<Property name="enabled" type="boolean" value="false"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/> <Dimension value="[0, 0]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/> <Dimension value="[0, 0]"/>
</Property> </Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties> </Properties>
<AuxValues> <AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>

View File

@ -63,7 +63,7 @@ final class DomainDetailsPanel extends JPanel {
* *
* @param tabName The name of the tab to select initially. * @param tabName The name of the tab to select initially.
*/ */
@NbBundle.Messages({"DomainDetailsPanel.miniTimelineTitle.text=Mini Timeline"}) @NbBundle.Messages({"DomainDetailsPanel.miniTimelineTitle.text=Timeline"})
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
void configureArtifactTabs(String tabName) { void configureArtifactTabs(String tabName) {
selectedTabName = tabName; selectedTabName = tabName;
@ -104,6 +104,20 @@ final class DomainDetailsPanel extends JPanel {
} }
} }
/**
* Get the status of the currently selected tab.
*
* @return The loading status of the currently selected tab.
*/
DomainArtifactsTabPanel.ArtifactRetrievalStatus getCurrentTabStatus() {
if (jTabbedPane1.getSelectedComponent() instanceof MiniTimelinePanel) {
return ((MiniTimelinePanel) jTabbedPane1.getSelectedComponent()).getStatus();
} else if (jTabbedPane1.getSelectedComponent() instanceof DomainArtifactsTabPanel) {
return ((DomainArtifactsTabPanel) jTabbedPane1.getSelectedComponent()).getStatus();
}
return null;
}
/** /**
* Run the worker which retrieves the list of artifacts for the domain to * Run the worker which retrieves the list of artifacts for the domain to
* populate the details area. * populate the details area.
@ -146,20 +160,19 @@ final class DomainDetailsPanel extends JPanel {
*/ */
@Subscribe @Subscribe
void handlePopulateDomainTabsEvent(DiscoveryEventUtils.PopulateDomainTabsEvent populateEvent) { void handlePopulateDomainTabsEvent(DiscoveryEventUtils.PopulateDomainTabsEvent populateEvent) {
domain = populateEvent.getDomain();
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
resetTabsStatus(); if (StringUtils.isBlank(populateEvent.getDomain())) {
selectTab(); resetTabsStatus();
Component selectedComponent = jTabbedPane1.getSelectedComponent();
if (selectedComponent instanceof DomainArtifactsTabPanel) {
runDomainWorker((DomainArtifactsTabPanel) selectedComponent);
} else if (selectedComponent instanceof MiniTimelinePanel) {
runMiniTimelineWorker((MiniTimelinePanel) selectedComponent);
}
if (StringUtils.isBlank(domain)) {
//send fade out event //send fade out event
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false)); DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false));
} else { } else {
domain = populateEvent.getDomain();
Component selectedComponent = jTabbedPane1.getSelectedComponent();
if (selectedComponent instanceof DomainArtifactsTabPanel) {
runDomainWorker((DomainArtifactsTabPanel) selectedComponent);
} else if (selectedComponent instanceof MiniTimelinePanel) {
runMiniTimelineWorker((MiniTimelinePanel) selectedComponent);
}
//send fade in event //send fade in event
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(true)); DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(true));
} }

View File

@ -33,6 +33,7 @@
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="domainListModel" type="code"/> <Connection code="domainListModel" type="code"/>
</Property> </Property>
<Property name="selectionMode" type="int" value="0"/>
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> <Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DomainSummaryPanel()" type="code"/> <Connection code="new DomainSummaryPanel()" type="code"/>
</Property> </Property>

View File

@ -64,6 +64,7 @@ public class DomainSummaryViewer extends javax.swing.JPanel {
setLayout(new java.awt.BorderLayout()); setLayout(new java.awt.BorderLayout());
domainList.setModel(domainListModel); domainList.setModel(domainListModel);
domainList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
domainList.setCellRenderer(new DomainSummaryPanel()); domainList.setCellRenderer(new DomainSummaryPanel());
domainScrollPane.setViewportView(domainList); domainScrollPane.setViewportView(domainList);

View File

@ -0,0 +1,60 @@
<?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"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="loadingLabel" alignment="1" max="32767" attributes="0"/>
<Component id="detailsLabel" alignment="0" pref="390" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="loadingLabel" min="-2" pref="48" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="detailsLabel" min="-2" pref="33" max="-2" attributes="0"/>
<EmptySpace pref="30" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="loadingLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font component="loadingLabel" property="font" relativeSize="true" size="4"/>
</FontInfo>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="detailsLabel">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="verticalAlignment" type="int" value="1"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="1"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="LoadingPanel.detailsLabel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,97 @@
/*
* 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.ui;
import javax.swing.JPanel;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
/**
* Panel to let user know that the information is loading.
*/
class LoadingPanel extends JPanel {
private static final long serialVersionUID = 1L;
/**
* Creates new form LoadingPanel
*/
LoadingPanel() {
this(null);
}
@NbBundle.Messages({"LoadingPanel.loading.text=Loading, please wait.",
"# {0} - resultInfo",
"LoadingPanel.retrieving.text=Retrieving results for {0}."})
LoadingPanel(String details) {
initComponents();
loadingLabel.setText(Bundle.LoadingPanel_loading_text());
if (!StringUtils.isBlank(details)) {
detailsLabel.setText(Bundle.LoadingPanel_retrieving_text(details));
}
}
/**
* 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() {
loadingLabel = new javax.swing.JLabel();
detailsLabel = new javax.swing.JLabel();
loadingLabel.setFont(loadingLabel.getFont().deriveFont(loadingLabel.getFont().getSize()+4f));
loadingLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
loadingLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
detailsLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
detailsLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
detailsLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
detailsLabel.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(loadingLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(detailsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(loadingLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(detailsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(30, Short.MAX_VALUE))
);
detailsLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(LoadingPanel.class, "LoadingPanel.detailsLabel.AccessibleContext.accessibleName")); // NOI18N
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel detailsLabel;
private javax.swing.JLabel loadingLabel;
// End of variables declaration//GEN-END:variables
}

View File

@ -138,8 +138,8 @@ class MiniTimelineArtifactListPanel extends AbstractArtifactListPanel {
artifactsTable = new javax.swing.JTable(); artifactsTable = new javax.swing.JTable();
setOpaque(false); setOpaque(false);
setPreferredSize(new java.awt.Dimension(300, 0)); setPreferredSize(new java.awt.Dimension(200, 10));
jScrollPane1.setPreferredSize(new java.awt.Dimension(200, 10));
jScrollPane1.setBorder(null); jScrollPane1.setBorder(null);
jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0)); jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0));

View File

@ -139,8 +139,8 @@ class MiniTimelineDateListPanel extends JPanel {
jTable1 = new javax.swing.JTable(); jTable1 = new javax.swing.JTable();
setOpaque(false); setOpaque(false);
setPreferredSize(new java.awt.Dimension(200, 0)); setPreferredSize(new java.awt.Dimension(200, 10));
jScrollPane1.setPreferredSize(new java.awt.Dimension(200, 10));
jScrollPane1.setBorder(null); jScrollPane1.setBorder(null);
jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0)); jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0));

View File

@ -1,13 +1,42 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Container class="javax.swing.JSplitPane" name="mainSplitPane">
<Properties>
<Property name="dividerLocation" type="int" value="400"/>
<Property name="resizeWeight" type="double" value="0.1"/>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="leftSplitPane">
<Properties>
<Property name="dividerLocation" type="int" value="198"/>
<Property name="resizeWeight" type="double" value="0.5"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</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.support.JSplitPaneSupportLayout"/>
</Container>
</SubComponents>
</Container>
</NonVisualComponents>
<Properties> <Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/> <Dimension value="[0, 0]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
@ -23,45 +52,4 @@
</AuxValues> </AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="mainSplitPane">
<Properties>
<Property name="resizeWeight" type="double" value="0.4"/>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</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="leftSplitPane">
<Properties>
<Property name="resizeWeight" type="double" value="0.5"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 0]"/>
</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.support.JSplitPaneSupportLayout"/>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -23,6 +23,7 @@ import java.util.logging.Level;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.contentviewers.artifactviewers.GeneralPurposeArtifactViewer; import org.sleuthkit.autopsy.contentviewers.artifactviewers.GeneralPurposeArtifactViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
@ -32,7 +33,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
/** /**
* Panel to display the entire mini timeline feature. * Panel to display the entire mini timeline feature.
*/ */
class MiniTimelinePanel extends javax.swing.JPanel { final class MiniTimelinePanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -44,6 +45,7 @@ class MiniTimelinePanel extends javax.swing.JPanel {
private final ListSelectionListener artifactListener; private final ListSelectionListener artifactListener;
private final ListSelectionListener dateListener; private final ListSelectionListener dateListener;
@NbBundle.Messages({"MiniTimelinePanel.loadingPanel.details=the Timeline view"})
/** /**
* Creates new form MiniTimelinePanel. * Creates new form MiniTimelinePanel.
*/ */
@ -62,8 +64,8 @@ class MiniTimelinePanel extends javax.swing.JPanel {
} else { } else {
rightPanel = new GeneralPurposeArtifactViewer(); rightPanel = new GeneralPurposeArtifactViewer();
} }
rightPanel.setArtifact(artifact);
mainSplitPane.setRightComponent(rightPanel.getComponent()); mainSplitPane.setRightComponent(rightPanel.getComponent());
rightPanel.setArtifact(artifact);
validate(); validate();
repaint(); repaint();
} }
@ -88,6 +90,7 @@ class MiniTimelinePanel extends javax.swing.JPanel {
leftSplitPane.setLeftComponent(dateListPanel); leftSplitPane.setLeftComponent(dateListPanel);
leftSplitPane.setRightComponent(artifactListPanel); leftSplitPane.setRightComponent(artifactListPanel);
mainSplitPane.setRightComponent(rightPanel.getComponent()); mainSplitPane.setRightComponent(rightPanel.getComponent());
add(mainSplitPane);
} }
/** /**
@ -111,10 +114,16 @@ class MiniTimelinePanel extends javax.swing.JPanel {
if (status == DomainArtifactsTabPanel.ArtifactRetrievalStatus.UNPOPULATED) { if (status == DomainArtifactsTabPanel.ArtifactRetrievalStatus.UNPOPULATED) {
artifactListPanel.clearList(); artifactListPanel.clearList();
dateListPanel.clearList(); dateListPanel.clearList();
removeAll();
add(mainSplitPane);
if (rightPanel != null) { if (rightPanel != null) {
rightPanel.setArtifact(null); rightPanel.setArtifact(null);
} }
} else if (status == DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATING) {
removeAll();
add(new LoadingPanel(Bundle.MiniTimelinePanel_loadingPanel_details()));
} }
} }
/** /**
@ -134,6 +143,8 @@ class MiniTimelinePanel extends javax.swing.JPanel {
dateListPanel.addSelectionListener(dateListener); dateListPanel.addSelectionListener(dateListener);
artifactListPanel.addSelectionListener(artifactListener); artifactListPanel.addSelectionListener(artifactListener);
dateListPanel.selectFirst(); dateListPanel.selectFirst();
removeAll();
add(mainSplitPane);
revalidate(); revalidate();
repaint(); repaint();
try { try {
@ -157,21 +168,18 @@ class MiniTimelinePanel extends javax.swing.JPanel {
mainSplitPane = new javax.swing.JSplitPane(); mainSplitPane = new javax.swing.JSplitPane();
leftSplitPane = new javax.swing.JSplitPane(); leftSplitPane = new javax.swing.JSplitPane();
setMinimumSize(new java.awt.Dimension(0, 0)); mainSplitPane.setDividerLocation(400);
setPreferredSize(new java.awt.Dimension(0, 0)); mainSplitPane.setResizeWeight(0.1);
setLayout(new java.awt.BorderLayout());
mainSplitPane.setResizeWeight(0.4);
mainSplitPane.setToolTipText(""); mainSplitPane.setToolTipText("");
mainSplitPane.setMinimumSize(new java.awt.Dimension(0, 0)); mainSplitPane.setMinimumSize(new java.awt.Dimension(0, 0));
mainSplitPane.setPreferredSize(new java.awt.Dimension(0, 0));
leftSplitPane.setDividerLocation(198);
leftSplitPane.setResizeWeight(0.5); leftSplitPane.setResizeWeight(0.5);
leftSplitPane.setMinimumSize(new java.awt.Dimension(0, 0)); leftSplitPane.setMinimumSize(new java.awt.Dimension(0, 0));
leftSplitPane.setPreferredSize(new java.awt.Dimension(300, 0));
mainSplitPane.setLeftComponent(leftSplitPane); mainSplitPane.setLeftComponent(leftSplitPane);
add(mainSplitPane, java.awt.BorderLayout.CENTER); setMinimumSize(new java.awt.Dimension(0, 0));
setLayout(new java.awt.BorderLayout());
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents

View File

@ -57,10 +57,10 @@ class MiniTimelineWorker extends SwingWorker<List<MiniTimelineResult>, Void> {
DomainSearch domainSearch = new DomainSearch(); DomainSearch domainSearch = new DomainSearch();
try { try {
results.addAll(domainSearch.getAllArtifactsForDomain(Case.getCurrentCase().getSleuthkitCase(), domain)); results.addAll(domainSearch.getAllArtifactsForDomain(Case.getCurrentCase().getSleuthkitCase(), domain));
} catch (DiscoveryException ex) { } catch (DiscoveryException ex) {
if (ex.getCause() instanceof InterruptedException) { if (ex.getCause() instanceof InterruptedException) {
logger.log(Level.INFO, "MiniTimeline search was cancelled or interrupted for domain: {0}", domain); this.cancel(true);
//ignore the exception as it was cancelled while the cache was performing its get and we support cancellation
} else { } else {
throw ex; throw ex;
} }

View File

@ -32,7 +32,7 @@ The Types tab shows counts of different file types found in the data source.
\subsection ds_summary_user_activity User Activity \subsection ds_summary_user_activity User Activity
The User Activity tab shows the most recent results found in the data source. The User Activity tab shows the most recent results found in the data source. You can right click on a row to navigate directly to the corresponding result.
\image html ds_summary_user_activity.png \image html ds_summary_user_activity.png
@ -44,7 +44,7 @@ The Analysis tab shows the sets with the most results from the \ref hash_db_page
\subsection ds_summary_recent_files Recent Files \subsection ds_summary_recent_files Recent Files
The Recent Files tab shows information on the most recent files opened and downloaded. The Recent Files tab shows information on the most recent files opened and downloaded. You can right click on a row to navigate directly to the corresponding file or result.
\image html ds_summary_recent_files.png \image html ds_summary_recent_files.png
@ -56,6 +56,18 @@ The Past Cases tab shows which cases had results or notable files in common with
Note that because these entries are based on the Interesting Items results created during ingest and not querying the central repository, they will not reflect any matches in cases processed after this case. For example, suppose we create Case A and ingest a data source with Device Z. If we make a new case Case B afterward and ingest a data source that also has Device Z, we would see Case A listed in this tab for Case B, but if we reopened Case A we would not see Case B listed unless ingest was run again. Note that because these entries are based on the Interesting Items results created during ingest and not querying the central repository, they will not reflect any matches in cases processed after this case. For example, suppose we create Case A and ingest a data source with Device Z. If we make a new case Case B afterward and ingest a data source that also has Device Z, we would see Case A listed in this tab for Case B, but if we reopened Case A we would not see Case B listed unless ingest was run again.
\subsection ds_summary_geo Geolocation
The Geolocation tab uses the coordinates from geolocation results to find the nearest city for each and displays the most recent cities and most common cities. If the location is more than 150 km from a city then it will be displayed as "Unknown". The "View in Map" button under the recent cities table will open the \ref geolocation_page "Geolocation window" showing all waypoints for this data source with timestamps in the last 30 days. The "View in Map" button under the most common cities will show all waypoints for this data source.
\image html ds_summary_geo.png
\subsection ds_summary_timeline Timeline
The Timeline tab shows a simplified version of the \ref timeline_page "Timeline Viewer" for the selected data source. It will show events for the last 30 days of activity in the data source and give the first and last dates of activity. "File events" represent file creation, modification, access, and change. "Result events" represent the results from running ingest, such as the time a message was sent or when a URL was accessed. The "View in Timeline" button will open the main \ref timeline_page "Timeline Viewer".
\image html ds_summary_timeline.png
\subsection ds_summary_ingest_history Ingest History \subsection ds_summary_ingest_history Ingest History
The Ingest History tab shows which ingest modules have been run on the data source and the version of each module. The Ingest History tab shows which ingest modules have been run on the data source and the version of each module.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 59 KiB