Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
OpenRecentCasePanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2019 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.casemodule;
20 
21 import java.awt.event.ActionListener;
22 import java.awt.event.KeyEvent;
23 import java.io.File;
24 import java.util.logging.Level;
25 import javax.swing.JOptionPane;
26 import javax.swing.JTable;
27 import javax.swing.ListSelectionModel;
28 import javax.swing.SwingUtilities;
29 import javax.swing.event.ListSelectionEvent;
30 import javax.swing.event.ListSelectionListener;
31 import javax.swing.table.AbstractTableModel;
32 import org.openide.util.NbBundle;
33 import org.openide.windows.WindowManager;
34 import static org.sleuthkit.autopsy.casemodule.Bundle.*;
37 
41 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
42 class OpenRecentCasePanel extends javax.swing.JPanel {
43 
44  private static final long serialVersionUID = 1L;
45  private static final Logger logger = Logger.getLogger(OpenRecentCasePanel.class.getName());
46  private static OpenRecentCasePanel instance;
47  private static String[] caseNames;
48  private static String[] casePaths;
49  private RecentCasesTableModel model;
50 
55  private OpenRecentCasePanel() {
56  initComponents();
57  imagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
58  imagesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
59  @Override
60  public void valueChanged(ListSelectionEvent e) {
61  //enable the ok button when something is selected
62  if (!e.getValueIsAdjusting()){
63  openButton.setEnabled(imagesTable.getSelectedRowCount() > 0);
64  }
65  }
66  });
67  }
68 
69  /*
70  * Gets the singleton instance of the panel used by the the open recent case
71  * option of the start window.
72  */
73  static OpenRecentCasePanel getInstance() {
74  if (instance == null) {
75  instance = new OpenRecentCasePanel();
76  }
77  instance.refreshRecentCasesTable();
78  return instance;
79  }
80 
86  void setCloseButtonActionListener(ActionListener listener) {
87  this.cancelButton.addActionListener(listener);
88  }
89 
93  private void refreshRecentCasesTable() {
94  caseNames = RecentCases.getInstance().getRecentCaseNames();
95  casePaths = RecentCases.getInstance().getRecentCasePaths();
96  model = new RecentCasesTableModel();
97  imagesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
98  imagesTable.setModel(model);
99 
100  int width = tableScrollPane.getPreferredSize().width;
101  imagesTable.getColumnModel().getColumn(0).setPreferredWidth((int) (.30 * width));
102  imagesTable.getColumnModel().getColumn(1).setPreferredWidth((int) (.70 * width));
103  // If there are any images, let's select the first one
104  if (imagesTable.getRowCount() > 0) {
105  imagesTable.setRowSelectionInterval(0, 0);
106  }
107  }
108 
112  @NbBundle.Messages({"# {0} - case name",
113  "RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists.",
114  "CaseOpenAction.msgDlg.cantOpenCase.title=Error Opening Case"})
115  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
116  private void openCase() {
117  if (casePaths.length < 1) {
118  return;
119  }
120  final String caseMetadataFilePath = casePaths[imagesTable.getSelectedRow()];
121  final String caseName = caseNames[imagesTable.getSelectedRow()];
122  if (!caseMetadataFilePath.isEmpty()) {
123  try {
124  StartupWindowProvider.getInstance().close();
125  CueBannerPanel.closeOpenRecentCasesWindow();
126  } catch (Exception ex) {
127  logger.log(Level.SEVERE, "Error closing start up window", ex); //NON-NLS
128  }
129 
130  // try to open the case.
131  if (caseName.isEmpty() || caseMetadataFilePath.isEmpty() || (!new File(caseMetadataFilePath).exists())) {
132  //case doesn't exist
133  JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
134  RecentItems_openRecentCase_msgDlg_text(caseName),
135  CaseOpenAction_msgDlg_cantOpenCase_title(),
136  JOptionPane.ERROR_MESSAGE);
137  RecentCases.getInstance().removeRecentCase(caseName, caseMetadataFilePath); // remove the recent case if it doesn't exist anymore
138  StartupWindowProvider.getInstance().open();
139  } else {
140  //do actual opening on another thread
141  new Thread(() -> {
142  try {
143  Case.openAsCurrentCase(caseMetadataFilePath);
144  } catch (CaseActionException ex) {
145  SwingUtilities.invokeLater(() -> {
146  if (!(ex instanceof CaseActionCancelledException)) {
147  logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
148 
149  JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
150  ex.getLocalizedMessage(),
151  CaseOpenAction_msgDlg_cantOpenCase_title(), //NON-NLS
152  JOptionPane.ERROR_MESSAGE);
153  }
154  StartupWindowProvider.getInstance().open();
155  });
156  }
157  }).start();
158  }
159  }
160  }
161 
165  private class RecentCasesTableModel extends AbstractTableModel {
166 
167  private static final long serialVersionUID = 1L;
168 
169  @Override
170  public int getRowCount() {
171  int count = 0;
172  for (String s : caseNames) {
173  if (!s.isEmpty()) {
174  count++;
175  }
176  }
177  return count;
178  }
179 
180  @Override
181  public int getColumnCount() {
182  return 2;
183  }
184 
185  @Override
186  public String getColumnName(int column) {
187  String colName = null;
188  switch (column) {
189  case 0:
190  colName = NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.colName.caseName");
191  break;
192  case 1:
193  colName = NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.colName.path");
194  break;
195  default:
196  break;
197  }
198  return colName;
199  }
200 
201  @Override
202  public Object getValueAt(int rowIndex, int columnIndex) {
203  Object ret = null;
204  switch (columnIndex) {
205  case 0:
206  ret = caseNames[rowIndex];
207  break;
208  case 1:
209  ret = shortenPath(casePaths[rowIndex]);
210  break;
211  default:
212  logger.log(Level.SEVERE, "Invalid table column index: {0}", columnIndex); //NON-NLS
213  break;
214  }
215  return ret;
216  }
217 
218  @Override
219  public boolean isCellEditable(int rowIndex, int columnIndex) {
220  return false;
221  }
222 
223  @Override
224  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
225  }
226 
234  private String shortenPath(String path) {
235  String shortenedPath = path;
236  if (shortenedPath.length() > 50) {
237  shortenedPath = path.substring(0, 10 + path.substring(10).indexOf(File.separator) + 1) + "..."
238  + path.substring((path.length() - 20) + path.substring(path.length() - 20).indexOf(File.separator));
239  }
240  return shortenedPath;
241  }
242  }
243 
249  @SuppressWarnings("unchecked")
250  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
251  private void initComponents() {
252 
253  jLabel1 = new javax.swing.JLabel();
254  cancelButton = new javax.swing.JButton();
255  openButton = new javax.swing.JButton();
256  tableScrollPane = new javax.swing.JScrollPane();
257  imagesTable = new javax.swing.JTable();
258 
259  jLabel1.setText(org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.jLabel1.text")); // NOI18N
260 
261  cancelButton.setText(org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.cancelButton.text")); // NOI18N
262 
263  openButton.setText(org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.openButton.text")); // NOI18N
264  openButton.setEnabled(false);
265  openButton.addActionListener(new java.awt.event.ActionListener() {
266  public void actionPerformed(java.awt.event.ActionEvent evt) {
267  openButtonActionPerformed(evt);
268  }
269  });
270 
271  imagesTable.setModel(new javax.swing.table.DefaultTableModel(
272  new Object [][] {
273 
274  },
275  new String [] {
276 
277  }
278  ));
279  imagesTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
280  imagesTable.setShowHorizontalLines(false);
281  imagesTable.setShowVerticalLines(false);
282  imagesTable.getTableHeader().setReorderingAllowed(false);
283  imagesTable.setUpdateSelectionOnSort(false);
284  imagesTable.addMouseListener(new java.awt.event.MouseAdapter() {
285  public void mouseClicked(java.awt.event.MouseEvent evt) {
286  imagesTableMouseClicked(evt);
287  }
288  });
289  imagesTable.addKeyListener(new java.awt.event.KeyAdapter() {
290  public void keyPressed(java.awt.event.KeyEvent evt) {
291  imagesTableKeyPressed(evt);
292  }
293  });
294  tableScrollPane.setViewportView(imagesTable);
295 
296  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
297  this.setLayout(layout);
298  layout.setHorizontalGroup(
299  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
300  .addGroup(layout.createSequentialGroup()
301  .addContainerGap()
302  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
303  .addGroup(layout.createSequentialGroup()
304  .addComponent(jLabel1)
305  .addGap(292, 414, Short.MAX_VALUE))
306  .addGroup(layout.createSequentialGroup()
307  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
308  .addComponent(tableScrollPane)
309  .addGroup(layout.createSequentialGroup()
310  .addGap(0, 0, Short.MAX_VALUE)
311  .addComponent(openButton)
312  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
313  .addComponent(cancelButton)))
314  .addContainerGap())))
315  );
316  layout.setVerticalGroup(
317  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
318  .addGroup(layout.createSequentialGroup()
319  .addContainerGap()
320  .addComponent(jLabel1)
321  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
322  .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE)
323  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
324  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
325  .addComponent(cancelButton)
326  .addComponent(openButton))
327  .addContainerGap())
328  );
329  }// </editor-fold>//GEN-END:initComponents
330 
331  private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
332  openCase();
333  }//GEN-LAST:event_openButtonActionPerformed
334 
335  private void imagesTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_imagesTableMouseClicked
336  // If it's a doubleclick
337  if (evt.getClickCount() == 2) {
338  openCase();
339  }
340  }//GEN-LAST:event_imagesTableMouseClicked
341 
342  private void imagesTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_imagesTableKeyPressed
343  if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
344  openCase();
345  }
346  }//GEN-LAST:event_imagesTableKeyPressed
347 
348  // Variables declaration - do not modify//GEN-BEGIN:variables
349  private javax.swing.JButton cancelButton;
350  private javax.swing.JTable imagesTable;
351  private javax.swing.JLabel jLabel1;
352  private javax.swing.JButton openButton;
353  private javax.swing.JScrollPane tableScrollPane;
354  // End of variables declaration//GEN-END:variables
355 
356 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.