19 package org.sleuthkit.autopsy.livetriage;
 
   21 import java.util.ArrayList;
 
   22 import java.util.List;
 
   23 import java.util.concurrent.CancellationException;
 
   24 import java.util.logging.Level;
 
   25 import java.awt.Dimension;
 
   26 import java.awt.Point;
 
   27 import java.util.Collections;
 
   28 import javax.swing.SwingWorker;
 
   29 import javax.swing.event.ListSelectionEvent;
 
   30 import javax.swing.event.ListSelectionListener;
 
   31 import javax.swing.event.TableModelListener;
 
   32 import javax.swing.table.TableModel;
 
   33 import org.openide.util.NbBundle;
 
   41 @SuppressWarnings(
"PMD.SingularField") 
 
   42 class SelectDriveDialog extends javax.swing.JDialog {
 
   44     private List<LocalDisk> disks = 
new ArrayList<>();
 
   45     private final LocalDiskModel model = 
new LocalDiskModel();
 
   46     private final java.awt.Frame parent;
 
   47     private String drivePath = 
"";
 
   52     @NbBundle.Messages({
"SelectDriveDialog.title=Create Live Triage Drive"})
 
   53     SelectDriveDialog(java.awt.Frame parent, 
boolean modal) {
 
   59         bnOk.setEnabled(
false);
 
   60         diskTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
 
   62             public void valueChanged(ListSelectionEvent e) {
 
   63                 if (diskTable.getSelectedRow() >= 0 && diskTable.getSelectedRow() < disks.size()) {
 
   64                     bnOk.setEnabled(
true);
 
   66                     bnOk.setEnabled(
false);
 
   73         this.setTitle(Bundle.SelectDriveDialog_title());
 
   75         final Dimension parentSize = parent.getSize();
 
   76         final Point parentLocationOnScreen = parent.getLocationOnScreen();
 
   77         final Dimension childSize = this.getSize();
 
   80         x = (parentSize.width - childSize.width) / 2;
 
   81         y = (parentSize.height - childSize.height) / 2;
 
   82         x += parentLocationOnScreen.x;
 
   83         y += parentLocationOnScreen.y;
 
   89     String getSelectedDrive() {
 
   90         return this.drivePath;
 
   98     @SuppressWarnings(
"unchecked")
 
  100     private 
void initComponents() {
 
  102         jScrollPane1 = 
new javax.swing.JScrollPane();
 
  103         diskTable = 
new javax.swing.JTable();
 
  104         jLabel1 = 
new javax.swing.JLabel();
 
  105         bnRefresh = 
new javax.swing.JButton();
 
  106         bnOk = 
new javax.swing.JButton();
 
  107         errorLabel = 
new javax.swing.JLabel();
 
  108         jSeparator1 = 
new javax.swing.JSeparator();
 
  109         bnCancel = 
new javax.swing.JButton();
 
  110         jScrollPane2 = 
new javax.swing.JScrollPane();
 
  111         jTextArea1 = 
new javax.swing.JTextArea();
 
  113         setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
 
  115         diskTable.setModel(model);
 
  116         jScrollPane1.setViewportView(diskTable);
 
  118         org.openide.awt.Mnemonics.setLocalizedText(jLabel1, 
org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, 
"SelectDriveDialog.jLabel1.text")); 
 
  120         org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, 
org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, 
"SelectDriveDialog.bnRefresh.text")); 
 
  121         bnRefresh.addActionListener(
new java.awt.event.ActionListener() {
 
  122             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  123                 bnRefreshActionPerformed(evt);
 
  127         org.openide.awt.Mnemonics.setLocalizedText(bnOk, 
org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, 
"SelectDriveDialog.bnOk.text")); 
 
  128         bnOk.addActionListener(
new java.awt.event.ActionListener() {
 
  129             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  130                 bnOkActionPerformed(evt);
 
  134         org.openide.awt.Mnemonics.setLocalizedText(errorLabel, 
org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, 
"SelectDriveDialog.errorLabel.text")); 
 
  136         org.openide.awt.Mnemonics.setLocalizedText(bnCancel, 
org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, 
"SelectDriveDialog.bnCancel.text")); 
 
  137         bnCancel.addActionListener(
new java.awt.event.ActionListener() {
 
  138             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  139                 bnCancelActionPerformed(evt);
 
  143         jScrollPane2.setBorder(null);
 
  145         jTextArea1.setBackground(
new java.awt.Color(240, 240, 240));
 
  146         jTextArea1.setColumns(20);
 
  147         jTextArea1.setFont(
new java.awt.Font(
"Tahoma", 0, 11)); 
 
  148         jTextArea1.setRows(5);
 
  149         jTextArea1.setText(
org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, 
"SelectDriveDialog.jTextArea1.text")); 
 
  150         jTextArea1.setBorder(null);
 
  151         jScrollPane2.setViewportView(jTextArea1);
 
  153         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(getContentPane());
 
  154         getContentPane().setLayout(layout);
 
  155         layout.setHorizontalGroup(
 
  156             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  157             .addGroup(layout.createSequentialGroup()
 
  159                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, 
false)
 
  160                     .addGroup(layout.createSequentialGroup()
 
  161                         .addComponent(bnRefresh, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE)
 
  162                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 48, Short.MAX_VALUE)
 
  163                         .addComponent(bnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  164                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  165                         .addComponent(bnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  166                     .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
 
  167                     .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  168                     .addComponent(jSeparator1)
 
  169                     .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  170                     .addComponent(jScrollPane2))
 
  171                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  173         layout.setVerticalGroup(
 
  174             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  175             .addGroup(layout.createSequentialGroup()
 
  177                 .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  178                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  179                 .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  180                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  181                 .addComponent(jLabel1)
 
  182                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  183                 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  184                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  185                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  186                     .addComponent(bnRefresh)
 
  187                     .addComponent(bnCancel)
 
  189                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  190                 .addComponent(errorLabel)
 
  191                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  197     private void bnRefreshActionPerformed(java.awt.event.ActionEvent evt) {
 
  201     private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {
 
  202         if (diskTable.getSelectedRow() >= 0 && diskTable.getSelectedRow() < disks.size()) {
 
  203             LocalDisk selectedDisk = disks.get(diskTable.getSelectedRow());
 
  204             drivePath = selectedDisk.getPath();
 
  211     private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {
 
  217     private javax.swing.JButton bnCancel;
 
  218     private javax.swing.JButton bnOk;
 
  219     private javax.swing.JButton bnRefresh;
 
  220     private javax.swing.JTable diskTable;
 
  221     private javax.swing.JLabel errorLabel;
 
  222     private javax.swing.JLabel jLabel1;
 
  223     private javax.swing.JScrollPane jScrollPane1;
 
  224     private javax.swing.JScrollPane jScrollPane2;
 
  225     private javax.swing.JSeparator jSeparator1;
 
  226     private javax.swing.JTextArea jTextArea1;
 
  232     @NbBundle.Messages({
"SelectDriveDialog.localDiskModel.loading.msg=",
 
  233         "SelectDriveDialog.localDiskModel.nodrives.msg=Executable could not be found",
 
  234         "SelectDriveDialog.diskTable.column1.title=Disk Name",
 
  235         "SelectDriveDialog.diskTable.column2.title=Disk Size",
 
  236         "SelectDriveDialog.errLabel.disksNotDetected.text=Disks were not detected. On some systems it requires admin privileges",
 
  237         "SelectDriveDialog.errLabel.disksNotDetected.toolTipText=Disks were not detected." 
  242         private LocalDiskThread worker = null;
 
  243         private boolean ready = 
false;
 
  244         private volatile boolean loadingDisks = 
false;
 
  247         private final String LOADING = NbBundle.getMessage(this.getClass(), 
"SelectDriveDialog.localDiskModel.loading.msg");
 
  248         private final String NO_DRIVES = NbBundle.getMessage(this.getClass(), 
"SelectDriveDialog.localDiskModel.nodrives.msg");
 
  253             if (loadingDisks && worker != null) {
 
  254                 worker.cancel(
false);
 
  258             errorLabel.setText(
"");
 
  259             diskTable.setEnabled(
false);
 
  262             worker = 
new LocalDiskThread();
 
  268             if (disks.isEmpty()) {
 
  282             switch (columnIndex) {
 
  284                     return NbBundle.getMessage(this.getClass(), 
"SelectDriveDialog.diskTable.column1.title");
 
  286                     return NbBundle.getMessage(this.getClass(), 
"SelectDriveDialog.diskTable.column2.title");
 
  305                 if (disks.isEmpty()) {
 
  308                 switch (columnIndex) {
 
  310                         return disks.get(rowIndex).getName();
 
  312                         return disks.get(rowIndex).getReadableSize();
 
  314                         return disks.get(rowIndex).getPath();
 
  322         public void setValueAt(Object aValue, 
int rowIndex, 
int columnIndex) {
 
  340         class LocalDiskThread 
extends SwingWorker<Object, Void> {
 
  343             private List<LocalDisk> partitions = 
new ArrayList<>();
 
  346             protected Object doInBackground() throws Exception {
 
  348                 partitions = 
new ArrayList<>();
 
  357             private void displayErrors() {
 
  358                 if (partitions.isEmpty()) {
 
  361                                 NbBundle.getMessage(
this.getClass(), 
"SelectDriveDialog.errLabel.disksNotDetected.text"));
 
  362                         errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
 
  363                                 "SelectDriveDialog.errLabel.disksNotDetected.toolTipText"));
 
  366                                 NbBundle.getMessage(
this.getClass(), 
"SelectDriveDialog.errLabel.drivesNotDetected.text"));
 
  367                         errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
 
  368                                 "SelectDriveDialog.errLabel.drivesNotDetected.toolTipText"));
 
  370                     errorLabel.setVisible(
true);
 
  371                     diskTable.setEnabled(
false);
 
  376             protected void done() {
 
  379                 } 
catch (CancellationException ex) {
 
  380                     logger.log(Level.INFO, 
"Loading local disks was canceled."); 
 
  381                 } 
catch (InterruptedException ex) {
 
  382                     logger.log(Level.INFO, 
"Loading local disks was interrupted."); 
 
  383                 } 
catch (Exception ex) {
 
  384                     logger.log(Level.SEVERE, 
"Fatal error when loading local disks", ex); 
 
  386                     if (!this.isCancelled()) {
 
  389                         loadingDisks = 
false;
 
  390                         disks = 
new ArrayList<>();
 
  391                         disks.addAll(partitions);
 
  393                         if (disks.size() > 0) {
 
  394                             diskTable.setEnabled(
true);
 
  395                             diskTable.clearSelection();
 
  397                             Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
 
  403                 diskTable.revalidate();
 
void removeTableModelListener(TableModelListener l)
 
void addTableModelListener(TableModelListener l)
 
Class<?> getColumnClass(int columnIndex)
 
boolean isCellEditable(int rowIndex, int columnIndex)
 
String getColumnName(int columnIndex)
 
synchronized static Logger getLogger(String name)
 
Object getValueAt(int rowIndex, int columnIndex)
 
void setValueAt(Object aValue, int rowIndex, int columnIndex)