Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ResultsPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy
3  *
4  * Copyright 2019-2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.filequery;
20 
21 import com.google.common.eventbus.Subscribe;
22 import java.awt.Component;
23 import java.awt.Image;
24 import java.awt.event.ItemEvent;
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.concurrent.CancellationException;
32 import java.util.concurrent.ExecutionException;
33 import java.util.logging.Level;
34 import javax.swing.DefaultComboBoxModel;
35 import javax.swing.DefaultListCellRenderer;
36 import javax.swing.DefaultListModel;
37 import javax.swing.JList;
38 import javax.swing.JOptionPane;
39 import javax.swing.JPopupMenu;
40 import javax.swing.SwingUtilities;
41 import javax.swing.SwingWorker;
42 import javax.swing.event.ListSelectionListener;
43 import org.openide.util.NbBundle.Messages;
55 import org.sleuthkit.datamodel.AbstractFile;
56 import org.sleuthkit.datamodel.TskCoreException;
59 
64 public class ResultsPanel extends javax.swing.JPanel {
65 
66  private static final long serialVersionUID = 1L;
67  private final static Logger logger = Logger.getLogger(ResultsPanel.class.getName());
71  private List<FileSearchFiltering.FileFilter> searchFilters;
72  private FileSearch.AttributeType groupingAttribute;
73  private FileGroup.GroupSortingAlgorithm groupSort;
74  private FileSorter.SortingMethod fileSortMethod;
75  private GroupKey selectedGroupKey;
76  private int currentPage = 0;
77  private int previousPageSize = 10;
78  private FileSearchData.FileType resultType;
79  private int groupSize = 0;
80  private PageWorker pageWorker;
81  private final List<SwingWorker<Void, Void>> resultContentWorkers = new ArrayList<>();
82  private final DefaultListModel<AbstractFile> instancesListModel = new DefaultListModel<>();
83  private ListSelectionListener listener = null;
84 
88  @Messages({"ResultsPanel.viewFileInDir.name=View File in Directory",
89  "ResultsPanel.openInExternalViewer.name=Open in External Viewer"})
90  public ResultsPanel() {
92  imageThumbnailViewer = new ImageThumbnailViewer();
93  videoThumbnailViewer = new VideoThumbnailViewer();
94  documentPreviewViewer = new DocumentPreviewViewer();
95  videoThumbnailViewer.addListSelectionListener((e) -> {
96  if (resultType == FileSearchData.FileType.VIDEO) {
97  if (!e.getValueIsAdjusting()) {
98  populateInstancesList();
99  } else {
100  instancesList.clearSelection();
101  }
102  }
103  });
104  imageThumbnailViewer.addListSelectionListener((e) -> {
105  if (resultType == FileSearchData.FileType.IMAGE) {
106  if (!e.getValueIsAdjusting()) {
107  populateInstancesList();
108  } else {
109  instancesList.clearSelection();
110  }
111  }
112  });
113  documentPreviewViewer.addListSelectionListener((e) -> {
114  if (resultType == FileSearchData.FileType.DOCUMENTS) {
115  if (!e.getValueIsAdjusting()) {
116  populateInstancesList();
117  } else {
118  instancesList.clearSelection();
119  }
120  }
121  });
122  //Add the context menu when right clicking
123  instancesList.addMouseListener(new MouseAdapter() {
124  @Override
125  public void mousePressed(MouseEvent e) {
126  if (SwingUtilities.isRightMouseButton(e)) {
127  SwingUtilities.invokeLater(() -> {
128  instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint()));
129  Set<AbstractFile> files = new HashSet<>();
130  files.add(instancesList.getSelectedValue());
131  JPopupMenu menu = new JPopupMenu();
132  menu.add(new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue()));
133  menu.add(new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(), new FileNode(instancesList.getSelectedValue())));
134  menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue()));
135  menu.add(new DiscoveryExtractAction(files));
136  menu.add(AddContentTagAction.getInstance().getMenuForContent(files));
137  menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files));
138  menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files));
139  menu.show(instancesList, e.getPoint().x, e.getPoint().y);
140  });
141  }
142  }
143  });
144 
145  }
146 
152  void addListSelectionListener(ListSelectionListener newListener) {
153  instancesList.removeListSelectionListener(listener);
154  listener = newListener;
155  instancesList.addListSelectionListener(listener);
156  }
157 
161  synchronized void populateInstancesList() {
162  SwingUtilities.invokeLater(() -> {
163  List<AbstractFile> files = getInstancesForSelected();
164  if (files.isEmpty()) {
165  //if there are no files currently remove the current items without removing listener to cause content viewer to reset
166  instancesListModel.removeAllElements();
167  } else {
168  //remove listener so content viewer node is not set multiple times
169  instancesList.removeListSelectionListener(listener);
170  instancesListModel.removeAllElements();
171  for (AbstractFile file : files) {
172  instancesListModel.addElement(file);
173  }
174  //add listener back to allow selection of first index to cause content viewer node to be set
175  instancesList.addListSelectionListener(listener);
176  if (!instancesListModel.isEmpty()) {
177  instancesList.setSelectedIndex(0);
178  }
179  }
180  });
181  }
182 
189  synchronized AbstractFile getSelectedFile() {
190  if (instancesList.getSelectedIndex() == -1) {
191  return null;
192  } else {
193  return instancesListModel.getElementAt(instancesList.getSelectedIndex());
194  }
195  }
196 
204  private List<AbstractFile> getInstancesForSelected() {
205  if (null != resultType) {
206  switch (resultType) {
207  case VIDEO:
208  return videoThumbnailViewer.getInstancesForSelected();
209  case IMAGE:
210  return imageThumbnailViewer.getInstancesForSelected();
211  case DOCUMENTS:
212  return documentPreviewViewer.getInstancesForSelected();
213  default:
214  break;
215  }
216  }
217  return new ArrayList<>();
218  }
219 
225  @Subscribe
226  void handlePageRetrievedEvent(DiscoveryEventUtils.PageRetrievedEvent pageRetrievedEvent) {
227  SwingUtilities.invokeLater(() -> {
228  populateInstancesList();
229  currentPage = pageRetrievedEvent.getPageNumber();
230  updateControls();
231  resetResultViewer();
232  if (null != pageRetrievedEvent.getType()) {
233  switch (pageRetrievedEvent.getType()) {
234  case IMAGE:
235  populateImageViewer(pageRetrievedEvent.getSearchResults());
236  resultsViewerPanel.add(imageThumbnailViewer);
237  break;
238  case VIDEO:
239  populateVideoViewer(pageRetrievedEvent.getSearchResults());
240  resultsViewerPanel.add(videoThumbnailViewer);
241  break;
242  case DOCUMENTS:
243  populateDocumentViewer(pageRetrievedEvent.getSearchResults());
244  resultsViewerPanel.add(documentPreviewViewer);
245  break;
246  default:
247  break;
248  }
249  }
250  resultsViewerPanel.revalidate();
251  resultsViewerPanel.repaint();
252  }
253  );
254  }
255 
260  synchronized void resetResultViewer() {
261  resultsViewerPanel.remove(imageThumbnailViewer);
262  resultsViewerPanel.remove(videoThumbnailViewer);
263  resultsViewerPanel.remove(documentPreviewViewer);
264  //cancel any unfished thumb workers
265  for (SwingWorker<Void, Void> thumbWorker : resultContentWorkers) {
266  if (!thumbWorker.isDone()) {
267  thumbWorker.cancel(true);
268  }
269  }
270  //clear old thumbnails
271  resultContentWorkers.clear();
272  videoThumbnailViewer.clearViewer();
273  imageThumbnailViewer.clearViewer();
274  documentPreviewViewer.clearViewer();
275  }
276 
283  synchronized void populateVideoViewer(List<ResultFile> files) {
284  for (ResultFile file : files) {
285  VideoThumbnailWorker thumbWorker = new VideoThumbnailWorker(file);
286  thumbWorker.execute();
287  //keep track of thumb worker for possible cancelation
288  resultContentWorkers.add(thumbWorker);
289  }
290  }
291 
298  synchronized void populateImageViewer(List<ResultFile> files) {
299  for (ResultFile file : files) {
300  ImageThumbnailWorker thumbWorker = new ImageThumbnailWorker(file);
301  thumbWorker.execute();
302  //keep track of thumb worker for possible cancelation
303  resultContentWorkers.add(thumbWorker);
304  }
305  }
306 
313  synchronized void populateDocumentViewer(List<ResultFile> files) {
314  for (ResultFile file : files) {
315  DocumentPreviewWorker documentWorker = new DocumentPreviewWorker(file);
316  documentWorker.execute();
317  //keep track of thumb worker for possible cancelation
318  resultContentWorkers.add(documentWorker);
319  }
320  }
321 
327  @Subscribe
328  void handleGroupSelectedEvent(DiscoveryEventUtils.GroupSelectedEvent groupSelectedEvent) {
329  SwingUtilities.invokeLater(() -> {
330  searchFilters = groupSelectedEvent.getFilters();
331  groupingAttribute = groupSelectedEvent.getGroupingAttr();
332  groupSort = groupSelectedEvent.getGroupSort();
333  fileSortMethod = groupSelectedEvent.getFileSort();
334  selectedGroupKey = groupSelectedEvent.getGroupKey();
335  resultType = groupSelectedEvent.getResultType();
336  groupSize = groupSelectedEvent.getGroupSize();
337  setPage(0);
338  });
339  }
340 
347  @Subscribe
348  void handleNoResultsEvent(DiscoveryEventUtils.NoResultsEvent noResultsEvent) {
349  SwingUtilities.invokeLater(() -> {
350  groupSize = 0;
351  currentPage = 0;
352  updateControls();
353  videoThumbnailViewer.clearViewer();
354  imageThumbnailViewer.clearViewer();
355  documentPreviewViewer.clearViewer();
356  resultsViewerPanel.revalidate();
357  resultsViewerPanel.repaint();
358  });
359  }
360 
367  private synchronized void setPage(int startingEntry) {
368  int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
369  synchronized (this) {
370  if (pageWorker != null && !pageWorker.isDone()) {
371  pageWorker.cancel(true);
372  }
373  CentralRepository centralRepo = null;
375  try {
376  centralRepo = CentralRepository.getInstance();
377  } catch (CentralRepoException ex) {
378  centralRepo = null;
379  logger.log(Level.SEVERE, "Error loading central repository database, no central repository options will be available for File Discovery", ex);
380  }
381  }
382  pageWorker = new PageWorker(searchFilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupKey, startingEntry, pageSize, resultType, centralRepo);
383  pageWorker.execute();
384  }
385  }
386 
390  @Messages({"# {0} - currentPage",
391  "# {1} - totalPages",
392  "ResultsPanel.currentPage.displayValue=Page: {0} of {1}"})
393  private void updateControls() {
394  previousPageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
395  int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
396  //handle edge case where group size is 0 and we want the empty results to be labeled paged 1 of 1 not page 1 of 0
397  double maxPageDouble = groupSize == 0 ? 1 : Math.ceil((double) groupSize / pageSize);
398  currentPageLabel.setText(Bundle.ResultsPanel_currentPage_displayValue(currentPage + 1, maxPageDouble));
399  previousPageButton.setEnabled(currentPage != 0);
400  nextPageButton.setEnabled(groupSize > ((currentPage + 1) * pageSize));
401  gotoPageField.setEnabled(groupSize > pageSize);
402  pageSizeComboBox.setEnabled(true);
403  }
404 
410  @SuppressWarnings("unchecked")
411  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
412  private void initComponents() {
413 
414  javax.swing.JPanel pagingPanel = new javax.swing.JPanel();
415  previousPageButton = new javax.swing.JButton();
416  currentPageLabel = new javax.swing.JLabel();
417  nextPageButton = new javax.swing.JButton();
418  javax.swing.JLabel pageControlsLabel = new javax.swing.JLabel();
419  javax.swing.JLabel gotoPageLabel = new javax.swing.JLabel();
420  gotoPageField = new javax.swing.JTextField();
421  javax.swing.JLabel pageSizeLabel = new javax.swing.JLabel();
422  pageSizeComboBox = new javax.swing.JComboBox<>();
423  javax.swing.JSplitPane resultsSplitPane = new javax.swing.JSplitPane();
424  javax.swing.JPanel instancesPanel = new javax.swing.JPanel();
425  javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane();
426  instancesList = new javax.swing.JList<>();
427  resultsViewerPanel = new javax.swing.JPanel();
428 
429  setPreferredSize(new java.awt.Dimension(777, 475));
430 
431  pagingPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
432 
433  previousPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
434  previousPageButton.setBorder(null);
435  previousPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
436  previousPageButton.setEnabled(false);
437  previousPageButton.setFocusable(false);
438  previousPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N
439  previousPageButton.addActionListener(new java.awt.event.ActionListener() {
440  public void actionPerformed(java.awt.event.ActionEvent evt) {
441  previousPageButtonActionPerformed(evt);
442  }
443  });
444 
445  org.openide.awt.Mnemonics.setLocalizedText(currentPageLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.currentPageLabel.text")); // NOI18N
446  currentPageLabel.setMaximumSize(new java.awt.Dimension(90, 23));
447  currentPageLabel.setMinimumSize(new java.awt.Dimension(90, 23));
448  currentPageLabel.setPreferredSize(new java.awt.Dimension(90, 23));
449 
450  nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
451  nextPageButton.setBorder(null);
452  nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
453  nextPageButton.setEnabled(false);
454  nextPageButton.setFocusable(false);
455  nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N
456  nextPageButton.addActionListener(new java.awt.event.ActionListener() {
457  public void actionPerformed(java.awt.event.ActionEvent evt) {
458  nextPageButtonActionPerformed(evt);
459  }
460  });
461 
462  org.openide.awt.Mnemonics.setLocalizedText(pageControlsLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.pageControlsLabel.text")); // NOI18N
463  pageControlsLabel.setMaximumSize(new java.awt.Dimension(33, 23));
464  pageControlsLabel.setMinimumSize(new java.awt.Dimension(33, 23));
465  pageControlsLabel.setPreferredSize(new java.awt.Dimension(33, 23));
466 
467  org.openide.awt.Mnemonics.setLocalizedText(gotoPageLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.gotoPageLabel.text")); // NOI18N
468  gotoPageLabel.setMaximumSize(new java.awt.Dimension(70, 23));
469  gotoPageLabel.setMinimumSize(new java.awt.Dimension(70, 23));
470  gotoPageLabel.setPreferredSize(new java.awt.Dimension(70, 23));
471 
472  gotoPageField.setEnabled(false);
473  gotoPageField.addActionListener(new java.awt.event.ActionListener() {
474  public void actionPerformed(java.awt.event.ActionEvent evt) {
475  gotoPageFieldActionPerformed(evt);
476  }
477  });
478 
479  org.openide.awt.Mnemonics.setLocalizedText(pageSizeLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.pageSizeLabel.text")); // NOI18N
480  pageSizeLabel.setMaximumSize(new java.awt.Dimension(60, 23));
481  pageSizeLabel.setMinimumSize(new java.awt.Dimension(60, 23));
482  pageSizeLabel.setPreferredSize(new java.awt.Dimension(60, 23));
483 
484  pageSizeComboBox.setModel(new DefaultComboBoxModel<Integer>(new Integer[] {25,50,75,100,125,150,175,200}));
485  pageSizeComboBox.setSelectedIndex(3);
486  pageSizeComboBox.addItemListener(new java.awt.event.ItemListener() {
487  public void itemStateChanged(java.awt.event.ItemEvent evt) {
488  pageSizeChanged(evt);
489  }
490  });
491 
492  javax.swing.GroupLayout pagingPanelLayout = new javax.swing.GroupLayout(pagingPanel);
493  pagingPanel.setLayout(pagingPanelLayout);
494  pagingPanelLayout.setHorizontalGroup(
495  pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
496  .addGroup(pagingPanelLayout.createSequentialGroup()
497  .addContainerGap()
498  .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
499  .addGap(18, 18, 18)
500  .addComponent(pageControlsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
501  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
502  .addComponent(previousPageButton)
503  .addGap(0, 0, 0)
504  .addComponent(nextPageButton)
505  .addGap(18, 18, 18)
506  .addComponent(gotoPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
507  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
508  .addComponent(gotoPageField, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
509  .addGap(18, 18, 18)
510  .addComponent(pageSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
511  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
512  .addComponent(pageSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
513  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
514  );
515  pagingPanelLayout.setVerticalGroup(
516  pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
517  .addGroup(pagingPanelLayout.createSequentialGroup()
518  .addGap(4, 4, 4)
519  .addGroup(pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
520  .addComponent(nextPageButton, javax.swing.GroupLayout.Alignment.TRAILING)
521  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
522  .addComponent(previousPageButton, javax.swing.GroupLayout.Alignment.TRAILING)
523  .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
524  .addComponent(pageControlsLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
525  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
526  .addComponent(gotoPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
527  .addComponent(gotoPageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
528  .addComponent(pageSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
529  .addComponent(pageSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
530  .addGap(4, 4, 4))
531  );
532 
533  resultsSplitPane.setDividerLocation(380);
534  resultsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
535  resultsSplitPane.setResizeWeight(1.0);
536  resultsSplitPane.setToolTipText(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.resultsSplitPane.toolTipText")); // NOI18N
537  resultsSplitPane.setLastDividerLocation(180);
538  resultsSplitPane.setOpaque(false);
539  resultsSplitPane.setPreferredSize(new java.awt.Dimension(777, 440));
540 
541  instancesPanel.setPreferredSize(new java.awt.Dimension(775, 68));
542 
543  instancesScrollPane.setPreferredSize(new java.awt.Dimension(775, 60));
544 
545  instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.instancesList.border.title"))); // NOI18N
546  instancesList.setModel(instancesListModel);
547  instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
548  instancesList.setCellRenderer(new InstancesCellRenderer());
549  instancesList.setVisibleRowCount(2);
550  instancesScrollPane.setViewportView(instancesList);
551 
552  javax.swing.GroupLayout instancesPanelLayout = new javax.swing.GroupLayout(instancesPanel);
553  instancesPanel.setLayout(instancesPanelLayout);
554  instancesPanelLayout.setHorizontalGroup(
555  instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
556  .addGap(0, 775, Short.MAX_VALUE)
557  .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
558  .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
559  );
560  instancesPanelLayout.setVerticalGroup(
561  instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
562  .addGap(0, 68, Short.MAX_VALUE)
563  .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
564  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup()
565  .addGap(0, 0, 0)
566  .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
567  );
568 
569  resultsSplitPane.setRightComponent(instancesPanel);
570 
571  resultsViewerPanel.setPreferredSize(new java.awt.Dimension(0, 380));
572  resultsViewerPanel.setLayout(new java.awt.BorderLayout());
573  resultsSplitPane.setLeftComponent(resultsViewerPanel);
574 
575  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
576  this.setLayout(layout);
577  layout.setHorizontalGroup(
578  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
579  .addComponent(pagingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
580  .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
581  );
582  layout.setVerticalGroup(
583  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
584  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
585  .addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
586  .addGap(0, 0, 0)
587  .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
588  .addGap(0, 0, 0))
589  );
590  }// </editor-fold>//GEN-END:initComponents
591 
597  private void previousPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previousPageButtonActionPerformed
598  if (currentPage > 0) {
599  disablePagingControls();
600  int previousPage = currentPage - 1;
601  int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
602  setPage(previousPage * pageSize);
603  }
604  }//GEN-LAST:event_previousPageButtonActionPerformed
605 
611  private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
612  disablePagingControls();
613  int nextPage = currentPage + 1;
614  int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
615  setPage(nextPage * pageSize);
616  }//GEN-LAST:event_nextPageButtonActionPerformed
617 
623  @Messages({"# {0} - selectedPage",
624  "# {1} - maxPage",
625  "ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value from 1 to {1}.",
626  "ResultsPanel.invalidPageNumber.title=Invalid Page Number"})
627  private void gotoPageFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoPageFieldActionPerformed
628  int newPage;
629  try {
630  newPage = Integer.parseInt(gotoPageField.getText());
631  } catch (NumberFormatException e) {
632  //ignore input
633  return;
634  }
635  int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
636  if ((newPage - 1) < 0 || groupSize <= ((newPage - 1) * pageSize)) {
637  JOptionPane.showMessageDialog(this,
638  Bundle.ResultsPanel_invalidPageNumber_message(newPage, Math.ceil((double) groupSize / pageSize)),
639  Bundle.ResultsPanel_invalidPageNumber_title(),
640  JOptionPane.WARNING_MESSAGE);
641  return;
642  }
643  disablePagingControls();
644  setPage((newPage - 1) * pageSize);
645  }//GEN-LAST:event_gotoPageFieldActionPerformed
646 
647  private void pageSizeChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_pageSizeChanged
648  if (evt.getStateChange() == ItemEvent.SELECTED) {
649  disablePagingControls();
650  int previousPage = currentPage - 1;
651  int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
652  if (previousPageSize != pageSize) {
653  previousPage = 0;
654  }
655  setPage(previousPage * pageSize);
656  }
657  }//GEN-LAST:event_pageSizeChanged
658 
662  private void disablePagingControls() {
663  nextPageButton.setEnabled(false);
664  previousPageButton.setEnabled(false);
665  gotoPageField.setEnabled(false);
666  pageSizeComboBox.setEnabled(false);
667  }
668 
669  // Variables declaration - do not modify//GEN-BEGIN:variables
670  private javax.swing.JLabel currentPageLabel;
671  private javax.swing.JTextField gotoPageField;
672  private javax.swing.JList<AbstractFile> instancesList;
673  private javax.swing.JButton nextPageButton;
674  private javax.swing.JComboBox<Integer> pageSizeComboBox;
675  private javax.swing.JButton previousPageButton;
676  private javax.swing.JPanel resultsViewerPanel;
677  // End of variables declaration//GEN-END:variables
678 
683  private class VideoThumbnailWorker extends SwingWorker<Void, Void> {
684 
685  private final VideoThumbnailsWrapper thumbnailWrapper;
686 
693  VideoThumbnailWorker(ResultFile file) {
694  thumbnailWrapper = new VideoThumbnailsWrapper(file);
695  videoThumbnailViewer.addVideo(thumbnailWrapper);
696  }
697 
698  @Override
699  protected Void doInBackground() throws Exception {
700  FileSearch.getVideoThumbnails(thumbnailWrapper);
701  return null;
702  }
703 
704  @Override
705  protected void done() {
706  try {
707  get();
708  } catch (InterruptedException | ExecutionException ex) {
709  logger.log(Level.WARNING, "Video Worker Exception for file: " + thumbnailWrapper.getResultFile().getFirstInstance().getId(), ex);
710  } catch (CancellationException ignored) {
711  //we want to do nothing in response to this since we allow it to be cancelled
712  }
713  videoThumbnailViewer.repaint();
714  }
715  }
716 
721  private class ImageThumbnailWorker extends SwingWorker<Void, Void> {
722 
724 
731  ImageThumbnailWorker(ResultFile file) {
732  thumbnailWrapper = new ImageThumbnailWrapper(file);
733  imageThumbnailViewer.addImage(thumbnailWrapper);
734  }
735 
736  @Override
737  protected Void doInBackground() throws Exception {
738  Image thumbnail = ImageUtils.getThumbnail(thumbnailWrapper.getResultFile().getFirstInstance(), ImageUtils.ICON_SIZE_LARGE);
739  if (thumbnail != null) {
740  thumbnailWrapper.setImageThumbnail(thumbnail);
741  }
742  return null;
743  }
744 
745  @Override
746  protected void done() {
747  try {
748  get();
749  } catch (InterruptedException | ExecutionException ex) {
750  logger.log(Level.WARNING, "Image Worker Exception for file: " + thumbnailWrapper.getResultFile().getFirstInstance().getId(), ex);
751  } catch (CancellationException ignored) {
752  //we want to do nothing in response to this since we allow it to be cancelled
753  }
754  imageThumbnailViewer.repaint();
755  }
756 
757  }
758 
763  private class DocumentPreviewWorker extends SwingWorker<Void, Void> {
764 
766 
773  DocumentPreviewWorker(ResultFile file) {
774  documentWrapper = new DocumentWrapper(file);
775  documentPreviewViewer.addDocument(documentWrapper);
776  }
777 
778  @Messages({"ResultsPanel.unableToCreate.text=Unable to create summary."})
779  @Override
780  protected Void doInBackground() throws Exception {
781  TextSummary preview = FileSearch.summarize(documentWrapper.getResultFile().getFirstInstance());
782  if (preview == null) {
783  preview = new TextSummary(Bundle.ResultsPanel_unableToCreate_text(), null, 0);
784  }
785  documentWrapper.setSummary(preview);
786  return null;
787  }
788 
789  @Messages({"ResultsPanel.documentPreview.text=Document preview creation cancelled."})
790  @Override
791  protected void done() {
792  try {
793  get();
794  } catch (InterruptedException | ExecutionException ex) {
795  documentWrapper.setSummary(new TextSummary(ex.getMessage(), null, 0));
796  logger.log(Level.WARNING, "Document Worker Exception", ex);
797  } catch (CancellationException ignored) {
798  documentWrapper.setSummary(new TextSummary(Bundle.ResultsPanel_documentPreview_text(), null, 0));
799  //we want to do nothing in response to this since we allow it to be cancelled
800  }
801  documentPreviewViewer.repaint();
802  }
803 
804  }
805 
809  private class InstancesCellRenderer extends DefaultListCellRenderer {
810 
811  private static final long serialVersionUID = 1L;
812 
813  @Override
814  public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
815  super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
816  String name = "";
817  if (value instanceof AbstractFile) {
818  AbstractFile file = (AbstractFile) value;
819  try {
820  name = file.getUniquePath();
821  } catch (TskCoreException ingored) {
822  name = file.getParentPath() + "/" + file.getName();
823  }
824 
825  }
826  setText(name);
827  return this;
828  }
829 
830  }
831 }
List< FileSearchFiltering.FileFilter > searchFilters
final List< SwingWorker< Void, Void > > resultContentWorkers
void gotoPageFieldActionPerformed(java.awt.event.ActionEvent evt)
final VideoThumbnailViewer videoThumbnailViewer
javax.swing.JComboBox< Integer > pageSizeComboBox
Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)
final DefaultListModel< AbstractFile > instancesListModel
final DocumentPreviewViewer documentPreviewViewer
javax.swing.JList< AbstractFile > instancesList
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)
void previousPageButtonActionPerformed(java.awt.event.ActionEvent evt)
void pageSizeChanged(java.awt.event.ItemEvent evt)
FileGroup.GroupSortingAlgorithm groupSort
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
final ImageThumbnailViewer imageThumbnailViewer
static BufferedImage getThumbnail(Content content, int iconSize)
synchronized void setPage(int startingEntry)

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.