From 3519ecc2c2e122edf4681e900a6f00092168c513 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 3 Sep 2019 15:17:58 -0400 Subject: [PATCH 01/10] 5423 working image thumbnail viewer for file discovery --- .../filequery/Bundle.properties-MERGED | 4 + .../filequery/ImageThumbnailPanel.form | 63 +++++++++++ .../filequery/ImageThumbnailPanel.java | 107 ++++++++++++++++++ .../filequery/ImageThumbnailViewer.form | 50 ++++++++ .../filequery/ImageThumbnailViewer.java | 104 +++++++++++++++++ .../filequery/ImageThumbnailWrapper.java | 56 +++++++++ .../autopsy/filequery/ResultsPanel.java | 76 ++++++++++--- .../filequery/VideoThumbnailPanel.form | 2 +- .../filequery/VideoThumbnailPanel.java | 4 +- .../filequery/VideoThumbnailViewer.java | 16 --- 10 files changed, 446 insertions(+), 36 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java create mode 100644 Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form create mode 100644 Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java create mode 100644 Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java diff --git a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED index 5054037b5a..1cfac53de5 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED @@ -117,6 +117,10 @@ FileSorter.SortingMethod.filetype.displayName=By file type FileSorter.SortingMethod.frequency.displayName=By central repo frequency FileSorter.SortingMethod.keywordlist.displayName=By keyword list names FileSorter.SortingMethod.parent.displayName=By parent path +# {0} - numberOfInstances +ImageThumbnailPanel.countLabel.text=Numbber of Instances: {0} +# {0} - fileSize +ImageThumbnailPanel.sizeLabel.text=Size: {0} bytes ResultsDialog.dialogTitle.text=File search results ResultsDialog.exitButton.text=Exit ResultsDialog.searchButton.text=Run another search diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form new file mode 100644 index 0000000000..ac95e5b3f3 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form @@ -0,0 +1,63 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java new file mode 100644 index 0000000000..55d9bbb5c4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java @@ -0,0 +1,107 @@ +/* + * Autopsy + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.filequery; + +import java.awt.Color; +import java.awt.Component; +import javax.swing.ImageIcon; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import org.openide.util.NbBundle; + +/** + * + * @author wschaefer + */ +public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellRenderer { + + private static final long serialVersionUID = 1L; + private static final Color SELECTION_COLOR = new Color(0, 120, 215); + + /** + * Creates new form ImageThumbnailPanel + */ + public ImageThumbnailPanel() { + initComponents(); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + thumbnailPanel = new javax.swing.JPanel(); + thumbnailLabel = new javax.swing.JLabel(); + fileSizeLabel = new javax.swing.JLabel(); + countLabel = new javax.swing.JLabel(); + + thumbnailPanel.setLayout(new java.awt.GridBagLayout()); + thumbnailPanel.add(thumbnailLabel, new java.awt.GridBagConstraints()); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(thumbnailPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(countLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE) + .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(thumbnailPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(countLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel countLabel; + private javax.swing.JLabel fileSizeLabel; + private javax.swing.JLabel thumbnailLabel; + private javax.swing.JPanel thumbnailPanel; + // End of variables declaration//GEN-END:variables + + @NbBundle.Messages({"# {0} - fileSize", + "ImageThumbnailPanel.sizeLabel.text=Size: {0} bytes", + "# {0} - numberOfInstances", + "ImageThumbnailPanel.countLabel.text=Numbber of Instances: {0}"}) + @Override + public Component getListCellRendererComponent(JList list, ImageThumbnailWrapper value, int index, boolean isSelected, boolean cellHasFocus) { + fileSizeLabel.setText(Bundle.ImageThumbnailPanel_sizeLabel_text(value.getResultFile().getFirstInstance().getSize())); + countLabel.setText(Bundle.ImageThumbnailPanel_countLabel_text(value.getResultFile().getAllInstances().size())); + thumbnailLabel.setIcon(new ImageIcon(value.getThumbnail())); + setBackground(isSelected ? SELECTION_COLOR : list.getBackground()); + return this; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form new file mode 100644 index 0000000000..7ff333b8b3 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form @@ -0,0 +1,50 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java new file mode 100644 index 0000000000..c919c1b82f --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java @@ -0,0 +1,104 @@ +/* + * Autopsy + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.filequery; + +import java.util.ArrayList; +import java.util.List; +import javax.swing.DefaultListModel; +import javax.swing.event.ListSelectionListener; +import org.sleuthkit.datamodel.AbstractFile; + +/** + * + * @author wschaefer + */ +public class ImageThumbnailViewer extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + + private final DefaultListModel thumbnailListModel = new DefaultListModel<>(); + + /** + * Creates new form ImageThumbnailViewer + */ + public ImageThumbnailViewer() { + initComponents(); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + thumbnailListScrollPane = new javax.swing.JScrollPane(); + thumbnailList = new javax.swing.JList<>(); + + setLayout(new java.awt.BorderLayout()); + + thumbnailList.setModel(thumbnailListModel); + thumbnailList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); + thumbnailList.setCellRenderer(new ImageThumbnailPanel()); + thumbnailList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP); + thumbnailList.setVisibleRowCount(0); + thumbnailListScrollPane.setViewportView(thumbnailList); + + add(thumbnailListScrollPane, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JList thumbnailList; + private javax.swing.JScrollPane thumbnailListScrollPane; + // End of variables declaration//GEN-END:variables + + /** + * Add a selection listener to the list of thumbnails being displayed. + * + * @param listener The ListSelectionListener to add to the selection model. + */ + void addListSelectionListener(ListSelectionListener listener) { + thumbnailList.getSelectionModel().addListSelectionListener(listener); + } + + List getInstancesForSelected() { + synchronized (this) { + if (thumbnailList.getSelectedIndex() == -1) { + return new ArrayList<>(); + } else { + return thumbnailListModel.getElementAt(thumbnailList.getSelectedIndex()).getResultFile().getAllInstances(); + } + } + } + + void clearViewer() { + synchronized (this) { + thumbnailListModel.removeAllElements(); + } + } + + void addFile(ImageThumbnailWrapper thumbnailWrapper) { + synchronized (this) { + thumbnailListModel.addElement(thumbnailWrapper); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java new file mode 100644 index 0000000000..8950a6e644 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java @@ -0,0 +1,56 @@ +/* + * Autopsy + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.filequery; + +import java.awt.Image; + +/** + * + * @author wschaefer + */ +public class ImageThumbnailWrapper { + + private final Image thumbnail; + private final ResultFile resultFile; + + ImageThumbnailWrapper(Image thumbnail, ResultFile file) { + this.thumbnail = thumbnail; + this.resultFile = file; + } + + /** + * Get the ResultFile which represents the image file which the thumbnail + * was created for. + * + * @return The ResultFile which represents the image file which the + * thumbnail was created for. + */ + ResultFile getResultFile() { + return resultFile; + } + + /** + * Get the thumbnail for the image. + * + * @return The Image which is the thumbnail for the image. + */ + Image getThumbnail() { + return thumbnail; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index 56893c850c..d15edae485 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -32,13 +32,12 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.event.ListSelectionListener; import org.openide.explorer.ExplorerManager; -import org.openide.nodes.AbstractNode; import org.openide.nodes.Node; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; -import org.sleuthkit.autopsy.corecomponents.DataResultViewerThumbnail; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; @@ -50,9 +49,9 @@ import org.sleuthkit.datamodel.TskCoreException; public class ResultsPanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; - private final DataResultViewerThumbnail thumbnailViewer; private final DataResultViewerTable tableViewer; private final VideoThumbnailViewer videoThumbnailViewer; + private final ImageThumbnailViewer imageThumbnailViewer; private List searchFilters; private FileSearch.AttributeType groupingAttribute; private FileGroup.GroupSortingAlgorithm groupSort; @@ -73,8 +72,8 @@ public class ResultsPanel extends javax.swing.JPanel { public ResultsPanel(ExplorerManager explorerManager, EamDb centralRepo) { initComponents(); this.centralRepo = centralRepo; - thumbnailViewer = new DataResultViewerThumbnail(explorerManager); tableViewer = new DataResultViewerTable(explorerManager); + imageThumbnailViewer = new ImageThumbnailViewer(); videoThumbnailViewer = new VideoThumbnailViewer(); // Disable manual editing of page size spinner videoThumbnailViewer.addListSelectionListener((e) -> { @@ -82,6 +81,11 @@ public class ResultsPanel extends javax.swing.JPanel { populateInstancesList(); } }); + imageThumbnailViewer.addListSelectionListener((e) -> { + if (!e.getValueIsAdjusting()) { + populateInstancesList(); + } + }); ((JSpinner.DefaultEditor) pageSizeSpinner.getEditor()).getTextField().setEditable(false); } @@ -112,6 +116,8 @@ public class ResultsPanel extends javax.swing.JPanel { private List getInstancesForSelected() { if (resultType == FileSearchData.FileType.VIDEO) { return videoThumbnailViewer.getInstancesForSelected(); + } else if (resultType == FileSearchData.FileType.IMAGE) { + return imageThumbnailViewer.getInstancesForSelected(); } return new ArrayList<>(); } @@ -127,23 +133,17 @@ public class ResultsPanel extends javax.swing.JPanel { populateInstancesList(); currentPage = pageRetrievedEvent.getPageNumber(); updateControls(); - thumbnailViewer.resetComponent(); + imageThumbnailViewer.clearViewer(); tableViewer.resetComponent(); - resultsViewerPanel.remove(thumbnailViewer); + resultsViewerPanel.remove(imageThumbnailViewer); resultsViewerPanel.remove(tableViewer); resultsViewerPanel.remove(videoThumbnailViewer); if (pageRetrievedEvent.getType() == FileSearchData.FileType.IMAGE) { - resultsViewerPanel.add(thumbnailViewer); - if (pageRetrievedEvent.getSearchResults().size() > 0) { - List filesList = pageRetrievedEvent.getSearchResults().stream().map(file -> file.getFirstInstance()).collect(Collectors.toList()); - thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new DiscoveryThumbnailChildren(filesList))), true)); - } else { - thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); - } + populateImageViewer(pageRetrievedEvent.getSearchResults()); + resultsViewerPanel.add(imageThumbnailViewer); } else if (pageRetrievedEvent.getType() == FileSearchData.FileType.VIDEO) { populateVideoViewer(pageRetrievedEvent.getSearchResults()); resultsViewerPanel.add(videoThumbnailViewer); - } else { resultsViewerPanel.add(tableViewer); if (pageRetrievedEvent.getSearchResults().size() > 0) { @@ -153,7 +153,8 @@ public class ResultsPanel extends javax.swing.JPanel { tableViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); } } - }); + } + ); } synchronized void populateVideoViewer(List files) { @@ -174,6 +175,24 @@ public class ResultsPanel extends javax.swing.JPanel { } } + synchronized void populateImageViewer(List files) { + + for (SwingWorker thumbWorker : thumbnailWorkers) { + if (!thumbWorker.isDone()) { + thumbWorker.cancel(true); + } + } + //clear old thumbnails + thumbnailWorkers.clear(); + imageThumbnailViewer.clearViewer(); + for (ResultFile file : files) { + ImageThumbnailWorker thumbWorker = new ImageThumbnailWorker(file); + thumbWorker.execute(); + //keep track of thumb worker for possible cancelation + thumbnailWorkers.add(thumbWorker); + } + } + /** * Subscribe and respond to GroupSelectedEvents. * @@ -200,8 +219,7 @@ public class ResultsPanel extends javax.swing.JPanel { currentPage = 0; updateControls(); videoThumbnailViewer.clearViewer(); - thumbnailViewer.resetComponent(); - thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); + imageThumbnailViewer.clearViewer(); tableViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); resultsViewerPanel.revalidate(); resultsViewerPanel.repaint(); @@ -522,6 +540,30 @@ public class ResultsPanel extends javax.swing.JPanel { } + private class ImageThumbnailWorker extends SwingWorker { + + private final ResultFile file; + private ImageThumbnailWrapper thumbnailWrapper; + + ImageThumbnailWorker(ResultFile file) { + this.file = file; + } + + @Override + protected Void doInBackground() throws Exception { + thumbnailWrapper = new ImageThumbnailWrapper(ImageUtils.getThumbnail(file.getFirstInstance(), ImageUtils.ICON_SIZE_LARGE), file); + return null; + } + + @Override + protected void done() { + if (!isCancelled()) { + imageThumbnailViewer.addFile(thumbnailWrapper); + } + } + + } + private class InstancesCellRenderer extends DefaultListCellRenderer { private static final long serialVersionUID = 1L; diff --git a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.form index a159e274d6..5f41c66123 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.form @@ -47,7 +47,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.java index e68323f2ee..f272bd1e59 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailPanel.java @@ -35,7 +35,7 @@ import org.openide.util.NbBundle.Messages; final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRenderer { private static final int GAP_SIZE = 4; - private static final Color SELECTION_COLOR = new Color(100, 200, 255); + private static final Color SELECTION_COLOR = new Color(0,120,215); private static final long serialVersionUID = 1L; /** @@ -124,7 +124,7 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE) .addComponent(countLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java index da1ef749a9..2836109af9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java @@ -49,22 +49,6 @@ public class VideoThumbnailViewer extends javax.swing.JPanel { thumbnailList.getSelectionModel().addListSelectionListener(listener); } - /** - * Get the AbstractFile associated with the selected thumbnails. - * - * @return The AbstractFile associated with the selected thumbnails, or null - * if no thumbnails are selected. - */ - AbstractFile getSelectedFile() { - synchronized (this) { - if (thumbnailList.getSelectedIndex() == -1) { - return null; - } else { - return thumbnailListModel.getElementAt(thumbnailList.getSelectedIndex()).getResultFile().getFirstInstance(); - } - } - } - List getInstancesForSelected() { synchronized (this) { if (thumbnailList.getSelectedIndex() == -1) { From 521d8272234793effb18d178524937d7c8e488f9 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 3 Sep 2019 16:48:54 -0400 Subject: [PATCH 02/10] 5423 fix pottential NPE --- Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index d15edae485..27b0fb0d31 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filequery; import com.google.common.eventbus.Subscribe; import java.awt.Component; +import java.awt.Image; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -551,7 +552,11 @@ public class ResultsPanel extends javax.swing.JPanel { @Override protected Void doInBackground() throws Exception { - thumbnailWrapper = new ImageThumbnailWrapper(ImageUtils.getThumbnail(file.getFirstInstance(), ImageUtils.ICON_SIZE_LARGE), file); + Image thumbnail = ImageUtils.getThumbnail(file.getFirstInstance(), ImageUtils.ICON_SIZE_LARGE); + if (thumbnail == null) { + thumbnail = ImageUtils.getDefaultThumbnail(); + } + thumbnailWrapper = new ImageThumbnailWrapper(thumbnail, file); return null; } From cad50a5c1790ba103bbf52d3bd4154bf51df2abe Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 3 Sep 2019 17:57:06 -0400 Subject: [PATCH 03/10] 5423 fix typo with word number --- .../org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED | 2 +- .../org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED index 577f5beb6a..af49cf14a4 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED @@ -118,7 +118,7 @@ FileSorter.SortingMethod.frequency.displayName=By central repo frequency FileSorter.SortingMethod.keywordlist.displayName=By keyword list names FileSorter.SortingMethod.parent.displayName=By parent path # {0} - numberOfInstances -ImageThumbnailPanel.countLabel.text=Numbber of Instances: {0} +ImageThumbnailPanel.countLabel.text=Number of Instances: {0} # {0} - fileSize ImageThumbnailPanel.sizeLabel.text=Size: {0} bytes ResultsDialog.dialogTitle.text=File search results diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java index 55d9bbb5c4..ab90105a1f 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java @@ -94,7 +94,7 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR @NbBundle.Messages({"# {0} - fileSize", "ImageThumbnailPanel.sizeLabel.text=Size: {0} bytes", "# {0} - numberOfInstances", - "ImageThumbnailPanel.countLabel.text=Numbber of Instances: {0}"}) + "ImageThumbnailPanel.countLabel.text=Number of Instances: {0}"}) @Override public Component getListCellRendererComponent(JList list, ImageThumbnailWrapper value, int index, boolean isSelected, boolean cellHasFocus) { fileSizeLabel.setText(Bundle.ImageThumbnailPanel_sizeLabel_text(value.getResultFile().getFirstInstance().getSize())); From 524b0ffe42842f528caec7f5385f144797160f6b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 4 Sep 2019 12:24:31 -0400 Subject: [PATCH 04/10] 5423 disable multi-select --- .../org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form | 2 +- .../org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form index 7ff333b8b3..4d065c3bf9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form @@ -33,7 +33,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java index c919c1b82f..4633aea045 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java @@ -56,7 +56,7 @@ public class ImageThumbnailViewer extends javax.swing.JPanel { setLayout(new java.awt.BorderLayout()); thumbnailList.setModel(thumbnailListModel); - thumbnailList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); + thumbnailList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); thumbnailList.setCellRenderer(new ImageThumbnailPanel()); thumbnailList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP); thumbnailList.setVisibleRowCount(0); From 8722f847b30fbd16e2c20d04b67d890c4cee2afc Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 4 Sep 2019 13:45:09 -0400 Subject: [PATCH 05/10] 5423 preserve ordering of image thumbnails --- .../filequery/ImageThumbnailWrapper.java | 12 +++-- .../autopsy/filequery/ResultsPanel.java | 49 ++++++++++--------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java index 8950a6e644..2d671fe0ee 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.filequery; import java.awt.Image; +import org.sleuthkit.autopsy.coreutils.ImageUtils; /** * @@ -26,14 +27,19 @@ import java.awt.Image; */ public class ImageThumbnailWrapper { - private final Image thumbnail; + private Image thumbnail; private final ResultFile resultFile; - ImageThumbnailWrapper(Image thumbnail, ResultFile file) { - this.thumbnail = thumbnail; + + ImageThumbnailWrapper(ResultFile file) { + this.thumbnail = ImageUtils.getDefaultThumbnail(); this.resultFile = file; } + void setImageThumbnail(Image thumbnail){ + this.thumbnail = thumbnail; + } + /** * Get the ResultFile which represents the image file which the thumbnail * was created for. diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index 5ecf154a54..1958528821 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -529,34 +529,39 @@ public class ResultsPanel extends javax.swing.JPanel { @Override protected Void doInBackground() throws Exception { FileSearch.getVideoThumbnails(thumbnailWrapper); - videoThumbnailViewer.repaint(); - return null; - } - } - - private class ImageThumbnailWorker extends SwingWorker { - - private final ResultFile file; - private ImageThumbnailWrapper thumbnailWrapper; - - ImageThumbnailWorker(ResultFile file) { - this.file = file; - } - - @Override - protected Void doInBackground() throws Exception { - Image thumbnail = ImageUtils.getThumbnail(file.getFirstInstance(), ImageUtils.ICON_SIZE_LARGE); - if (thumbnail == null) { - thumbnail = ImageUtils.getDefaultThumbnail(); - } - thumbnailWrapper = new ImageThumbnailWrapper(thumbnail, file); return null; } @Override protected void done() { if (!isCancelled()) { - imageThumbnailViewer.addFile(thumbnailWrapper); + videoThumbnailViewer.repaint(); + } + } + } + + private class ImageThumbnailWorker extends SwingWorker { + + private ImageThumbnailWrapper thumbnailWrapper; + + ImageThumbnailWorker(ResultFile file) { + thumbnailWrapper = new ImageThumbnailWrapper(file); + imageThumbnailViewer.addFile(thumbnailWrapper); + } + + @Override + protected Void doInBackground() throws Exception { + Image thumbnail = ImageUtils.getThumbnail(thumbnailWrapper.getResultFile().getFirstInstance(), ImageUtils.ICON_SIZE_LARGE); + if (thumbnail != null) { + thumbnailWrapper.setImageThumbnail(thumbnail); + } + return null; + } + + @Override + protected void done() { + if (!isCancelled()) { + imageThumbnailViewer.repaint(); } } From b526772481d84389f92b8e1bba8fc73a64180f13 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 4 Sep 2019 16:08:42 -0400 Subject: [PATCH 06/10] 5423 clean up and add comments --- .../filequery/ImageThumbnailPanel.java | 3 +- .../filequery/ImageThumbnailViewer.java | 22 +++++- .../filequery/ImageThumbnailWrapper.java | 20 ++++-- .../autopsy/filequery/ResultsPanel.java | 68 +++++++++++++++++-- .../filequery/VideoThumbnailViewer.java | 9 ++- .../filequery/VideoThumbnailsWrapper.java | 27 +++++--- 6 files changed, 121 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java index ab90105a1f..f2ad61326c 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java @@ -26,8 +26,7 @@ import javax.swing.ListCellRenderer; import org.openide.util.NbBundle; /** - * - * @author wschaefer + * Class which displays a thumbnail and information for an image file. */ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellRenderer { diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java index 4633aea045..140d211bfe 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java @@ -25,8 +25,8 @@ import javax.swing.event.ListSelectionListener; import org.sleuthkit.datamodel.AbstractFile; /** + * A JPanel to display image thumbnails. * - * @author wschaefer */ public class ImageThumbnailViewer extends javax.swing.JPanel { @@ -79,7 +79,14 @@ public class ImageThumbnailViewer extends javax.swing.JPanel { void addListSelectionListener(ListSelectionListener listener) { thumbnailList.getSelectionModel().addListSelectionListener(listener); } - + + /** + * Get the list of AbstractFiles which are represented by the selected image + * thumbnail. + * + * @return The list of AbstractFiles which are represented by the selected image + * thumbnail. + */ List getInstancesForSelected() { synchronized (this) { if (thumbnailList.getSelectedIndex() == -1) { @@ -90,13 +97,22 @@ public class ImageThumbnailViewer extends javax.swing.JPanel { } } + /** + * Clear the list of thumbnails being displayed. + */ void clearViewer() { synchronized (this) { thumbnailListModel.removeAllElements(); } } - void addFile(ImageThumbnailWrapper thumbnailWrapper) { + /** + * Add the thumbnail for an image to the panel. + * + * @param thumbnailWrapper The object which contains the thumbnail which + * will be displayed. + */ + void addImage(ImageThumbnailWrapper thumbnailWrapper) { synchronized (this) { thumbnailListModel.addElement(thumbnailWrapper); } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java index 2d671fe0ee..dd1923007d 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailWrapper.java @@ -22,24 +22,34 @@ import java.awt.Image; import org.sleuthkit.autopsy.coreutils.ImageUtils; /** - * - * @author wschaefer + * Class to wrap all the information necessary for an image thumbnail to be + * displayed. */ public class ImageThumbnailWrapper { private Image thumbnail; private final ResultFile resultFile; - + /** + * Construct a new ImageThumbnailsWrapper. + * + * @param file The ResultFile which represents the image file which the + * thumbnails were created for. + */ ImageThumbnailWrapper(ResultFile file) { this.thumbnail = ImageUtils.getDefaultThumbnail(); this.resultFile = file; } - void setImageThumbnail(Image thumbnail){ + /** + * Set the image thumbnail which exists. + * + * @param thumbnail The thumbnail which exists for this file. + */ + void setImageThumbnail(Image thumbnail) { this.thumbnail = thumbnail; } - + /** * Get the ResultFile which represents the image file which the thumbnail * was created for. diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index 1958528821..c4e6191da9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -76,7 +76,6 @@ public class ResultsPanel extends javax.swing.JPanel { tableViewer = new DataResultViewerTable(explorerManager); imageThumbnailViewer = new ImageThumbnailViewer(); videoThumbnailViewer = new VideoThumbnailViewer(); - // Disable manual editing of page size spinner videoThumbnailViewer.addListSelectionListener((e) -> { if (!e.getValueIsAdjusting()) { populateInstancesList(); @@ -87,13 +86,22 @@ public class ResultsPanel extends javax.swing.JPanel { populateInstancesList(); } }); + // Disable manual editing of page size spinner ((JSpinner.DefaultEditor) pageSizeSpinner.getEditor()).getTextField().setEditable(false); } + /** + * Add a list selection listener to the instances list. + * + * @param listener The ListSelectionListener to add to the instances list. + */ void addListSelectionListener(ListSelectionListener listener) { instancesList.addListSelectionListener(listener); } + /** + * Populate the instances list. + */ synchronized void populateInstancesList() { SwingUtilities.invokeLater(() -> { instancesListModel.removeAllElements(); @@ -106,6 +114,12 @@ public class ResultsPanel extends javax.swing.JPanel { }); } + /** + * Get the AbstractFile for the item currently selected in the instances + * list. + * + * @return The AbstractFile which is currently selected. + */ synchronized AbstractFile getSelectedFile() { if (instancesList.getSelectedIndex() == -1) { return null; @@ -114,6 +128,13 @@ public class ResultsPanel extends javax.swing.JPanel { } } + /** + * Get the list of all instances for the the currently selected item in the + * results viewer area. + * + * @return The list of AbstractFiles which are represented by the item + * selected in the results viewer area. + */ private List getInstancesForSelected() { if (resultType == FileSearchData.FileType.VIDEO) { return videoThumbnailViewer.getInstancesForSelected(); @@ -135,6 +156,7 @@ public class ResultsPanel extends javax.swing.JPanel { currentPage = pageRetrievedEvent.getPageNumber(); updateControls(); imageThumbnailViewer.clearViewer(); + videoThumbnailViewer.clearViewer(); tableViewer.resetComponent(); resultsViewerPanel.remove(imageThumbnailViewer); resultsViewerPanel.remove(tableViewer); @@ -158,6 +180,12 @@ public class ResultsPanel extends javax.swing.JPanel { ); } + /** + * Populate the video thumbnail viewer, cancelling any thumbnails which are + * currently being created first. + * + * @param files The list of ResultFiles to populate the video viewer with. + */ synchronized void populateVideoViewer(List files) { //cancel any unfished thumb workers for (SwingWorker thumbWorker : thumbnailWorkers) { @@ -176,8 +204,13 @@ public class ResultsPanel extends javax.swing.JPanel { } } + /** + * Populate the image thumbnail viewer, cancelling any thumbnails which are + * currently being created first. + * + * @param files The list of ResultFiles to populate the image viewer with. + */ synchronized void populateImageViewer(List files) { - for (SwingWorker thumbWorker : thumbnailWorkers) { if (!thumbWorker.isDone()) { thumbWorker.cancel(true); @@ -517,13 +550,23 @@ public class ResultsPanel extends javax.swing.JPanel { private javax.swing.JPanel resultsViewerPanel; // End of variables declaration//GEN-END:variables + /** + * Swing worker to handle the retrieval of video thumbnails and population + * of the Video Thumbnail Viewer. + */ private class VideoThumbnailWorker extends SwingWorker { private final VideoThumbnailsWrapper thumbnailWrapper; + /** + * Construct a new VideoThumbnailWorker. + * + * @param file The ResultFile which represents the video file thumbnails + * are being retrieved for. + */ VideoThumbnailWorker(ResultFile file) { - thumbnailWrapper = new VideoThumbnailsWrapper(new ArrayList(), new int[4], file); - videoThumbnailViewer.addRow(thumbnailWrapper); + thumbnailWrapper = new VideoThumbnailsWrapper(file); + videoThumbnailViewer.addVideo(thumbnailWrapper); } @Override @@ -540,13 +583,23 @@ public class ResultsPanel extends javax.swing.JPanel { } } + /** + * Swing worker to handle the retrieval of image thumbnails and population + * of the Image Thumbnail Viewer. + */ private class ImageThumbnailWorker extends SwingWorker { - private ImageThumbnailWrapper thumbnailWrapper; + private final ImageThumbnailWrapper thumbnailWrapper; + /** + * Construct a new ImageThumbnailWorker. + * + * @param file The ResultFile which represents the image file thumbnails + * are being retrieved for. + */ ImageThumbnailWorker(ResultFile file) { thumbnailWrapper = new ImageThumbnailWrapper(file); - imageThumbnailViewer.addFile(thumbnailWrapper); + imageThumbnailViewer.addImage(thumbnailWrapper); } @Override @@ -567,6 +620,9 @@ public class ResultsPanel extends javax.swing.JPanel { } + /** + * Cell renderer for the instances list. + */ private class InstancesCellRenderer extends DefaultListCellRenderer { private static final long serialVersionUID = 1L; diff --git a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java index 2836109af9..9994506a0e 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailViewer.java @@ -49,6 +49,13 @@ public class VideoThumbnailViewer extends javax.swing.JPanel { thumbnailList.getSelectionModel().addListSelectionListener(listener); } + /** + * Get the list of AbstractFiles which are represented by the selected Video + * thumbnails. + * + * @return The list of AbstractFiles which are represented by the selected Video + * thumbnails. + */ List getInstancesForSelected() { synchronized (this) { if (thumbnailList.getSelectedIndex() == -1) { @@ -74,7 +81,7 @@ public class VideoThumbnailViewer extends javax.swing.JPanel { * @param thumbnailWrapper The object which contains the thumbnails which * will be displayed. */ - void addRow(VideoThumbnailsWrapper thumbnailWrapper) { + void addVideo(VideoThumbnailsWrapper thumbnailWrapper) { synchronized (this) { thumbnailListModel.addElement(thumbnailWrapper); } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java index 106910e87e..5f9af3681e 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.filequery; import java.awt.Image; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -35,16 +36,12 @@ final class VideoThumbnailsWrapper { /** * Construct a new VideoThumbnailsWrapper. * - * @param thumbnails The list of Images which are the thumbnails for the - * video. - * @param timeStamps An array containing the time in milliseconds into the - * video that each thumbnail created for. - * @param file The ResultFile which represents the video file which - * the thumbnails were created for. + * @param file The ResultFile which represents the video file which the + * thumbnails were created for. */ - VideoThumbnailsWrapper(List thumbnails, int[] timeStamps, ResultFile file) { - this.thumbnails = thumbnails; - this.timeStamps = timeStamps; + VideoThumbnailsWrapper(ResultFile file) { + this.thumbnails = new ArrayList<>(); + this.timeStamps = new int[4]; this.resultFile = file; } @@ -79,9 +76,17 @@ final class VideoThumbnailsWrapper { return Collections.unmodifiableList(thumbnails); } + /** + * Set the thumbnails and their associated time stamps. + * + * @param videoThumbnails The list of Images which are the thumbnails for + * the video. + * @param framePositions An array containing the time in milliseconds into + * the video that each thumbnail created for. + */ void setThumbnails(List videoThumbnails, int[] framePositions) { - this.thumbnails = videoThumbnails; - this.timeStamps = framePositions; + this.thumbnails.addAll(videoThumbnails); + this.timeStamps = framePositions.clone(); } } From b1f8f630beab6c7f4e4cb7cf70f4a3efcb37bf72 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 4 Sep 2019 16:08:51 -0400 Subject: [PATCH 07/10] 5423 clean up and add comments --- .../org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java index 5f9af3681e..08c68611c0 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/VideoThumbnailsWrapper.java @@ -29,7 +29,7 @@ import java.util.List; */ final class VideoThumbnailsWrapper { - private List thumbnails; + private final List thumbnails; private final ResultFile resultFile; private int[] timeStamps; From 8aba6c9d9ee6bf32b7e8679d65d84220f12e9437 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 4 Sep 2019 17:46:52 -0400 Subject: [PATCH 08/10] 5423 address codacy complaints --- .../org/sleuthkit/autopsy/filequery/FileSearch.java | 4 ++-- .../autopsy/filequery/ImageThumbnailPanel.form | 4 ++++ .../autopsy/filequery/ImageThumbnailPanel.java | 3 +-- .../autopsy/filequery/ImageThumbnailViewer.form | 2 ++ .../autopsy/filequery/ImageThumbnailViewer.java | 3 +-- .../org/sleuthkit/autopsy/filequery/ResultsPanel.form | 10 ++++++++++ .../org/sleuthkit/autopsy/filequery/ResultsPanel.java | 9 +++------ .../org/sleuthkit/autopsy/filequery/SearchResults.java | 4 ++-- 8 files changed, 25 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 5d269629f8..fcabca4238 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -116,7 +116,7 @@ class FileSearch { // Sort and group the results searchResults.sortGroupsAndFiles(); - LinkedHashMap> resultHashMap = searchResults.toLinkedHashMap(); + Map> resultHashMap = searchResults.toLinkedHashMap(); for (String groupName : resultHashMap.keySet()) { groupCache.put(groupName, resultHashMap.get(groupName)); } @@ -251,7 +251,7 @@ class FileSearch { // Collect everything in the search results SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod); searchResults.add(resultFiles); - LinkedHashMap> resultHashMap = searchResults.toLinkedHashMap(); + Map> resultHashMap = searchResults.toLinkedHashMap(); for (String groupName : resultHashMap.keySet()) { groupCache.put(groupName, resultHashMap.get(groupName)); } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form index ac95e5b3f3..bc2f036c23 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.form @@ -43,6 +43,10 @@
+ + + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java index f2ad61326c..d73a6e4d0c 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailPanel.java @@ -49,7 +49,7 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR // //GEN-BEGIN:initComponents private void initComponents() { - thumbnailPanel = new javax.swing.JPanel(); + javax.swing.JPanel thumbnailPanel = new javax.swing.JPanel(); thumbnailLabel = new javax.swing.JLabel(); fileSizeLabel = new javax.swing.JLabel(); countLabel = new javax.swing.JLabel(); @@ -87,7 +87,6 @@ public class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellR private javax.swing.JLabel countLabel; private javax.swing.JLabel fileSizeLabel; private javax.swing.JLabel thumbnailLabel; - private javax.swing.JPanel thumbnailPanel; // End of variables declaration//GEN-END:variables @NbBundle.Messages({"# {0} - fileSize", diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form index 4d065c3bf9..4b96bac8ae 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.form @@ -18,6 +18,8 @@ + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java index 140d211bfe..1524f60820 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ImageThumbnailViewer.java @@ -50,7 +50,7 @@ public class ImageThumbnailViewer extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - thumbnailListScrollPane = new javax.swing.JScrollPane(); + javax.swing.JScrollPane thumbnailListScrollPane = new javax.swing.JScrollPane(); thumbnailList = new javax.swing.JList<>(); setLayout(new java.awt.BorderLayout()); @@ -68,7 +68,6 @@ public class ImageThumbnailViewer extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JList thumbnailList; - private javax.swing.JScrollPane thumbnailListScrollPane; // End of variables declaration//GEN-END:variables /** diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form index 8e26e73944..c666c85413 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form @@ -238,10 +238,18 @@ + + + + + + + + @@ -269,6 +277,8 @@ + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index c4e6191da9..3477c614bd 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -313,9 +313,9 @@ public class ResultsPanel extends javax.swing.JPanel { javax.swing.JLabel gotoPageLabel = new javax.swing.JLabel(); gotoPageField = new javax.swing.JTextField(); javax.swing.JLabel pageSizeLabel = new javax.swing.JLabel(); - resultsSplitPane = new javax.swing.JSplitPane(); - instancesPanel = new javax.swing.JPanel(); - instancesScrollPane = new javax.swing.JScrollPane(); + javax.swing.JSplitPane resultsSplitPane = new javax.swing.JSplitPane(); + javax.swing.JPanel instancesPanel = new javax.swing.JPanel(); + javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane(); instancesList = new javax.swing.JList<>(); resultsViewerPanel = new javax.swing.JPanel(); @@ -540,13 +540,10 @@ public class ResultsPanel extends javax.swing.JPanel { private javax.swing.JLabel currentPageLabel; private javax.swing.JTextField gotoPageField; private javax.swing.JList instancesList; - private javax.swing.JPanel instancesPanel; - private javax.swing.JScrollPane instancesScrollPane; private javax.swing.JButton nextPageButton; private javax.swing.JSpinner pageSizeSpinner; private javax.swing.JPanel pagingPanel; private javax.swing.JButton previousPageButton; - private javax.swing.JSplitPane resultsSplitPane; private javax.swing.JPanel resultsViewerPanel; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java b/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java index 91bb93e865..f48cd4d1f8 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/SearchResults.java @@ -150,8 +150,8 @@ class SearchResults { * * @return the grouped and sorted results */ - LinkedHashMap> toLinkedHashMap() throws FileSearchException { - LinkedHashMap> map = new LinkedHashMap<>(); + Map> toLinkedHashMap() throws FileSearchException { + Map> map = new LinkedHashMap<>(); // Sort the groups and files sortGroupsAndFiles(); From 04e0fe7ad6ff2b71f90494d1f05c0cbdbb0db40f Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 5 Sep 2019 11:48:09 -0400 Subject: [PATCH 09/10] 5423 hopefully fix refresh issue and reduce duplicate code --- .../autopsy/filequery/ResultsPanel.java | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index 3477c614bd..d8798a42e4 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -155,12 +155,7 @@ public class ResultsPanel extends javax.swing.JPanel { populateInstancesList(); currentPage = pageRetrievedEvent.getPageNumber(); updateControls(); - imageThumbnailViewer.clearViewer(); - videoThumbnailViewer.clearViewer(); - tableViewer.resetComponent(); - resultsViewerPanel.remove(imageThumbnailViewer); - resultsViewerPanel.remove(tableViewer); - resultsViewerPanel.remove(videoThumbnailViewer); + resetResultViewer(); if (pageRetrievedEvent.getType() == FileSearchData.FileType.IMAGE) { populateImageViewer(pageRetrievedEvent.getSearchResults()); resultsViewerPanel.add(imageThumbnailViewer); @@ -176,17 +171,22 @@ public class ResultsPanel extends javax.swing.JPanel { tableViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); } } + resultsViewerPanel.revalidate(); + resultsViewerPanel.repaint(); } ); } /** - * Populate the video thumbnail viewer, cancelling any thumbnails which are - * currently being created first. - * - * @param files The list of ResultFiles to populate the video viewer with. + * Reset the result viewer and any associate workers to a default empty + * state. */ - synchronized void populateVideoViewer(List files) { + private synchronized void resetResultViewer() { + resultsViewerPanel.remove(imageThumbnailViewer); + tableViewer.resetComponent(); + resultsViewerPanel.remove(tableViewer); + resultsViewerPanel.remove(videoThumbnailViewer); + //cancel any unfished thumb workers for (SwingWorker thumbWorker : thumbnailWorkers) { if (!thumbWorker.isDone()) { @@ -196,6 +196,16 @@ public class ResultsPanel extends javax.swing.JPanel { //clear old thumbnails thumbnailWorkers.clear(); videoThumbnailViewer.clearViewer(); + imageThumbnailViewer.clearViewer(); + } + + /** + * Populate the video thumbnail viewer, cancelling any thumbnails which are + * currently being created first. + * + * @param files The list of ResultFiles to populate the video viewer with. + */ + synchronized void populateVideoViewer(List files) { for (ResultFile file : files) { VideoThumbnailWorker thumbWorker = new VideoThumbnailWorker(file); thumbWorker.execute(); @@ -211,14 +221,6 @@ public class ResultsPanel extends javax.swing.JPanel { * @param files The list of ResultFiles to populate the image viewer with. */ synchronized void populateImageViewer(List files) { - for (SwingWorker thumbWorker : thumbnailWorkers) { - if (!thumbWorker.isDone()) { - thumbWorker.cancel(true); - } - } - //clear old thumbnails - thumbnailWorkers.clear(); - imageThumbnailViewer.clearViewer(); for (ResultFile file : files) { ImageThumbnailWorker thumbWorker = new ImageThumbnailWorker(file); thumbWorker.execute(); @@ -574,9 +576,7 @@ public class ResultsPanel extends javax.swing.JPanel { @Override protected void done() { - if (!isCancelled()) { - videoThumbnailViewer.repaint(); - } + videoThumbnailViewer.repaint(); } } @@ -610,9 +610,7 @@ public class ResultsPanel extends javax.swing.JPanel { @Override protected void done() { - if (!isCancelled()) { - imageThumbnailViewer.repaint(); - } + imageThumbnailViewer.repaint(); } } From e8d81c4240532e04802bab51b70376c951fbe0ef Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 17 Sep 2019 11:57:57 -0400 Subject: [PATCH 10/10] 5423 prevent multi-select in instances list --- Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form | 1 + Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java | 1 + 2 files changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form index c666c85413..97080a329a 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form @@ -296,6 +296,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index d8798a42e4..5809eb6051 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -427,6 +427,7 @@ public class ResultsPanel extends javax.swing.JPanel { instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.instancesList.border.title"))); // NOI18N instancesList.setModel(instancesListModel); + instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); instancesList.setCellRenderer(new InstancesCellRenderer()); instancesScrollPane.setViewportView(instancesList);