diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 92c098bd22..efc5cab83c 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -95,8 +95,8 @@ class FileSearch { SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod); searchResults.add(resultFiles); - // We don't need the linked hash map, but this also does the sorting and grouping - searchResults.toLinkedHashMap(); + // Sort and group the results + searchResults.sortGroupsAndFiles(); return searchResults; } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java index 215eb5513c..c9bbb29cbe 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java @@ -1218,6 +1218,7 @@ final class FileSearchPanel extends javax.swing.JPanel implements ActionListener searchTerm = new ParentSearchTerm(parentTextField.getText(), false); } parentListModel.add(parentListModel.size(), searchTerm); + validateFields(); } }//GEN-LAST:event_addButtonActionPerformed @@ -1230,6 +1231,7 @@ final class FileSearchPanel extends javax.swing.JPanel implements ActionListener private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed int index = parentList.getSelectedIndex(); parentListModel.remove(index); + validateFields(); }//GEN-LAST:event_deleteButtonActionPerformed private void parentListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_parentListValueChanged diff --git a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java index eeb6cf5c14..1608239955 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java @@ -34,7 +34,7 @@ class GroupListPanel extends javax.swing.JPanel { private final static Logger logger = Logger.getLogger(GroupListPanel.class.getName()); private static final long serialVersionUID = 1L; - private LinkedHashMap> results = null; + private SearchResults results = null; private FileType resultType = null; /** @@ -52,7 +52,7 @@ class GroupListPanel extends javax.swing.JPanel { @Subscribe void handleSearchStartedEvent(DiscoveryEvents.SearchStartedEvent searchStartedEvent) { resultType = searchStartedEvent.getType(); - results = new LinkedHashMap<>(); + results = new SearchResults(); groupList.setListData(new String[0]); } @@ -64,19 +64,15 @@ class GroupListPanel extends javax.swing.JPanel { */ @Subscribe void handleSearchCompleteEvent(DiscoveryEvents.SearchCompleteEvent searchCompleteEvent) { - try { - results = searchCompleteEvent.getSearchResults().toLinkedHashMap(); - Set resultsKeySet = results.keySet(); - groupList.setListData(resultsKeySet.toArray(new String[results.size()])); - if (groupList.getModel().getSize() > 0) { - groupList.setSelectedIndex(0); - } - validate(); - repaint(); - } catch (FileSearchException ex) { - logger.log(Level.WARNING, "Error handling completed search results for file discovery, no results displayed", ex); - groupList.setListData(new String[0]); + + results = searchCompleteEvent.getSearchResults(); + List groupNames = results.getGroupNamesWithCounts(); + groupList.setListData(groupNames.toArray(new String[groupNames.size()])); + if (groupList.getModel().getSize() > 0) { + groupList.setSelectedIndex(0); } + validate(); + repaint(); } /** @@ -122,7 +118,7 @@ class GroupListPanel extends javax.swing.JPanel { */ private void groupSelected(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_groupSelected if (!evt.getValueIsAdjusting() && results != null) { - DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent(resultType, results.get(groupList.getSelectedValue()))); + DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent(resultType, results.getAbstractFilesInGroup(groupList.getSelectedValue()))); } }//GEN-LAST:event_groupSelected diff --git a/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java b/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java index 7b6620ab8f..7bdcf4b722 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java @@ -24,6 +24,8 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; import org.sleuthkit.datamodel.AbstractFile; /** @@ -36,7 +38,7 @@ class SearchResults { private final FileSorter fileSorter; private final Map groupMap = new HashMap<>(); - private List groupList = null; + private List groupList = new ArrayList<>(); private final long MAX_OUTPUT_FILES = 2000; // For debug UI - maximum number of lines to print @@ -54,6 +56,15 @@ class SearchResults { this.fileSorter = new FileSorter(fileSortingMethod); } + /** + * Create an dummy SearchResults object that can be used in the UI before the search is finished. + */ + SearchResults() { + this.groupSortingType = FileGroup.GroupSortingAlgorithm.BY_GROUP_KEY; + this.attrType = new FileSearch.FileSizeAttribute(); + this.fileSorter = new FileSorter(FileSorter.SortingMethod.BY_FILE_NAME); + } + /** * Add a list of ResultFile to the results * @@ -74,7 +85,7 @@ class SearchResults { /** * Run after all files have been added to sortGroupsAndFiles the groups and files. */ - private void sortGroupsAndFiles() { + void sortGroupsAndFiles() { // First sortGroupsAndFiles the files for (FileGroup group : groupMap.values()) { @@ -109,6 +120,33 @@ class SearchResults { return result; } + /** + * Get the names of the groups with counts + * + * @return the group names + */ + List getGroupNamesWithCounts() { + return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getResultFiles().size() + ")").collect(Collectors.toList()); + } + + /** + * Get the abstract files for the selected group + * + * @param groupName The name of the group. Can have the size appended. + * @return the list of abstract files + */ + List getAbstractFilesInGroup(String groupName) { + if (groupName != null) { + final String modifiedGroupName = groupName.replaceAll(" \\([0-9]+\\)$", ""); + + java.util.Optional fileGroup = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst(); + if (fileGroup.isPresent()) { + return fileGroup.get().getAbstractFiles(); + } + } + return new ArrayList<>(); + } + /** * Transform the results into a LinkedHashMap with abstract files. *