19 package org.sleuthkit.autopsy.casemodule;
 
   21 import java.awt.event.ActionListener;
 
   22 import java.awt.event.KeyEvent;
 
   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;
 
   41 @SuppressWarnings(
"PMD.SingularField") 
 
   42 class OpenRecentCasePanel extends javax.swing.JPanel {
 
   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;
 
   55     private OpenRecentCasePanel() {
 
   57         imagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 
   58         imagesTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
 
   60             public void valueChanged(ListSelectionEvent e) {
 
   62                 if (!e.getValueIsAdjusting()){
 
   63                     openButton.setEnabled(imagesTable.getSelectedRowCount() > 0);
 
   73     static OpenRecentCasePanel getInstance() {
 
   74         if (instance == null) {
 
   75             instance = 
new OpenRecentCasePanel();
 
   77         instance.refreshRecentCasesTable();
 
   86     void setCloseButtonActionListener(ActionListener listener) {
 
   87         this.cancelButton.addActionListener(listener);
 
   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);
 
  100         int width = tableScrollPane.getPreferredSize().width;
 
  101         imagesTable.getColumnModel().getColumn(0).setPreferredWidth((
int) (.30 * width));
 
  102         imagesTable.getColumnModel().getColumn(1).setPreferredWidth((
int) (.70 * width));
 
  104         if (imagesTable.getRowCount() > 0) {
 
  105             imagesTable.setRowSelectionInterval(0, 0);
 
  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) {
 
  120         final String caseMetadataFilePath = casePaths[imagesTable.getSelectedRow()];
 
  121         final String caseName = caseNames[imagesTable.getSelectedRow()];
 
  122         if (!caseMetadataFilePath.isEmpty()) {
 
  124                 StartupWindowProvider.getInstance().close();
 
  125                 CueBannerPanel.closeOpenRecentCasesWindow();
 
  126             } 
catch (Exception ex) {
 
  127                 logger.log(Level.SEVERE, 
"Error closing start up window", ex); 
 
  131             if (caseName.isEmpty() || caseMetadataFilePath.isEmpty() || (!
new File(caseMetadataFilePath).exists())) {
 
  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); 
 
  138                 StartupWindowProvider.getInstance().open();
 
  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); 
 
  149                                 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
 
  150                                         ex.getLocalizedMessage(),
 
  151                                         CaseOpenAction_msgDlg_cantOpenCase_title(), 
 
  152                                         JOptionPane.ERROR_MESSAGE);
 
  154                             StartupWindowProvider.getInstance().open();
 
  167         private static final long serialVersionUID = 1L;
 
  172             for (String s : caseNames) {
 
  187             String colName = null;
 
  190                     colName = NbBundle.getMessage(OpenRecentCasePanel.class, 
"OpenRecentCasePanel.colName.caseName");
 
  193                     colName = NbBundle.getMessage(OpenRecentCasePanel.class, 
"OpenRecentCasePanel.colName.path");
 
  204             switch (columnIndex) {
 
  206                     ret = caseNames[rowIndex];
 
  209                     ret = shortenPath(casePaths[rowIndex]);
 
  212                     logger.log(Level.SEVERE, 
"Invalid table column index: {0}", columnIndex); 
 
  224         public void setValueAt(Object aValue, 
int rowIndex, 
int columnIndex) {
 
  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));
 
  240             return shortenedPath;
 
  249     @SuppressWarnings(
"unchecked")
 
  251     private 
void initComponents() {
 
  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();
 
  259         jLabel1.setText(
org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, 
"OpenRecentCasePanel.jLabel1.text")); 
 
  261         cancelButton.setText(
org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, 
"OpenRecentCasePanel.cancelButton.text")); 
 
  263         openButton.setText(
org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, 
"OpenRecentCasePanel.openButton.text")); 
 
  264         openButton.setEnabled(
false);
 
  265         openButton.addActionListener(
new java.awt.event.ActionListener() {
 
  266             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  267                 openButtonActionPerformed(evt);
 
  271         imagesTable.setModel(
new javax.swing.table.DefaultTableModel(
 
  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);
 
  289         imagesTable.addKeyListener(
new java.awt.event.KeyAdapter() {
 
  290             public void keyPressed(java.awt.event.KeyEvent evt) {
 
  291                 imagesTableKeyPressed(evt);
 
  294         tableScrollPane.setViewportView(imagesTable);
 
  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()
 
  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())))
 
  316         layout.setVerticalGroup(
 
  317             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  318             .addGroup(layout.createSequentialGroup()
 
  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))
 
  331     private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  335     private void imagesTableMouseClicked(java.awt.event.MouseEvent evt) {
 
  337         if (evt.getClickCount() == 2) {
 
  342     private void imagesTableKeyPressed(java.awt.event.KeyEvent evt) {
 
  343         if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
 
  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;
 
String getColumnName(int column)
 
String shortenPath(String path)
 
Object getValueAt(int rowIndex, int columnIndex)
 
boolean isCellEditable(int rowIndex, int columnIndex)
 
void setValueAt(Object aValue, int rowIndex, int columnIndex)