19 package org.sleuthkit.autopsy.casemodule;
21 import java.awt.Window;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.concurrent.CancellationException;
27 import java.util.concurrent.ExecutionException;
28 import java.util.logging.Level;
29 import javax.swing.JDialog;
30 import javax.swing.SwingWorker;
31 import javax.swing.event.ListSelectionEvent;
32 import javax.swing.event.ListSelectionListener;
33 import javax.swing.event.TableModelListener;
34 import javax.swing.table.TableModel;
35 import org.openide.util.NbBundle;
43 "LocalDiskSelectionDialog.moduleErrorMessage.title=Module Error",
44 "LocalDiskSelectionDialog.moduleErrorMessage.body=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete.",
45 "LocalDiskSelectionDialog.errorMessage.disksNotDetected=Disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\").",
46 "LocalDiskSelectionDialog.errorMessage.drivesNotDetected=Local drives were not detected. Auto-detection not supported on this OS or admin privileges required",
47 "LocalDiskSelectionDialog.errorMessage.someDisksNotDetected=Some disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\")."
52 @SuppressWarnings(
"PMD.SingularField")
53 final class LocalDiskSelectionDialog
extends JDialog {
55 private static final Logger logger = Logger.getLogger(LocalDiskSelectionDialog.class.getName());
56 private static final long serialVersionUID = 1L;
57 private List<LocalDisk> disks;
58 private final LocalDiskModel model;
63 LocalDiskSelectionDialog() {
64 super((Window) LocalDiskPanel.getDefault().getTopLevelAncestor(), ModalityType.MODELESS);
66 this.model =
new LocalDiskModel();
67 this.disks =
new ArrayList<>();
72 localDiskTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
74 public void valueChanged(ListSelectionEvent e) {
75 int selectedRow = localDiskTable.getSelectedRow();
76 okButton.setEnabled(selectedRow >= 0 && selectedRow < disks.size());
86 setSize(getPreferredSize());
87 setLocationRelativeTo(this.getParent());
88 setAlwaysOnTop(
false);
97 @SuppressWarnings(
"unchecked")
99 private
void initComponents() {
101 selectLocalDiskLabel =
new javax.swing.JLabel();
102 errorLabel =
new javax.swing.JLabel();
103 localDiskScrollPane =
new javax.swing.JScrollPane();
104 localDiskTable =
new javax.swing.JTable();
105 refreshLocalDisksButton =
new javax.swing.JButton();
106 okButton =
new javax.swing.JButton();
107 cancelButton =
new javax.swing.JButton();
109 setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
110 setTitle(
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.title"));
111 setAlwaysOnTop(
true);
114 selectLocalDiskLabel.setFont(selectLocalDiskLabel.getFont().deriveFont(selectLocalDiskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
115 org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.selectLocalDiskLabel.text"));
117 errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
118 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
119 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.errorLabel.text"));
121 localDiskTable.setModel(model);
122 localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
123 localDiskScrollPane.setViewportView(localDiskTable);
125 org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.refreshLocalDisksButton.text"));
126 refreshLocalDisksButton.addActionListener(
new java.awt.event.ActionListener() {
127 public void actionPerformed(java.awt.event.ActionEvent evt) {
128 refreshLocalDisksButtonActionPerformed(evt);
132 org.openide.awt.Mnemonics.setLocalizedText(okButton,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.okButton.text"));
133 okButton.setEnabled(
false);
134 okButton.addActionListener(
new java.awt.event.ActionListener() {
135 public void actionPerformed(java.awt.event.ActionEvent evt) {
136 okButtonActionPerformed(evt);
140 org.openide.awt.Mnemonics.setLocalizedText(cancelButton,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.cancelButton.text"));
141 cancelButton.addActionListener(
new java.awt.event.ActionListener() {
142 public void actionPerformed(java.awt.event.ActionEvent evt) {
143 cancelButtonActionPerformed(evt);
147 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(getContentPane());
148 getContentPane().setLayout(layout);
149 layout.setHorizontalGroup(
150 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
151 .addGroup(layout.createSequentialGroup()
153 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
154 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
155 .addGroup(layout.createSequentialGroup()
156 .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
157 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
158 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
159 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
160 .addComponent(refreshLocalDisksButton))
161 .addGroup(layout.createSequentialGroup()
162 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
163 .addComponent(selectLocalDiskLabel)
164 .addComponent(errorLabel))
165 .addGap(0, 0, Short.MAX_VALUE)))
168 layout.setVerticalGroup(
169 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
170 .addGroup(layout.createSequentialGroup()
172 .addComponent(selectLocalDiskLabel)
174 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
175 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
176 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
177 .addComponent(refreshLocalDisksButton)
178 .addComponent(okButton)
179 .addComponent(cancelButton))
180 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
181 .addComponent(errorLabel)
182 .addContainerGap(27, Short.MAX_VALUE))
188 private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {
192 private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {
196 private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
197 localDiskTable.clearSelection();
202 private javax.swing.JButton cancelButton;
203 private javax.swing.JLabel errorLabel;
204 private javax.swing.JScrollPane localDiskScrollPane;
205 private javax.swing.JTable localDiskTable;
206 private javax.swing.JButton okButton;
207 private javax.swing.JButton refreshLocalDisksButton;
208 private javax.swing.JLabel selectLocalDiskLabel;
214 private void fireUpdateEvent() {
216 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
217 }
catch (Exception e) {
218 logger.log(Level.SEVERE,
"LocalDiskSelectionDialog listener threw exception", e);
219 MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(),
220 Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(),
221 MessageNotifyUtil.MessageType.ERROR);
230 String getContentPaths() {
231 LocalDisk selected = getLocalDiskSelection();
232 if (selected != null) {
233 return selected.getPath();
241 private void refreshTable() {
243 localDiskTable.clearSelection();
251 LocalDisk getLocalDiskSelection() {
252 if (disks.size() > 0) {
253 int selectedRow = localDiskTable.getSelectedRow();
254 if (selectedRow >= 0 && selectedRow < disks.size()) {
255 return disks.get(selectedRow);
262 "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...",
263 "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives",
270 private LocalDiskThread worker = null;
271 private boolean ready =
false;
272 private volatile boolean loadingDisks =
false;
277 if (loadingDisks && worker != null) {
278 worker.cancel(
false);
282 errorLabel.setText(
"");
283 localDiskTable.setEnabled(
false);
286 worker =
new LocalDiskThread();
292 if (disks.isEmpty()) {
305 "LocalDiskSelectionDialog.columnName.diskName=Disk Name",
306 "LocalDiskSelectionDialog.columnName.diskSize=Disk Size"
311 switch (columnIndex) {
313 return Bundle.LocalDiskSelectionDialog_columnName_diskName();
315 return Bundle.LocalDiskSelectionDialog_columnName_diskSize();
334 if (disks.isEmpty()) {
335 return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives();
337 switch (columnIndex) {
339 return disks.get(rowIndex).getName();
341 return disks.get(rowIndex).getReadableSize();
343 return disks.get(rowIndex).getPath();
346 return Bundle.LocalDiskSelectionDialog_tableMessage_loading();
351 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
369 class LocalDiskThread
extends SwingWorker<Object, Void> {
372 private List<LocalDisk> physicalDrives =
new ArrayList<>();
373 private List<LocalDisk> partitions =
new ArrayList<>();
376 protected Object doInBackground() throws Exception {
378 physicalDrives =
new ArrayList<>();
379 partitions =
new ArrayList<>();
389 private void displayErrors() {
390 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
392 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
393 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
395 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
396 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
398 errorLabel.setVisible(
true);
399 localDiskTable.setEnabled(
false);
400 }
else if (physicalDrives.isEmpty()) {
401 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
402 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
403 errorLabel.setVisible(
true);
408 protected void done() {
411 }
catch (CancellationException ex) {
412 logger.log(Level.INFO,
"Loading local disks was canceled.");
413 }
catch (InterruptedException ex) {
414 logger.log(Level.INFO,
"Loading local disks was interrupted.");
415 }
catch (ExecutionException ex) {
416 logger.log(Level.SEVERE,
"Fatal error when loading local disks", ex);
418 if (!this.isCancelled()) {
421 loadingDisks =
false;
422 disks =
new ArrayList<>();
423 disks.addAll(physicalDrives);
424 disks.addAll(partitions);
425 if (disks.size() > 0) {
426 localDiskTable.setEnabled(
true);
427 localDiskTable.clearSelection();
430 String userConfigPath = PlatformUtil.getUserConfigDirectory();
431 for (Iterator<LocalDisk> iterator = disks.iterator(); iterator.hasNext();) {
432 LocalDisk disk = iterator.next();
433 String diskPath = disk.getPath();
434 if (diskPath.startsWith(
"\\\\.\\")) {
436 diskPath = diskPath.substring(4);
438 if (userConfigPath.startsWith(diskPath)) {
443 Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
449 localDiskTable.revalidate();
void addTableModelListener(TableModelListener l)
Object getValueAt(int rowIndex, int columnIndex)
Class<?> getColumnClass(int columnIndex)
void setValueAt(Object aValue, int rowIndex, int columnIndex)
void removeTableModelListener(TableModelListener l)
String getColumnName(int columnIndex)
synchronized static Logger getLogger(String name)
boolean isCellEditable(int rowIndex, int columnIndex)