mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
7084 bug fixes for feedback
This commit is contained in:
parent
e846885d88
commit
52fcedb5ea
@ -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)) {
|
||||
|
@ -94,11 +94,15 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
|
||||
|
||||
@Override
|
||||
BlackboardArtifact getSelectedArtifact() {
|
||||
int selectedIndex = artifactsTable.getSelectionModel().getLeadSelectionIndex();
|
||||
if (selectedIndex < artifactsTable.getSelectionModel().getMinSelectionIndex() || artifactsTable.getSelectionModel().getMaxSelectionIndex() < 0 || selectedIndex > artifactsTable.getSelectionModel().getMaxSelectionIndex()) {
|
||||
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;
|
||||
}
|
||||
return tableModel.getArtifactByRow(artifactsTable.convertRowIndexToModel(selectedIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -124,7 +128,12 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
@Override
|
||||
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.repaint();
|
||||
tableModel.fireTableDataChanged();
|
||||
@ -359,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_value_noValue();
|
||||
}
|
||||
@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
|
||||
|
@ -61,7 +61,7 @@ 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);
|
||||
//ignore the exception as it was cancelled while the cache was performing its get and we support cancellation
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
@ -73,7 +73,7 @@ class ArtifactsWorker extends SwingWorker<List<BlackboardArtifact>, Void> {
|
||||
@Override
|
||||
protected void done() {
|
||||
List<BlackboardArtifact> listOfArtifacts = new ArrayList<>();
|
||||
if (!isCancelled() && isDone()) {
|
||||
if (!isCancelled()) {
|
||||
try {
|
||||
listOfArtifacts.addAll(get());
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ArtifactSearchResultEvent(artifactType, listOfArtifacts));
|
||||
|
@ -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
|
||||
|
@ -40,6 +40,7 @@ import org.openide.windows.TopComponent;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils.PopulateDomainTabsEvent;
|
||||
import org.sleuthkit.autopsy.discovery.search.SearchData.Type;
|
||||
import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.DOMAIN;
|
||||
import org.sleuthkit.autopsy.discovery.search.SearchFiltering.ArtifactTypeFilter;
|
||||
@ -60,9 +61,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;
|
||||
|
||||
/**
|
||||
@ -88,19 +91,19 @@ public final class DiscoveryTopComponent extends TopComponent {
|
||||
rightSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
|
||||
@Override
|
||||
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
|
||||
if ((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)) {
|
||||
previousDividerLocation = (int) evt.getNewValue();
|
||||
}
|
||||
previousDividerLocation = (int) evt.getNewValue();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@ -132,7 +135,6 @@ public final class DiscoveryTopComponent extends TopComponent {
|
||||
*/
|
||||
public static DiscoveryTopComponent getTopComponent() {
|
||||
DiscoveryTopComponent discoveryTopComp = (DiscoveryTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
|
||||
discoveryTopComp.resetBottomComponent();
|
||||
return discoveryTopComp;
|
||||
}
|
||||
|
||||
@ -169,9 +171,9 @@ 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();
|
||||
}
|
||||
resetBottomComponent();
|
||||
super.componentClosed();
|
||||
@ -274,6 +276,25 @@ public final class DiscoveryTopComponent extends TopComponent {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to the PopulateDomainTabsEvent to ensure the bottom area only
|
||||
* shows when it has data
|
||||
*
|
||||
* @param populateDomainTabsEvent The event which indicates the domain tabs
|
||||
* contents should change.
|
||||
*/
|
||||
@Subscribe
|
||||
private void handlePopulateDomainTabsEvent(PopulateDomainTabsEvent populateDomainTabsEvent) {
|
||||
if (detailsPanel instanceof DomainDetailsPanel) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (((DomainDetailsPanel) detailsPanel).getCurrentTabStatus() == DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATED
|
||||
|| ((DomainDetailsPanel) detailsPanel).getCurrentTabStatus() == DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATING) {
|
||||
rightSplitPane.setBottomComponent(detailsPanel);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the DetailsVisible event and animate the panel as it changes
|
||||
* visibility.
|
||||
@ -311,6 +332,7 @@ public final class DiscoveryTopComponent extends TopComponent {
|
||||
@Subscribe
|
||||
void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
rightSplitPane.setBottomComponent(new JPanel());
|
||||
newSearchButton.setText(Bundle.DiscoveryTopComponent_cancelButton_text());
|
||||
progressMessageTextArea.setForeground(Color.red);
|
||||
searchType = searchStartedEvent.getType();
|
||||
@ -343,12 +365,16 @@ 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());
|
||||
FileDetailsPanel fileDetailsPanel = new FileDetailsPanel();
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(fileDetailsPanel);
|
||||
detailsPanel = new FileDetailsPanel();
|
||||
rightSplitPane.setBottomComponent(detailsPanel);
|
||||
}
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(rightSplitPane.getBottomComponent());
|
||||
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().register(detailsPanel);
|
||||
descriptionText += searchCompleteEvent.getFilters().stream().map(AbstractFilter::getDesc).collect(Collectors.joining("; "));
|
||||
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(descriptionText));
|
||||
progressMessageTextArea.setCaretPosition(0);
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -60,7 +60,7 @@ class MiniTimelineWorker extends SwingWorker<List<MiniTimelineResult>, Void> {
|
||||
|
||||
} catch (DiscoveryException ex) {
|
||||
if (ex.getCause() instanceof InterruptedException) {
|
||||
logger.log(Level.INFO, "MiniTimeline search was cancelled or interrupted for domain: {0}", domain);
|
||||
//ignore the exception as it was cancelled while the cache was performing its get and we support cancellation
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
@ -72,7 +72,7 @@ class MiniTimelineWorker extends SwingWorker<List<MiniTimelineResult>, Void> {
|
||||
@Override
|
||||
protected void done() {
|
||||
List<MiniTimelineResult> results = new ArrayList<>();
|
||||
if (!isCancelled() && isDone()) {
|
||||
if (!isCancelled()) {
|
||||
try {
|
||||
results.addAll(get());
|
||||
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.MiniTimelineResultEvent(results));
|
||||
|
Loading…
x
Reference in New Issue
Block a user