19package org.sleuthkit.autopsy.discovery.ui;
21import com.google.common.eventbus.Subscribe;
22import java.awt.Component;
23import java.awt.event.MouseAdapter;
24import java.awt.event.MouseEvent;
25import java.util.HashSet;
28import javax.swing.DefaultListCellRenderer;
29import javax.swing.DefaultListModel;
30import javax.swing.JList;
31import javax.swing.JPopupMenu;
32import javax.swing.SwingUtilities;
33import javax.swing.event.ListSelectionEvent;
34import javax.swing.event.ListSelectionListener;
35import org.sleuthkit.autopsy.actions.AddContentTagAction;
36import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
37import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
38import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
39import org.sleuthkit.autopsy.coreutils.ThreadConfined;
40import org.sleuthkit.autopsy.datamodel.FileNode;
41import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
42import org.sleuthkit.autopsy.directorytree.ViewContextAction;
43import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
44import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction;
45import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
46import org.sleuthkit.datamodel.AbstractFile;
47import org.sleuthkit.datamodel.TskCoreException;
52final class FileDetailsPanel
extends javax.swing.JPanel {
54 private static final long serialVersionUID = 1L;
56 private final DataContentPanel dataContentPanel;
57 private final DefaultListModel<AbstractFile> instancesListModel =
new DefaultListModel<>();
58 private final ListSelectionListener listener;
63 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
66 dataContentPanel = DataContentPanel.createInstance();
67 detailsSplitPane.setBottomComponent(dataContentPanel);
69 instancesList.addMouseListener(
new MouseAdapter() {
71 public void mousePressed(MouseEvent e) {
72 if (SwingUtilities.isRightMouseButton(e)) {
73 instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint()));
74 Set<AbstractFile> files =
new HashSet<>();
75 files.add(instancesList.getSelectedValue());
76 JPopupMenu menu =
new JPopupMenu();
77 menu.add(
new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue()));
78 menu.add(
new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(),
new FileNode(instancesList.getSelectedValue())));
79 menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue()));
80 menu.add(
new DiscoveryExtractAction(files));
81 menu.add(AddContentTagAction.getInstance().getMenuForContent(files));
82 menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files));
83 menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files));
84 menu.show(instancesList, e.getPoint().x, e.getPoint().y);
88 listener =
new ListSelectionListener() {
90 public void valueChanged(ListSelectionEvent e) {
91 if (!e.getValueIsAdjusting()) {
92 AbstractFile file = getSelectedFile();
94 dataContentPanel.setNode(
new TableFilterNode(
new FileNode(file),
false));
96 dataContentPanel.setNode(
null);
101 instancesList.addListSelectionListener(listener);
112 void handleClearSelectionListener(DiscoveryEventUtils.ClearInstanceSelectionEvent clearEvent) {
113 SwingUtilities.invokeLater(() -> {
114 instancesList.clearSelection();
125 void handlePopulateInstancesListEvent(DiscoveryEventUtils.PopulateInstancesListEvent populateEvent) {
126 List<AbstractFile> files = populateEvent.getInstances();
127 SwingUtilities.invokeLater(() -> {
128 if (files.isEmpty()) {
130 instancesListModel.removeAllElements();
132 DiscoveryEventUtils.getDiscoveryEventBus().post(
new DiscoveryEventUtils.DetailsVisibleEvent(
false));
135 instancesList.removeListSelectionListener(listener);
136 instancesListModel.removeAllElements();
137 for (AbstractFile file : files) {
138 instancesListModel.addElement(file);
141 instancesList.addListSelectionListener(listener);
142 if (!instancesListModel.isEmpty()) {
143 instancesList.setSelectedIndex(0);
146 DiscoveryEventUtils.getDiscoveryEventBus().post(
new DiscoveryEventUtils.DetailsVisibleEvent(
true));
157 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
158 AbstractFile getSelectedFile() {
159 if (instancesList.getSelectedIndex() == -1) {
162 return instancesListModel.getElementAt(instancesList.getSelectedIndex());
171 @SuppressWarnings(
"unchecked")
173 private
void initComponents() {
175 detailsSplitPane =
new javax.swing.JSplitPane();
176 javax.swing.JPanel instancesPanel =
new javax.swing.JPanel();
177 javax.swing.JScrollPane instancesScrollPane =
new javax.swing.JScrollPane();
178 instancesList =
new javax.swing.JList<>();
180 detailsSplitPane.setDividerLocation(80);
181 detailsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
182 detailsSplitPane.setMinimumSize(
new java.awt.Dimension(200, 0));
183 detailsSplitPane.setPreferredSize(
new java.awt.Dimension(700, 500));
185 instancesPanel.setMinimumSize(
new java.awt.Dimension(0, 60));
186 instancesPanel.setPreferredSize(
new java.awt.Dimension(700, 80));
188 instancesScrollPane.setPreferredSize(
new java.awt.Dimension(775, 60));
190 instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FileDetailsPanel.class,
"FileDetailsPanel.instancesList.border.title")));
191 instancesList.setModel(instancesListModel);
192 instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
194 instancesList.setVisibleRowCount(2);
195 instancesScrollPane.setViewportView(instancesList);
197 javax.swing.GroupLayout instancesPanelLayout =
new javax.swing.GroupLayout(instancesPanel);
198 instancesPanel.setLayout(instancesPanelLayout);
199 instancesPanelLayout.setHorizontalGroup(
200 instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
201 .addGap(0, 775, Short.MAX_VALUE)
202 .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
203 .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
205 instancesPanelLayout.setVerticalGroup(
206 instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
207 .addGap(0, 79, Short.MAX_VALUE)
208 .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
209 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup()
211 .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)))
214 detailsSplitPane.setTopComponent(instancesPanel);
216 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
217 this.setLayout(layout);
218 layout.setHorizontalGroup(
219 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
220 .addGap(0, 777, Short.MAX_VALUE)
221 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
222 .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
224 layout.setVerticalGroup(
225 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
226 .addGap(0, 402, Short.MAX_VALUE)
227 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
228 .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
234 private javax.swing.JSplitPane detailsSplitPane;
235 private javax.swing.JList<AbstractFile> instancesList;
248 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
250 if (value instanceof AbstractFile) {
251 AbstractFile file = (AbstractFile) value;
253 name = file.getUniquePath();
254 }
catch (TskCoreException ingored) {
255 name = file.getParentPath() +
"/" + file.getName();
static final long serialVersionUID
Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)