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_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,0,0,0,0,0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="detailsPanel">
<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">
<EmptySpace min="0" pref="0" max="32767" 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">
<EmptySpace min="0" pref="0" max="32767" 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>
<Container class="javax.swing.JScrollPane" name="detailsScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -37,7 +37,6 @@ import java.util.logging.Level;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import org.apache.commons.lang.StringUtils;
@ -82,6 +81,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private final GridBagLayout gridBagLayout = new GridBagLayout();
private final GridBagConstraints gridBagConstraints = new GridBagConstraints();
private final Map<Integer, Integer[]> orderingMap = new HashMap<>();
private final javax.swing.JPanel detailsPanel = new javax.swing.JPanel();
/**
* Creates new form GeneralPurposeArtifactViewer.
@ -90,6 +90,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
public GeneralPurposeArtifactViewer() {
addOrderings();
initComponents();
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
detailsPanel.setLayout(gridBagLayout);
}
@ -161,8 +162,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
}
updateView(artifact, attributeMap, dataSourceName, sourceFileName);
}
detailsScrollPane.setViewportView(detailsPanel);
detailsScrollPane.revalidate();
revalidate();
repaint();
}
/**
@ -172,7 +174,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private void resetComponent() {
// clear the panel
detailsPanel.removeAll();
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
detailsPanel.setLayout(gridBagLayout);
detailsPanel.revalidate();
gridBagConstraints.gridy = 0;
gridBagConstraints.gridx = LABEL_COLUMN;
gridBagConstraints.weighty = 0.0;
@ -183,14 +186,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@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) {
return (artifact != null)
&& (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
private void initComponents() {
detailsPanel = new javax.swing.JPanel();
detailsScrollPane = new javax.swing.JScrollPane();
setLayout(new java.awt.BorderLayout());
javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel);
detailsPanel.setLayout(detailsPanelLayout);
detailsPanelLayout.setHorizontalGroup(
detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(detailsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 62, Short.MAX_VALUE)
);
detailsPanelLayout.setVerticalGroup(
detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.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
/**
@ -257,7 +250,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFilePath) {
final Integer artifactTypeId = artifact.getArtifactTypeID();
if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) {
addDetailsHeader(artifactTypeId);
JTextPane firstTextPane = addDetailsHeader(artifactTypeId);
Integer[] orderingArray = orderingMap.get(artifactTypeId);
if (orderingArray == null) {
orderingArray = DEFAULT_ORDERING;
@ -282,7 +275,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
addNameValueRow(bba.getAttributeType().getDisplayName(), displayString);
} else {
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
}
}
}
@ -311,8 +303,12 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath);
// add veritcal glue at the end
addPageEndGlue();
if (firstTextPane != null) {
firstTextPane.setCaretPosition(0);
}
}
detailsPanel.revalidate();
}
/**
* Private helper method to add all dates in a given attribute list.
@ -353,7 +349,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
"GeneralPurposeArtifactViewer.details.searchHeader=Web Search",
"GeneralPurposeArtifactViewer.details.cachedHeader=Cached File",
"GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",})
private void addDetailsHeader(int artifactTypeId) {
private JTextPane addDetailsHeader(int artifactTypeId) {
String header;
if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader();
@ -370,7 +366,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
} else {
header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader();
}
addHeader(header);
return addHeader(header);
}
/**
@ -381,15 +377,20 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
* @return JLabel Heading label added.
*/
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private JLabel addHeader(String headerString) {
private JTextPane addHeader(String headerString) {
// 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
// the first section
if (gridBagConstraints.gridy != 0) {
gridBagConstraints.gridy++;
detailsPanel.add(new javax.swing.JLabel(" "), gridBagConstraints);
// add to panel
addToPanel(new javax.swing.JLabel(" "));
addLineEndGlue();
headingLabel.setFocusable(false);
}
gridBagConstraints.gridy++;
gridBagConstraints.gridx = LABEL_COLUMN;;
@ -401,7 +402,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
// make it large and bold
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
// add to panel
detailsPanel.add(headingLabel, gridBagConstraints);
addToPanel(headingLabel);
// reset constraints to normal
gridBagConstraints.gridwidth = LABEL_WIDTH;
// add line end glue
@ -417,9 +418,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
* @param keyString Key name to display.
* @param valueString Value string to display.
*/
private void addNameValueRow(String keyString, String valueString) {
private JTextPane addNameValueRow(String keyString, String valueString) {
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.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));
detailsPanel.add(horizontalFiller, gridBagConstraints);
// add to panel
addToPanel(horizontalFiller);
// restore fill & weight
gridBagConstraints.fill = GridBagConstraints.NONE;
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.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));
detailsPanel.add(vertFiller, gridBagConstraints);
// add to panel
addToPanel(vertFiller);
}
/**
@ -459,16 +462,22 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
private JLabel addKeyAtCol(String keyString) {
// create label
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
keyLabel.setFocusable(false);
gridBagConstraints.gridy++;
gridBagConstraints.gridx = LABEL_COLUMN;
gridBagConstraints.gridwidth = LABEL_WIDTH;
// set text
keyLabel.setText(keyString + ": ");
// add to panel
detailsPanel.add(keyLabel, gridBagConstraints);
addToPanel(keyLabel);
return keyLabel;
}
private void addToPanel(Component comp) {
detailsPanel.add(comp, gridBagConstraints);
detailsPanel.revalidate();
}
/**
* 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) {
// create label,
JTextPane valueField = new JTextPane();
valueField.setFocusable(false);
valueField.setEditable(false);
valueField.setOpaque(false);
gridBagConstraints.gridx = VALUE_COLUMN;
@ -488,8 +498,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
cloneConstraints.fill = GridBagConstraints.BOTH;
// set text
valueField.setText(valueString);
// scroll to start of text
valueField.setCaretPosition(0);
// attach a right click menu with Copy option
valueField.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
@ -497,8 +505,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
valueLabelMouseClicked(evt, valueField);
}
});
// add label to panel
// add label to panel with cloned contraintsF
detailsPanel.add(valueField, cloneConstraints);
revalidate();
// end the line
addLineEndGlue();
return valueField;
@ -531,6 +540,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
// 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
}

View File

@ -201,7 +201,7 @@ public class DomainSearch {
* @throws DiscoveryException if unable to get the artifacts or the date
* 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<>();
Map<String, List<BlackboardArtifact>> dateMap = new HashMap<>();
if (!StringUtils.isBlank(domain)) {

View File

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

View File

@ -4,7 +4,7 @@
<Properties>
<Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 0]"/>
<Dimension value="[350, 10]"/>
</Property>
</Properties>
<AuxValues>
@ -22,12 +22,12 @@
<Layout>
<DimensionLayout dim="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>
</DimensionLayout>
<DimensionLayout dim="1">
<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>
</DimensionLayout>
</Layout>
@ -37,9 +37,13 @@
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<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="[350, 10]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>

View File

@ -94,11 +94,15 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
@Override
BlackboardArtifact getSelectedArtifact() {
if (artifactsTable.getModel() instanceof DomainArtifactTableModel) {
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;
}
}
@Override
@ -124,7 +128,12 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
void addArtifacts(List<BlackboardArtifact> artifactList) {
if (!artifactList.isEmpty()) {
artifactsTable.setModel(tableModel);
tableModel.setContents(artifactList);
} else {
artifactsTable.setModel(new EmptyTableModel());
}
artifactsTable.validate();
artifactsTable.repaint();
tableModel.fireTableDataChanged();
@ -152,10 +161,12 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
artifactsTable = new javax.swing.JTable();
setOpaque(false);
setPreferredSize(new java.awt.Dimension(300, 0));
setPreferredSize(new java.awt.Dimension(350, 10));
jScrollPane1.setBorder(null);
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0));
jScrollPane1.setPreferredSize(new java.awt.Dimension(350, 10));
artifactsTable.setAutoCreateRowSorter(true);
artifactsTable.setModel(tableModel);
@ -166,11 +177,11 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
this.setLayout(layout);
layout.setHorizontalGroup(
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.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
@ -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
private javax.swing.JTable artifactsTable;
// 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));
} catch (DiscoveryException ex) {
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 {
throw ex;
}

View File

@ -62,3 +62,4 @@ CookieDetailsPanel.jLabel1.text=Artifact:
CookieDetailsPanel.jLabel2.text=
PreviouslyNotableFilterPanel.text_1=Include only previously notable domains
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.fileNameColumn.name=Name
ArtifactsListPanel.mimeTypeColumn.name=MIME Type
ArtifactsListPanel.noResultsFound.text=No results found
ArtifactsListPanel.termColumn.name=Term
ArtifactsListPanel.titleColumn.name=Title
ArtifactsListPanel.urlColumn.name=URL
@ -52,7 +53,7 @@ DocumentPanel.numberOfImages.noImages=No images
# {0} - numberOfImages
DocumentPanel.numberOfImages.text=1 of {0} images
DocumentWrapper.previewInitialValue=Preview not generated yet.
DomainDetailsPanel.miniTimelineTitle.text=Mini Timeline
DomainDetailsPanel.miniTimelineTitle.text=Timeline
# {0} - startDate
# {1} - endDate
DomainSummaryPanel.activity.text=Activity: {0} to {1}
@ -68,12 +69,16 @@ ImageThumbnailPanel.isDeleted.text=All instances of file are deleted.
# {0} - otherInstanceCount
ImageThumbnailPanel.nameLabel.more.text=\ and {0} more
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.typeColumn.name=Result Type
MiniTimelineArtifactListPanel.value.noValue=No value available.
MiniTimelineDateListPanel.countColumn.name=Count
MiniTimelineDateListPanel.dateColumn.name=Date
MiniTimelineDateListPanel.value.noValue=No value available.
MiniTimelinePanel.loadingPanel.details=the Timeline view
MonthAbbreviation.aprilAbbrev=Apr
MonthAbbreviation.augustAbbrev=Aug
MonthAbbreviation.decemberAbbrev=Dec
@ -165,6 +170,7 @@ CookieDetailsPanel.jLabel1.text=Artifact:
CookieDetailsPanel.jLabel2.text=
PreviouslyNotableFilterPanel.text_1=Include only previously notable domains
KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type
LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel
VideoThumbnailPanel.bytes.text=bytes
VideoThumbnailPanel.deleted.text=All instances of file are deleted.
VideoThumbnailPanel.gigaBytes.text=GB

View File

@ -60,9 +60,11 @@ public final class DiscoveryTopComponent extends TopComponent {
private volatile static int previousDividerLocation = 250;
private final GroupListPanel groupListPanel;
private final ResultsPanel resultsPanel;
private JPanel detailsPanel = new JPanel();
private String selectedDomainTabName;
private Type searchType;
private int dividerLocation = JSplitPane.UNDEFINED_CONDITION;
private SwingAnimator animator = null;
/**
@ -83,26 +85,26 @@ public final class DiscoveryTopComponent extends TopComponent {
}
});
rightSplitPane.setTopComponent(resultsPanel);
resetBottomComponent();
rightSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
//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())
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)) {
&& ((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
previousDividerLocation = (int) evt.getNewValue();
}
}
}
);
}
}
}
});
rightSplitPane.setTopComponent(resultsPanel);
rightSplitPane.setBottomComponent(new JPanel());
}
/**
* Private class for replacing the divider for the results split pane.
@ -131,7 +133,8 @@ public final class DiscoveryTopComponent extends TopComponent {
* @return The open DiscoveryTopComponent or null if it has not been opened.
*/
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);
}
private void resetBottomComponent() {
rightSplitPane.setBottomComponent(new JPanel());
rightSplitPane.setDividerLocation(JSplitPane.UNDEFINED_CONDITION);
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
protected void componentClosed() {
@ -162,11 +170,11 @@ public final class DiscoveryTopComponent extends TopComponent {
DiscoveryEventUtils.getDiscoveryEventBus().unregister(this);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(rightSplitPane.getBottomComponent());
if (rightSplitPane.getBottomComponent() instanceof DomainDetailsPanel) {
selectedDomainTabName = ((DomainDetailsPanel) rightSplitPane.getBottomComponent()).getSelectedTabName();
DiscoveryEventUtils.getDiscoveryEventBus().unregister(detailsPanel);
if (detailsPanel instanceof DomainDetailsPanel) {
selectedDomainTabName = ((DomainDetailsPanel) detailsPanel).getSelectedTabName();
}
rightSplitPane.setDividerLocation(JSplitPane.UNDEFINED_CONDITION);
resetBottomComponent();
super.componentClosed();
}
@ -336,12 +344,13 @@ public final class DiscoveryTopComponent extends TopComponent {
}
selectedDomainTabName = validateLastSelectedType(searchCompleteEvent);
DomainDetailsPanel domainDetailsPanel = new DomainDetailsPanel();
rightSplitPane.setBottomComponent(domainDetailsPanel);
domainDetailsPanel.configureArtifactTabs(selectedDomainTabName);
detailsPanel = domainDetailsPanel;
} 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("; "));
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(descriptionText));
progressMessageTextArea.setCaretPosition(0);

View File

@ -1,13 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<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>
<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>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
@ -23,23 +30,4 @@
</AuxValues>
<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>

View File

@ -22,7 +22,6 @@ import org.sleuthkit.autopsy.contentviewers.artifactviewers.GeneralPurposeArtifa
import com.google.common.eventbus.Subscribe;
import java.util.logging.Level;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
@ -64,7 +63,8 @@ final class DomainArtifactsTabPanel extends JPanel {
this.artifactType = type;
listPanel = new ArtifactsListPanel(artifactType);
listPanel.addMouseListener(new ArtifactMenuMouseAdapter(listPanel));
jSplitPane1.setLeftComponent(listPanel);
mainSplitPane.setLeftComponent(listPanel);
add(mainSplitPane);
setRightComponent();
listPanel.addSelectionListener(listener);
}
@ -91,7 +91,7 @@ final class DomainArtifactsTabPanel extends JPanel {
break;
}
if (rightPanel != null) {
jSplitPane1.setRightComponent(rightPanel.getComponent());
mainSplitPane.setRightComponent(rightPanel.getComponent());
}
}
@ -115,10 +115,14 @@ final class DomainArtifactsTabPanel extends JPanel {
this.status = status;
if (status == ArtifactRetrievalStatus.UNPOPULATED) {
listPanel.clearList();
removeAll();
add(mainSplitPane);
if (rightPanel != 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
void handleArtifactSearchResultEvent(DiscoveryEventUtils.ArtifactSearchResultEvent artifactresultEvent) {
if (artifactType == artifactresultEvent.getArtifactType()) {
if (artifactType == artifactresultEvent.getArtifactType() && status == ArtifactRetrievalStatus.POPULATING) {
SwingUtilities.invokeLater(() -> {
listPanel.removeSelectionListener(listener);
listPanel.addArtifacts(artifactresultEvent.getListOfArtifacts());
@ -138,6 +142,8 @@ final class DomainArtifactsTabPanel extends JPanel {
setEnabled(!listPanel.isEmpty());
listPanel.addSelectionListener(listener);
listPanel.selectFirst();
removeAll();
add(mainSplitPane);
revalidate();
repaint();
try {
@ -169,20 +175,18 @@ final class DomainArtifactsTabPanel extends JPanel {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN: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));
setPreferredSize(new java.awt.Dimension(0, 0));
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
// 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
/**

View File

@ -2,13 +2,13 @@
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
<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>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<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.
*/
@NbBundle.Messages({"DomainDetailsPanel.miniTimelineTitle.text=Mini Timeline"})
@NbBundle.Messages({"DomainDetailsPanel.miniTimelineTitle.text=Timeline"})
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
void configureArtifactTabs(String 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
* populate the details area.
@ -146,20 +160,19 @@ final class DomainDetailsPanel extends JPanel {
*/
@Subscribe
void handlePopulateDomainTabsEvent(DiscoveryEventUtils.PopulateDomainTabsEvent populateEvent) {
domain = populateEvent.getDomain();
SwingUtilities.invokeLater(() -> {
if (StringUtils.isBlank(populateEvent.getDomain())) {
resetTabsStatus();
selectTab();
//send fade out event
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false));
} else {
domain = populateEvent.getDomain();
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
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false));
} else {
//send fade in event
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">
<Connection code="domainListModel" 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 DomainSummaryPanel()" type="code"/>
</Property>

View File

@ -64,6 +64,7 @@ public class DomainSummaryViewer extends javax.swing.JPanel {
setLayout(new java.awt.BorderLayout());
domainList.setModel(domainListModel);
domainList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
domainList.setCellRenderer(new DomainSummaryPanel());
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();
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.setMinimumSize(new java.awt.Dimension(0, 0));

View File

@ -139,8 +139,8 @@ class MiniTimelineDateListPanel extends JPanel {
jTable1 = new javax.swing.JTable();
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.setMinimumSize(new java.awt.Dimension(0, 0));

View File

@ -1,11 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<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>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
</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>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 0]"/>
</Property>
</Properties>
@ -23,45 +52,4 @@
</AuxValues>
<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>

View File

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

View File

@ -57,10 +57,10 @@ class MiniTimelineWorker extends SwingWorker<List<MiniTimelineResult>, Void> {
DomainSearch domainSearch = new DomainSearch();
try {
results.addAll(domainSearch.getAllArtifactsForDomain(Case.getCurrentCase().getSleuthkitCase(), domain));
} catch (DiscoveryException ex) {
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 {
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
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
@ -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
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
@ -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.
\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
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