Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.discovery.ui;
20
21import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
22import com.google.common.eventbus.Subscribe;
23import java.awt.Cursor;
24import java.awt.Image;
25import java.awt.event.ItemEvent;
26import java.util.ArrayList;
27import java.util.List;
28import java.util.concurrent.CancellationException;
29import java.util.concurrent.ExecutionException;
30import java.util.logging.Level;
31import javax.swing.DefaultComboBoxModel;
32import javax.swing.JOptionPane;
33import javax.swing.SwingUtilities;
34import javax.swing.SwingWorker;
35import org.openide.util.NbBundle.Messages;
36import org.sleuthkit.autopsy.casemodule.Case;
37import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
38import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
39import org.sleuthkit.autopsy.coreutils.ImageUtils;
40import org.sleuthkit.autopsy.coreutils.Logger;
41import org.sleuthkit.datamodel.AbstractFile;
42import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
43import org.sleuthkit.autopsy.coreutils.ThreadConfined;
44import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes;
45import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
46import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
47import org.sleuthkit.autopsy.discovery.search.DomainSearch;
48import org.sleuthkit.autopsy.discovery.search.DomainSearchThumbnailRequest;
49import org.sleuthkit.autopsy.discovery.search.Group;
50import org.sleuthkit.autopsy.discovery.search.FileSearch;
51import org.sleuthkit.autopsy.discovery.search.SearchData;
52import org.sleuthkit.autopsy.discovery.search.ResultsSorter;
53import org.sleuthkit.autopsy.discovery.search.Result;
54import org.sleuthkit.autopsy.discovery.search.ResultDomain;
55import org.sleuthkit.autopsy.discovery.search.ResultFile;
56import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.DOMAIN;
57import org.sleuthkit.autopsy.textsummarizer.TextSummary;
58import org.sleuthkit.datamodel.SleuthkitCase;
59
64final 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());
68 private final VideoThumbnailViewer videoThumbnailViewer;
69 private final ImageThumbnailViewer imageThumbnailViewer;
70 private final DocumentPreviewViewer documentPreviewViewer;
71 private final DomainSummaryViewer domainSummaryViewer;
72 private List<AbstractFilter> searchFilters;
73 private DiscoveryAttributes.AttributeType groupingAttribute;
74 private Group.GroupSortingAlgorithm groupSort;
75 private ResultsSorter.SortingMethod fileSortMethod;
76 private GroupKey selectedGroupKey;
77 private int currentPage = 0;
78 private int previousPageSize = 10;
79 private SearchData.Type resultType;
80 private int groupSize = 0;
81 private PageWorker pageWorker;
82 private final List<SwingWorker<Void, Void>> resultContentWorkers = new ArrayList<>();
83
87 @Messages({"ResultsPanel.viewFileInDir.name=View File in Directory",
88 "ResultsPanel.openInExternalViewer.name=Open in External Viewer"})
89 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
90 ResultsPanel() {
91 initComponents();
92 imageThumbnailViewer = new ImageThumbnailViewer();
93 videoThumbnailViewer = new VideoThumbnailViewer();
94 documentPreviewViewer = new DocumentPreviewViewer();
95 domainSummaryViewer = new DomainSummaryViewer();
96 videoThumbnailViewer.addListSelectionListener((e) -> {
97 if (resultType == SearchData.Type.VIDEO) {
98 if (!e.getValueIsAdjusting()) {
99 //send populateMesage
100 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
101 } else {
102 //send clearSelection message
103 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
104 }
105 }
106 });
107 imageThumbnailViewer.addListSelectionListener((e) -> {
108 if (resultType == SearchData.Type.IMAGE) {
109 if (!e.getValueIsAdjusting()) {
110 //send populateMesage
111 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
112 } else {
113 //send clearSelection message
114 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
115 }
116
117 }
118 });
119 documentPreviewViewer.addListSelectionListener((e) -> {
120 if (resultType == SearchData.Type.DOCUMENT) {
121 if (!e.getValueIsAdjusting()) {
122 //send populateMesage
123 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
124 } else {
125 //send clearSelection message
126 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
127 }
128 }
129 });
130 domainSummaryViewer.addListSelectionListener((e) -> {
131 if (resultType == SearchData.Type.DOMAIN && !e.getValueIsAdjusting()) {
132 domainSummaryViewer.sendPopulateEvent();
133 }
134 });
135 }
136
137 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
138 SearchData.Type getActiveType() {
139 return resultType;
140 }
141
149 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
150 private List<AbstractFile> getInstancesForSelected() {
151 if (null != resultType) {
152 switch (resultType) {
153 case VIDEO:
154 return videoThumbnailViewer.getInstancesForSelected();
155 case IMAGE:
156 return imageThumbnailViewer.getInstancesForSelected();
157 case DOCUMENT:
158 return documentPreviewViewer.getInstancesForSelected();
159 default:
160 break;
161 }
162 }
163 return new ArrayList<>();
164 }
165
171 @Subscribe
172 void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
173 SwingUtilities.invokeLater(() -> {
174 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
175 });
176 }
177
183 @Subscribe
184 void handlePageRetrievedEvent(DiscoveryEventUtils.PageRetrievedEvent pageRetrievedEvent) {
185 //send populateMesage
186 if (pageRetrievedEvent.getType() != DOMAIN) {
187 DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
188 }
189 currentPage = pageRetrievedEvent.getPageNumber();
190 SwingUtilities.invokeLater(() -> {
191 updateControls();
192 resetResultViewer();
193 if (null != pageRetrievedEvent.getType()) {
194 switch (pageRetrievedEvent.getType()) {
195 case IMAGE:
196 populateImageViewer(pageRetrievedEvent.getSearchResults());
197 resultsViewerPanel.add(imageThumbnailViewer);
198 break;
199 case VIDEO:
200 populateVideoViewer(pageRetrievedEvent.getSearchResults());
201 resultsViewerPanel.add(videoThumbnailViewer);
202 break;
203 case DOCUMENT:
204 populateDocumentViewer(pageRetrievedEvent.getSearchResults());
205 resultsViewerPanel.add(documentPreviewViewer);
206 break;
207 case DOMAIN:
208 populateDomainViewer(pageRetrievedEvent.getSearchResults());
209 resultsViewerPanel.add(domainSummaryViewer);
210 break;
211 default:
212 break;
213 }
214 }
215 resultsViewerPanel.revalidate();
216 resultsViewerPanel.repaint();
217 });
218 }
219
220 @Subscribe
221 void handleCancelBackgroundTasksEvent(DiscoveryEventUtils.CancelBackgroundTasksEvent cancelEvent) {
222 for (SwingWorker<Void, Void> thumbWorker : resultContentWorkers) {
223 if (!thumbWorker.isDone()) {
224 thumbWorker.cancel(true);
225 }
226 }
227 resultContentWorkers.clear();
228 }
229
234 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
235 void resetResultViewer() {
236 resultsViewerPanel.remove(imageThumbnailViewer);
237 resultsViewerPanel.remove(videoThumbnailViewer);
238 resultsViewerPanel.remove(documentPreviewViewer);
239 resultsViewerPanel.remove(domainSummaryViewer);
240 //cancel any unfished thumb workers
241 for (SwingWorker<Void, Void> thumbWorker : resultContentWorkers) {
242 if (!thumbWorker.isDone()) {
243 thumbWorker.cancel(true);
244 }
245 }
246 //clear old thumbnails
247 resultContentWorkers.clear();
248 videoThumbnailViewer.clearViewer();
249 imageThumbnailViewer.clearViewer();
250 documentPreviewViewer.clearViewer();
251 domainSummaryViewer.clearViewer();
252 }
253
260 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
261 void populateVideoViewer(List<Result> results) {
262 for (Result result : results) {
263 VideoThumbnailWorker thumbWorker = new VideoThumbnailWorker((ResultFile) result);
264 thumbWorker.execute();
265 //keep track of thumb worker for possible cancelation
266 resultContentWorkers.add(thumbWorker);
267 }
268 }
269
276 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
277 void populateImageViewer(List<Result> results) {
278 for (Result result : results) {
279 ImageThumbnailWorker thumbWorker = new ImageThumbnailWorker((ResultFile) result);
280 thumbWorker.execute();
281 //keep track of thumb worker for possible cancelation
282 resultContentWorkers.add(thumbWorker);
283 }
284 }
285
293 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
294 void populateDocumentViewer(List<Result> results) {
295 for (Result result : results) {
296 DocumentPreviewWorker documentWorker = new DocumentPreviewWorker((ResultFile) result);
297 documentWorker.execute();
298 //keep track of thumb worker for possible cancelation
299 resultContentWorkers.add(documentWorker);
300 }
301 }
302
310 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
311 void populateDomainViewer(List<Result> results) {
312 SleuthkitCase currentCase;
313 try {
314 currentCase = Case.getCurrentCaseThrows().getSleuthkitCase();
315 } catch (NoCurrentCaseException ex) {
316 // Do nothing, case has been closed.
317 return;
318 }
319
320 for (Result result : results) {
322 currentCase, (ResultDomain) result);
323 domainWorker.execute();
324 //keep track of thumb worker for possible cancelation
325 resultContentWorkers.add(domainWorker);
326 }
327 }
328
334 @Subscribe
335 void handleGroupSelectedEvent(DiscoveryEventUtils.GroupSelectedEvent groupSelectedEvent) {
336 searchFilters = groupSelectedEvent.getFilters();
337 groupingAttribute = groupSelectedEvent.getGroupingAttr();
338 groupSort = groupSelectedEvent.getGroupSort();
339 fileSortMethod = groupSelectedEvent.getResultSort();
340 selectedGroupKey = groupSelectedEvent.getGroupKey();
341 resultType = groupSelectedEvent.getResultType();
342 groupSize = groupSelectedEvent.getGroupSize();
343 SwingUtilities.invokeLater(() -> {
344 resetResultViewer();
345 setPage(0);
346 });
347 }
348
355 @Subscribe
356 void handleNoResultsEvent(DiscoveryEventUtils.NoResultsEvent noResultsEvent) {
357 groupSize = 0;
358 currentPage = 0;
359 SwingUtilities.invokeLater(() -> {
360 updateControls();
361 videoThumbnailViewer.clearViewer();
362 imageThumbnailViewer.clearViewer();
363 documentPreviewViewer.clearViewer();
364 domainSummaryViewer.clearViewer();
365 resultsViewerPanel.revalidate();
366 resultsViewerPanel.repaint();
367 });
368 }
369
375 @Subscribe
376 void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
377 SwingUtilities.invokeLater(() -> {
378 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
379 });
380 }
381
388 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
389 private void setPage(int startingEntry) {
390 int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
391 if (pageWorker != null && !pageWorker.isDone()) {
392 pageWorker.cancel(true);
393 }
394 CentralRepository centralRepo = null;
395 if (CentralRepository.isEnabled()) {
396 try {
397 centralRepo = CentralRepository.getInstance();
398 } catch (CentralRepoException ex) {
399 centralRepo = null;
400 logger.log(Level.SEVERE, "Error loading central repository database, no central repository options will be available for Discovery", ex);
401 }
402 }
403 if (groupSize != 0) {
404 pageWorker = new PageWorker(searchFilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupKey, startingEntry, pageSize, resultType, centralRepo);
405 pageWorker.execute();
406 } else {
407 pageSizeComboBox.setEnabled(true);
408 }
409 }
410
415 @Messages({"# {0} - currentPage",
416 "# {1} - totalPages",
417 "ResultsPanel.currentPage.displayValue=Page: {0} of {1}"})
418 private void updateControls() {
419 previousPageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
420 int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
421 //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
422 double maxPageDouble = groupSize == 0 ? 1 : Math.ceil((double) groupSize / pageSize);
423 currentPageLabel.setText(Bundle.ResultsPanel_currentPage_displayValue(currentPage + 1, maxPageDouble));
424 previousPageButton.setEnabled(currentPage != 0);
425 nextPageButton.setEnabled(groupSize > ((currentPage + 1) * pageSize));
426 gotoPageField.setEnabled(groupSize > pageSize);
427 pageSizeComboBox.setEnabled(true);
428 }
429
435 @SuppressWarnings("unchecked")
436 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
437 private void initComponents() {
438 java.awt.GridBagConstraints gridBagConstraints;
439
440 javax.swing.JPanel pagingPanel = new javax.swing.JPanel();
441 previousPageButton = new javax.swing.JButton();
442 currentPageLabel = new javax.swing.JLabel();
443 nextPageButton = new javax.swing.JButton();
444 javax.swing.JLabel pageControlsLabel = new javax.swing.JLabel();
445 javax.swing.JLabel gotoPageLabel = new javax.swing.JLabel();
446 gotoPageField = new javax.swing.JTextField();
447 javax.swing.JLabel pageSizeLabel = new javax.swing.JLabel();
448 pageSizeComboBox = new javax.swing.JComboBox<>();
449 javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
450 javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
451 javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
452 javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
453 resultsViewerPanel = new javax.swing.JPanel();
454
455 setMinimumSize(new java.awt.Dimension(300, 60));
456 setPreferredSize(new java.awt.Dimension(700, 700));
457 setLayout(new java.awt.BorderLayout());
458
459 pagingPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
460 pagingPanel.setMinimumSize(new java.awt.Dimension(400, 39));
461 pagingPanel.setPreferredSize(new java.awt.Dimension(700, 39));
462 pagingPanel.setLayout(new java.awt.GridBagLayout());
463
464 previousPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
465 previousPageButton.setBorder(null);
466 previousPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
467 previousPageButton.setEnabled(false);
468 previousPageButton.setFocusable(false);
469 previousPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N
470 previousPageButton.addActionListener(new java.awt.event.ActionListener() {
471 public void actionPerformed(java.awt.event.ActionEvent evt) {
472 previousPageButtonActionPerformed(evt);
473 }
474 });
475 gridBagConstraints = new java.awt.GridBagConstraints();
476 gridBagConstraints.gridx = 3;
477 gridBagConstraints.gridy = 0;
478 gridBagConstraints.gridheight = 2;
479 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
480 gridBagConstraints.insets = new java.awt.Insets(6, 12, 6, 0);
481 pagingPanel.add(previousPageButton, gridBagConstraints);
482
483 org.openide.awt.Mnemonics.setLocalizedText(currentPageLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.currentPageLabel.text")); // NOI18N
484 currentPageLabel.setMaximumSize(new java.awt.Dimension(190, 23));
485 currentPageLabel.setMinimumSize(new java.awt.Dimension(90, 23));
486 currentPageLabel.setPreferredSize(new java.awt.Dimension(100, 23));
487 gridBagConstraints = new java.awt.GridBagConstraints();
488 gridBagConstraints.gridx = 0;
489 gridBagConstraints.gridy = 0;
490 gridBagConstraints.gridheight = 2;
491 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
492 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
493 gridBagConstraints.insets = new java.awt.Insets(6, 14, 6, 0);
494 pagingPanel.add(currentPageLabel, gridBagConstraints);
495
496 nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
497 nextPageButton.setBorder(null);
498 nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
499 nextPageButton.setEnabled(false);
500 nextPageButton.setFocusable(false);
501 nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N
502 nextPageButton.addActionListener(new java.awt.event.ActionListener() {
503 public void actionPerformed(java.awt.event.ActionEvent evt) {
504 nextPageButtonActionPerformed(evt);
505 }
506 });
507 gridBagConstraints = new java.awt.GridBagConstraints();
508 gridBagConstraints.gridx = 4;
509 gridBagConstraints.gridy = 0;
510 gridBagConstraints.gridheight = 2;
511 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
512 gridBagConstraints.insets = new java.awt.Insets(6, 0, 6, 0);
513 pagingPanel.add(nextPageButton, gridBagConstraints);
514
515 pageControlsLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
516 org.openide.awt.Mnemonics.setLocalizedText(pageControlsLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.pageControlsLabel.text")); // NOI18N
517 pageControlsLabel.setMaximumSize(new java.awt.Dimension(133, 23));
518 pageControlsLabel.setMinimumSize(new java.awt.Dimension(33, 23));
519 pageControlsLabel.setPreferredSize(new java.awt.Dimension(60, 23));
520 gridBagConstraints = new java.awt.GridBagConstraints();
521 gridBagConstraints.gridx = 2;
522 gridBagConstraints.gridy = 0;
523 gridBagConstraints.gridheight = 2;
524 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
525 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
526 gridBagConstraints.insets = new java.awt.Insets(6, 18, 6, 0);
527 pagingPanel.add(pageControlsLabel, gridBagConstraints);
528
529 gotoPageLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
530 org.openide.awt.Mnemonics.setLocalizedText(gotoPageLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.gotoPageLabel.text")); // NOI18N
531 gotoPageLabel.setMaximumSize(new java.awt.Dimension(170, 23));
532 gotoPageLabel.setMinimumSize(new java.awt.Dimension(70, 23));
533 gotoPageLabel.setPreferredSize(new java.awt.Dimension(100, 23));
534 gridBagConstraints = new java.awt.GridBagConstraints();
535 gridBagConstraints.gridx = 6;
536 gridBagConstraints.gridy = 0;
537 gridBagConstraints.gridheight = 2;
538 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
539 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
540 gridBagConstraints.insets = new java.awt.Insets(6, 18, 6, 0);
541 pagingPanel.add(gotoPageLabel, gridBagConstraints);
542
543 gotoPageField.setEnabled(false);
544 gotoPageField.setMinimumSize(new java.awt.Dimension(30, 22));
545 gotoPageField.setName(""); // NOI18N
546 gotoPageField.setPreferredSize(new java.awt.Dimension(26, 22));
547 gotoPageField.addActionListener(new java.awt.event.ActionListener() {
548 public void actionPerformed(java.awt.event.ActionEvent evt) {
549 gotoPageFieldActionPerformed(evt);
550 }
551 });
552 gridBagConstraints = new java.awt.GridBagConstraints();
553 gridBagConstraints.gridx = 7;
554 gridBagConstraints.gridy = 0;
555 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
556 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
557 gridBagConstraints.insets = new java.awt.Insets(6, 5, 0, 0);
558 pagingPanel.add(gotoPageField, gridBagConstraints);
559
560 pageSizeLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
561 org.openide.awt.Mnemonics.setLocalizedText(pageSizeLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.pageSizeLabel.text")); // NOI18N
562 pageSizeLabel.setMaximumSize(new java.awt.Dimension(160, 23));
563 pageSizeLabel.setMinimumSize(new java.awt.Dimension(60, 23));
564 pageSizeLabel.setPreferredSize(new java.awt.Dimension(90, 23));
565 gridBagConstraints = new java.awt.GridBagConstraints();
566 gridBagConstraints.gridx = 9;
567 gridBagConstraints.gridy = 0;
568 gridBagConstraints.gridheight = 2;
569 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
570 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
571 gridBagConstraints.insets = new java.awt.Insets(6, 18, 6, 0);
572 pagingPanel.add(pageSizeLabel, gridBagConstraints);
573
574 pageSizeComboBox.setModel(new DefaultComboBoxModel<Integer>(new Integer[] {25,50,75,100,125,150,175,200}));
575 pageSizeComboBox.setSelectedIndex(3);
576 pageSizeComboBox.addItemListener(new java.awt.event.ItemListener() {
577 public void itemStateChanged(java.awt.event.ItemEvent evt) {
578 pageSizeChanged(evt);
579 }
580 });
581 gridBagConstraints = new java.awt.GridBagConstraints();
582 gridBagConstraints.gridx = 10;
583 gridBagConstraints.gridy = 0;
584 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
585 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
586 gridBagConstraints.insets = new java.awt.Insets(6, 5, 0, 277);
587 pagingPanel.add(pageSizeComboBox, gridBagConstraints);
588 gridBagConstraints = new java.awt.GridBagConstraints();
589 gridBagConstraints.gridx = 11;
590 gridBagConstraints.gridy = 0;
591 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
592 gridBagConstraints.weightx = 0.1;
593 pagingPanel.add(filler1, gridBagConstraints);
594 gridBagConstraints = new java.awt.GridBagConstraints();
595 gridBagConstraints.gridx = 1;
596 gridBagConstraints.gridy = 0;
597 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
598 pagingPanel.add(filler2, gridBagConstraints);
599 gridBagConstraints = new java.awt.GridBagConstraints();
600 gridBagConstraints.gridx = 5;
601 gridBagConstraints.gridy = 0;
602 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
603 pagingPanel.add(filler3, gridBagConstraints);
604 gridBagConstraints = new java.awt.GridBagConstraints();
605 gridBagConstraints.gridx = 8;
606 gridBagConstraints.gridy = 0;
607 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
608 pagingPanel.add(filler4, gridBagConstraints);
609
610 add(pagingPanel, java.awt.BorderLayout.PAGE_START);
611
612 resultsViewerPanel.setMinimumSize(new java.awt.Dimension(0, 60));
613 resultsViewerPanel.setPreferredSize(new java.awt.Dimension(700, 700));
614 resultsViewerPanel.setLayout(new java.awt.BorderLayout());
615 add(resultsViewerPanel, java.awt.BorderLayout.CENTER);
616 }// </editor-fold>//GEN-END:initComponents
617
623 private void previousPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previousPageButtonActionPerformed
624 if (currentPage > 0) {
625 disablePagingControls();
626 int previousPage = currentPage - 1;
627 int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
628 setPage(previousPage * pageSize);
629 }
630 }//GEN-LAST:event_previousPageButtonActionPerformed
631
637 private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
638 disablePagingControls();
639 int nextPage = currentPage + 1;
640 int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
641 setPage(nextPage * pageSize);
642 }//GEN-LAST:event_nextPageButtonActionPerformed
643
649 @Messages({"# {0} - selectedPage",
650 "# {1} - maxPage",
651 "ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value from 1 to {1}.",
652 "ResultsPanel.invalidPageNumber.title=Invalid Page Number"})
653 private void gotoPageFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoPageFieldActionPerformed
654 int newPage;
655 try {
656 newPage = Integer.parseInt(gotoPageField.getText());
657 } catch (NumberFormatException e) {
658 //ignore input
659 return;
660 }
661 int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
662 if ((newPage - 1) < 0 || groupSize <= ((newPage - 1) * pageSize)) {
663 JOptionPane.showMessageDialog(this,
664 Bundle.ResultsPanel_invalidPageNumber_message(newPage, Math.ceil((double) groupSize / pageSize)),
665 Bundle.ResultsPanel_invalidPageNumber_title(),
666 JOptionPane.WARNING_MESSAGE);
667 return;
668 }
669 disablePagingControls();
670 setPage((newPage - 1) * pageSize);
671 }//GEN-LAST:event_gotoPageFieldActionPerformed
672
673 private void pageSizeChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_pageSizeChanged
674 if (evt.getStateChange() == ItemEvent.SELECTED) {
675 disablePagingControls();
676 int previousPage = currentPage - 1;
677 int pageSize = pageSizeComboBox.getItemAt(pageSizeComboBox.getSelectedIndex());
678 if (previousPageSize != pageSize) {
679 previousPage = 0;
680 }
681 setPage(previousPage * pageSize);
682 }
683 }//GEN-LAST:event_pageSizeChanged
684
688 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
689 private void disablePagingControls() {
690 nextPageButton.setEnabled(false);
691 previousPageButton.setEnabled(false);
692 gotoPageField.setEnabled(false);
693 pageSizeComboBox.setEnabled(false);
694 }
695
696 // Variables declaration - do not modify//GEN-BEGIN:variables
697 private javax.swing.JLabel currentPageLabel;
698 private javax.swing.JTextField gotoPageField;
699 private javax.swing.JButton nextPageButton;
700 private javax.swing.JComboBox<Integer> pageSizeComboBox;
701 private javax.swing.JButton previousPageButton;
702 private javax.swing.JPanel resultsViewerPanel;
703 // End of variables declaration//GEN-END:variables
704
709 private class VideoThumbnailWorker extends SwingWorker<Void, Void> {
710
711 private final VideoThumbnailsWrapper thumbnailWrapper;
712
720 VideoThumbnailWorker(ResultFile file) {
721 thumbnailWrapper = new VideoThumbnailsWrapper(file);
722 videoThumbnailViewer.addVideo(thumbnailWrapper);
723 }
724
725 @Override
726 protected Void doInBackground() throws Exception {
727 DiscoveryUiUtils.getVideoThumbnails(thumbnailWrapper);
728 return null;
729 }
730
731 @Override
732 protected void done() {
733 try {
734 get();
735 } catch (InterruptedException | ExecutionException ex) {
736 logger.log(Level.WARNING, "Video Worker Exception for file: " + thumbnailWrapper.getResultFile().getFirstInstance().getId(), ex);
737 } catch (CancellationException ignored) {
738 //we want to do nothing in response to this since we allow it to be cancelled
739 }
740 videoThumbnailViewer.repaint();
741 }
742 }
743
748 private class ImageThumbnailWorker extends SwingWorker<Void, Void> {
749
750 private final ImageThumbnailWrapper thumbnailWrapper;
751
759 ImageThumbnailWorker(ResultFile file) {
760 thumbnailWrapper = new ImageThumbnailWrapper(file);
761 imageThumbnailViewer.addImage(thumbnailWrapper);
762 }
763
764 @Override
765 protected Void doInBackground() throws Exception {
766 Image thumbnail = ImageUtils.getThumbnail(thumbnailWrapper.getResultFile().getFirstInstance(), ImageUtils.ICON_SIZE_LARGE);
767 if (thumbnail != null) {
768 thumbnailWrapper.setImageThumbnail(thumbnail);
769 }
770 return null;
771 }
772
773 @Override
774 protected void done() {
775 try {
776 get();
777 } catch (InterruptedException | ExecutionException ex) {
778 logger.log(Level.WARNING, "Image Worker Exception for file: " + thumbnailWrapper.getResultFile().getFirstInstance().getId(), ex);
779 } catch (CancellationException ignored) {
780 //we want to do nothing in response to this since we allow it to be cancelled
781 }
782 imageThumbnailViewer.repaint();
783 }
784
785 }
786
791 private class DocumentPreviewWorker extends SwingWorker<Void, Void> {
792
793 private final DocumentWrapper documentWrapper;
794
802 DocumentPreviewWorker(ResultFile file) {
803 documentWrapper = new DocumentWrapper(file);
804 documentPreviewViewer.addDocument(documentWrapper);
805 }
806
807 @Messages({"ResultsPanel.unableToCreate.text=Unable to create summary."})
808 @Override
809 protected Void doInBackground() throws Exception {
810 TextSummary preview = FileSearch.summarize(documentWrapper.getResultFile().getFirstInstance());
811 if (preview == null) {
812 preview = new TextSummary(Bundle.ResultsPanel_unableToCreate_text(), null, 0);
813 }
814 documentWrapper.setSummary(preview);
815 return null;
816 }
817
818 @Messages({"ResultsPanel.documentPreview.text=Document preview creation cancelled."})
819 @Override
820 protected void done() {
821 try {
822 get();
823 } catch (InterruptedException | ExecutionException ex) {
824 documentWrapper.setSummary(new TextSummary(ex.getMessage(), null, 0));
825 logger.log(Level.WARNING, "Document Worker Exception", ex);
826 } catch (CancellationException ignored) {
827 documentWrapper.setSummary(new TextSummary(Bundle.ResultsPanel_documentPreview_text(), null, 0));
828 //we want to do nothing in response to this since we allow it to be cancelled
829 }
830 documentPreviewViewer.repaint();
831 }
832
833 }
834
839 private class DomainThumbnailWorker extends SwingWorker<Void, Void> {
840
842 private final SleuthkitCase caseDb;
843
851 DomainThumbnailWorker(SleuthkitCase caseDb, ResultDomain domain) {
852 this.caseDb = caseDb;
853 domainWrapper = new DomainWrapper(domain);
854 domainSummaryViewer.addDomain(domainWrapper);
855 }
856
857 @Override
858 protected Void doInBackground() throws Exception {
859 DomainSearch domainSearch = new DomainSearch();
861 caseDb,
862 domainWrapper.getResultDomain().getDomain(),
864 );
865
866 Image thumbnail = domainSearch.getThumbnail(request);
867 domainWrapper.setThumbnail(thumbnail);
868 return null;
869 }
870
871 @Override
872 protected void done() {
873 try {
874 get();
875 } catch (ExecutionException ex) {
876 domainWrapper.setThumbnail(null);
877 logger.log(Level.WARNING, "Fatal error getting thumbnail for domain.", ex);
878 } catch (InterruptedException | CancellationException ignored) {
879 domainWrapper.setThumbnail(null);
880 //we want to do nothing in response to this since we allow it to be cancelled
881 }
882 domainSummaryViewer.repaint();
883 }
884
885 }
886}
static BufferedImage getThumbnail(Content content, int iconSize)
Image getThumbnail(DomainSearchThumbnailRequest thumbnailRequest)
static TextSummary summarize(AbstractFile file)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.