From c48a0771272b9b1e4ab78f712befc4d716acec10 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 13 Aug 2019 14:47:22 -0400 Subject: [PATCH 1/3] 5367 exit loop when selected group found --- Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java index ac27e0ebbc..e6c2daac91 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java @@ -120,13 +120,14 @@ class GroupListPanel extends javax.swing.JPanel { * @param evt the event which indicates a selection occurs in the list */ private void groupSelected(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_groupSelected - if (!evt.getValueIsAdjusting()) { + if (!evt.getValueIsAdjusting() && groupDisplayNameList.getSelectedValue() != null) { String selectedGroup = groupDisplayNameList.getSelectedValue().replaceAll(" \\([0-9]+\\)$", ""); for (String groupName : groupMap.keySet()) { if (selectedGroup.equalsIgnoreCase(groupName)) { selectedGroupName = groupName; DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent( searchfilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupName, groupMap.get(selectedGroupName), resultType)); + break; } } From 92983a050392b7b40bba119729b389d63d502742 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 13 Aug 2019 15:37:04 -0400 Subject: [PATCH 2/3] 5367 reset results section when no results --- .../filequery/Bundle.properties-MERGED | 2 +- .../autopsy/filequery/DiscoveryEvents.java | 7 +++++++ .../autopsy/filequery/GroupListPanel.java | 21 +++++++++++-------- .../autopsy/filequery/ResultsPanel.java | 19 +++++++++++++++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED index 1ab7f6cf88..0987f4e14c 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED @@ -158,7 +158,7 @@ ResultsPanel.currentPage.displayValue=Page: {0} of {1} ResultsPanel.currentPageLabel.text=Page: - # {0} - selectedPage # {1} - maxPage -ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value of at least 1 and at most {1} +ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value from 1 to {1}. ResultsPanel.invalidPageNumber.title=Invalid Page Number ResultsPanel.pageControlsLabel.text=Pages: ResultsPanel.gotoPageLabel.text=Go to Page: diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java index 3209918445..26a9ccc25a 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java @@ -201,6 +201,13 @@ final class DiscoveryEvents { } } + static final class NoResultsEvent { + + NoResultsEvent(){ + //no arg conustructor + } + } + /** * Event to signal that a group has been selected. */ diff --git a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java index e6c2daac91..6498ef9362 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java @@ -120,17 +120,20 @@ class GroupListPanel extends javax.swing.JPanel { * @param evt the event which indicates a selection occurs in the list */ private void groupSelected(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_groupSelected - if (!evt.getValueIsAdjusting() && groupDisplayNameList.getSelectedValue() != null) { - String selectedGroup = groupDisplayNameList.getSelectedValue().replaceAll(" \\([0-9]+\\)$", ""); - for (String groupName : groupMap.keySet()) { - if (selectedGroup.equalsIgnoreCase(groupName)) { - selectedGroupName = groupName; - DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent( - searchfilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupName, groupMap.get(selectedGroupName), resultType)); - break; + if (!evt.getValueIsAdjusting()) { + if (groupDisplayNameList.getSelectedValue() != null) { + String selectedGroup = groupDisplayNameList.getSelectedValue().replaceAll(" \\([0-9]+\\)$", ""); + for (String groupName : groupMap.keySet()) { + if (selectedGroup.equalsIgnoreCase(groupName)) { + selectedGroupName = groupName; + DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent( + searchfilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupName, groupMap.get(selectedGroupName), resultType)); + break; + } } + } else { + DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.NoResultsEvent()); } - } }//GEN-LAST:event_groupSelected diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index f350cfc342..ddb1a231e7 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -77,6 +77,7 @@ public class ResultsPanel extends javax.swing.JPanel { currentPage = pageRetrievedEvent.getPageNumber(); updateControls(); thumbnailViewer.resetComponent(); + tableViewer.resetComponent(); resultsViewerPanel.remove(thumbnailViewer); resultsViewerPanel.remove(tableViewer); if (pageRetrievedEvent.getType() == FileSearchData.FileType.IMAGE || pageRetrievedEvent.getType() == FileSearchData.FileType.VIDEO) { @@ -104,7 +105,7 @@ public class ResultsPanel extends javax.swing.JPanel { * @param groupSelectedEvent The GroupSelectedEvent received. */ @Subscribe - void handlePageChangedEvent(DiscoveryEvents.GroupSelectedEvent groupSelectedEvent) { + void handleGroupSelectedEvent(DiscoveryEvents.GroupSelectedEvent groupSelectedEvent) { SwingUtilities.invokeLater(() -> { searchFilters = groupSelectedEvent.getFilters(); groupingAttribute = groupSelectedEvent.getGroupingAttr(); @@ -117,6 +118,20 @@ public class ResultsPanel extends javax.swing.JPanel { }); } + @Subscribe + void handleNoResultsEvent(DiscoveryEvents.NoResultsEvent noResultsEven) { + SwingUtilities.invokeLater(() -> { + groupSize = 0; + currentPage = 0; + updateControls(); + thumbnailViewer.resetComponent(); + thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); + tableViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); + resultsViewerPanel.revalidate(); + resultsViewerPanel.repaint(); + }); + } + /** * Set the page number and retrieve its contents. * @@ -332,7 +347,7 @@ public class ResultsPanel extends javax.swing.JPanel { */ @Messages({"# {0} - selectedPage", "# {1} - maxPage", - "ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value of at least 1 and at most {1}", + "ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value from 1 to {1}.", "ResultsPanel.invalidPageNumber.title=Invalid Page Number"}) private void gotoPageFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoPageFieldActionPerformed int newPage; From 1f027be77c11e6fce4bd3ba1d2bf0bf58b86e65a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 13 Aug 2019 15:53:34 -0400 Subject: [PATCH 3/3] 5367 fix size filter thresholds --- .../autopsy/filequery/FileSearchData.java | 153 +++++++++--------- 1 file changed, 75 insertions(+), 78 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java index cea457b6c7..4decdb12ad 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java @@ -29,9 +29,9 @@ import org.sleuthkit.autopsy.datamodel.utils.FileTypeUtils; * Utility enums for FileSearch */ class FileSearchData { - + private final static long BYTES_PER_MB = 1000000; - + /** * Enum representing how often the file occurs in the Central Repository. */ @@ -43,43 +43,42 @@ class FileSearchData { "FileSearchData.Frequency.count_50.displayName=21 - 50", "FileSearchData.Frequency.count_100.displayName=51 - 100", "FileSearchData.Frequency.common.displayName=Common", - "FileSearchData.Frequency.unknown.displayName=Unknown", - }) + "FileSearchData.Frequency.unknown.displayName=Unknown",}) enum Frequency { - UNIQUE(0, 1, Bundle.FileSearchData_Frequency_unique_displayName()), - RARE(1, 5, Bundle.FileSearchData_Frequency_rare_displayName()), - COUNT_10(2, 10, Bundle.FileSearchData_Frequency_count_10_displayName()), - COUNT_20(3, 20, Bundle.FileSearchData_Frequency_count_20_displayName()), - COUNT_50(4, 50, Bundle.FileSearchData_Frequency_count_50_displayName()), - COUNT_100(5, 100, Bundle.FileSearchData_Frequency_count_100_displayName()), - COMMON(6, 0, Bundle.FileSearchData_Frequency_common_displayName()), - UNKNOWN(7, 0, Bundle.FileSearchData_Frequency_unknown_displayName()); - + UNIQUE(0, 1, Bundle.FileSearchData_Frequency_unique_displayName()), + RARE(1, 5, Bundle.FileSearchData_Frequency_rare_displayName()), + COUNT_10(2, 10, Bundle.FileSearchData_Frequency_count_10_displayName()), + COUNT_20(3, 20, Bundle.FileSearchData_Frequency_count_20_displayName()), + COUNT_50(4, 50, Bundle.FileSearchData_Frequency_count_50_displayName()), + COUNT_100(5, 100, Bundle.FileSearchData_Frequency_count_100_displayName()), + COMMON(6, 0, Bundle.FileSearchData_Frequency_common_displayName()), + UNKNOWN(7, 0, Bundle.FileSearchData_Frequency_unknown_displayName()); + private final int ranking; private final String displayName; private final int maxOccur; - + Frequency(int ranking, int maxOccur, String displayName) { this.ranking = ranking; this.maxOccur = maxOccur; this.displayName = displayName; } - + /** * Get the rank for sorting. - * + * * @return the rank (lower should be displayed first) */ int getRanking() { return ranking; } - + /** * Get the enum matching the given occurrence count. - * + * * @param count Number of times a file is in the Central Repository. - * - * @return the corresponding enum + * + * @return the corresponding enum */ static Frequency fromCount(long count) { if (count <= UNIQUE.maxOccur) { @@ -97,16 +96,16 @@ class FileSearchData { } return COMMON; } - + /** * Get the list of enums that are valid for filtering. - * + * * @return enums that can be used to filter */ static List getOptionsForFiltering() { return Arrays.asList(UNIQUE, RARE, COUNT_10, COUNT_20, COUNT_50, COUNT_100, COMMON); } - + @Override public String toString() { return displayName; @@ -122,39 +121,38 @@ class FileSearchData { "FileSearchData.FileSize.OVER_50MB.displayName=50 - 200 MB", "FileSearchData.FileSize.OVER_1MB.displayName=1 - 50 MB", "FileSearchData.FileSize.OVER_100KB.displayName=100 KB - 1 MB", - "FileSearchData.FileSize.UNDER_100KB.displayName=Under 100 KB", - }) + "FileSearchData.FileSize.UNDER_100KB.displayName=Under 100 KB",}) enum FileSize { OVER_1GB(0, 1000 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_OVER_1GB_displayName()), - OVER_200MB(1, 200 * BYTES_PER_MB, 1000, Bundle.FileSearchData_FileSize_OVER_200MB_displayName()), - OVER_50MB(2, 50 * BYTES_PER_MB, 200, Bundle.FileSearchData_FileSize_OVER_50MB_displayName()), - OVER_1MB(3, 1 * BYTES_PER_MB, 50, Bundle.FileSearchData_FileSize_OVER_1MB_displayName()), - OVER_100KB(4, 1000, 1 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_OVER_100KB_displayName()), - UNDER_100KB(5, 0, 1000, Bundle.FileSearchData_FileSize_UNDER_100KB_displayName()); + OVER_200MB(1, 200 * BYTES_PER_MB, 1000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_OVER_200MB_displayName()), + OVER_50MB(2, 50 * BYTES_PER_MB, 200 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_OVER_50MB_displayName()), + OVER_1MB(3, 1 * BYTES_PER_MB, 50 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_OVER_1MB_displayName()), + OVER_100KB(4, 100000, 1 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_OVER_100KB_displayName()), + UNDER_100KB(5, 0, 100000, Bundle.FileSearchData_FileSize_UNDER_100KB_displayName()); private final int ranking; // Must be unique for each value private final long minBytes; // Note that the size must be strictly greater than this to match private final long maxBytes; - private final String displayName; + private final String displayName; final static long NO_MAXIMUM = -1; - - FileSize(int ranking, long minMB, long maxMB, String displayName) { + + FileSize(int ranking, long minB, long maxB, String displayName) { this.ranking = ranking; - this.minBytes = minMB; - if (maxMB >= 0) { - this.maxBytes = maxMB; + this.minBytes = minB; + if (maxB >= 0) { + this.maxBytes = maxB; } else { this.maxBytes = NO_MAXIMUM; } this.displayName = displayName; } - + /** - * Get the enum corresponding to the given file size. - * The file size must be strictly greater than minBytes. - * + * Get the enum corresponding to the given file size. The file size must + * be strictly greater than minBytes. + * * @param size the file size - * + * * @return the enum whose range contains the file size */ static FileSize fromSize(long size) { @@ -172,45 +170,45 @@ class FileSearchData { return UNDER_100KB; } } - + /** * Get the upper limit of the range. - * + * * @return the maximum file size that will fit in this range. */ long getMaxBytes() { return maxBytes; } - + /** * Get the lower limit of the range. - * + * * @return the maximum file size that is not part of this range */ long getMinBytes() { return minBytes; } - + /** * Get the rank for sorting. - * + * * @return the rank (lower should be displayed first) */ int getRanking() { return ranking; } - + @Override public String toString() { return displayName; } } - + /** - * Enum representing the file type. - * We don't simply use FileTypeUtils.FileTypeCategory because: - * - Some file types categories overlap - * - It is convenient to have the "OTHER" option for files that don't match the given types + * Enum representing the file type. We don't simply use + * FileTypeUtils.FileTypeCategory because: - Some file types categories + * overlap - It is convenient to have the "OTHER" option for files that + * don't match the given types */ @NbBundle.Messages({ "FileSearchData.FileType.Audio.displayName=Audio", @@ -220,52 +218,52 @@ class FileSearchData { "FileSearchData.FileType.Executables.displayName=Executables", "FileSearchData.FileType.Other.displayName=Other/Unknown"}) enum FileType { - + IMAGE(0, Bundle.FileSearchData_FileType_Image_displayName(), FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes()), AUDIO(1, Bundle.FileSearchData_FileType_Audio_displayName(), FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes()), VIDEO(2, Bundle.FileSearchData_FileType_Video_displayName(), FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes()), EXECUTABLE(3, Bundle.FileSearchData_FileType_Executables_displayName(), FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes()), DOCUMENTS(4, Bundle.FileSearchData_FileType_Documents_displayName(), FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes()), OTHER(5, Bundle.FileSearchData_FileType_Other_displayName(), new ArrayList<>()); - + private final int ranking; // For ordering in the UI private final String displayName; private final Collection mediaTypes; - - private FileType (int value, String displayName, Collection mediaTypes) { + + private FileType(int value, String displayName, Collection mediaTypes) { this.ranking = value; this.displayName = displayName; this.mediaTypes = mediaTypes; } - + /** * Get the MIME types matching this category. - * + * * @return Collection of MIME type strings */ Collection getMediaTypes() { return mediaTypes; } - + @Override public String toString() { return displayName; } - + /** * Get the rank for sorting. - * + * * @return the rank (lower should be displayed first) */ int getRanking() { return ranking; } - + /** * Get the enum matching the given MIME type. - * + * * @param mimeType The MIME type for the file - * + * * @return the corresponding enum (will be OTHER if no types matched) */ static FileType fromMIMEtype(String mimeType) { @@ -276,41 +274,40 @@ class FileSearchData { } return OTHER; } - + /** * Get the list of enums that are valid for filtering. - * + * * @return enums that can be used to filter */ static List getOptionsForFiltering() { return Arrays.asList(IMAGE, AUDIO, VIDEO, EXECUTABLE, DOCUMENTS); } } - + /** * Enum representing the score of the file. */ @NbBundle.Messages({ "FileSearchData.Score.notable.displayName=Notable", "FileSearchData.Score.interesting.displayName=Interesting", - "FileSearchData.Score.unknown.displayName=Unknown", - }) + "FileSearchData.Score.unknown.displayName=Unknown",}) enum Score { NOTABLE(0, Bundle.FileSearchData_Score_notable_displayName()), INTERESTING(1, Bundle.FileSearchData_Score_interesting_displayName()), UNKNOWN(2, Bundle.FileSearchData_Score_unknown_displayName()); - + private final int ranking; private final String displayName; - + Score(int ranking, String displayName) { this.ranking = ranking; this.displayName = displayName; } - + /** * Get the rank for sorting. - * + * * @return the rank (lower should be displayed first) */ int getRanking() { @@ -319,19 +316,19 @@ class FileSearchData { /** * Get the list of enums that are valid for filtering. - * + * * @return enums that can be used to filter */ static List getOptionsForFiltering() { return Arrays.asList(NOTABLE, INTERESTING); } - + @Override public String toString() { return displayName; } - } - + } + private FileSearchData() { // Class should not be instantiated }