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 org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.selectLocalDiskLabel.text"));
116 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
117 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.errorLabel.text"));
119 localDiskTable.setModel(model);
120 localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
121 localDiskScrollPane.setViewportView(localDiskTable);
123 org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.refreshLocalDisksButton.text"));
124 refreshLocalDisksButton.addActionListener(
new java.awt.event.ActionListener() {
125 public void actionPerformed(java.awt.event.ActionEvent evt) {
126 refreshLocalDisksButtonActionPerformed(evt);
130 org.openide.awt.Mnemonics.setLocalizedText(okButton,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.okButton.text"));
131 okButton.setEnabled(
false);
132 okButton.addActionListener(
new java.awt.event.ActionListener() {
133 public void actionPerformed(java.awt.event.ActionEvent evt) {
134 okButtonActionPerformed(evt);
138 org.openide.awt.Mnemonics.setLocalizedText(cancelButton,
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class,
"LocalDiskSelectionDialog.cancelButton.text"));
139 cancelButton.addActionListener(
new java.awt.event.ActionListener() {
140 public void actionPerformed(java.awt.event.ActionEvent evt) {
141 cancelButtonActionPerformed(evt);
145 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(getContentPane());
146 getContentPane().setLayout(layout);
147 layout.setHorizontalGroup(
148 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
149 .addGroup(layout.createSequentialGroup()
151 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
152 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
153 .addGroup(layout.createSequentialGroup()
154 .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
155 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
156 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
157 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
158 .addComponent(refreshLocalDisksButton))
159 .addGroup(layout.createSequentialGroup()
160 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
161 .addComponent(selectLocalDiskLabel)
162 .addComponent(errorLabel))
163 .addGap(0, 0, Short.MAX_VALUE)))
166 layout.setVerticalGroup(
167 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
168 .addGroup(layout.createSequentialGroup()
170 .addComponent(selectLocalDiskLabel)
172 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
173 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
174 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
175 .addComponent(refreshLocalDisksButton)
176 .addComponent(okButton)
177 .addComponent(cancelButton))
178 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
179 .addComponent(errorLabel)
180 .addContainerGap(27, Short.MAX_VALUE))
186 private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {
190 private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {
194 private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
195 localDiskTable.clearSelection();
200 private javax.swing.JButton cancelButton;
201 private javax.swing.JLabel errorLabel;
202 private javax.swing.JScrollPane localDiskScrollPane;
203 private javax.swing.JTable localDiskTable;
204 private javax.swing.JButton okButton;
205 private javax.swing.JButton refreshLocalDisksButton;
206 private javax.swing.JLabel selectLocalDiskLabel;
212 private void fireUpdateEvent() {
214 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
215 }
catch (Exception e) {
216 logger.log(Level.SEVERE,
"LocalDiskSelectionDialog listener threw exception", e);
217 MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(),
218 Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(),
219 MessageNotifyUtil.MessageType.ERROR);
228 String getContentPaths() {
229 LocalDisk selected = getLocalDiskSelection();
230 if (selected != null) {
231 return selected.getPath();
239 private void refreshTable() {
241 localDiskTable.clearSelection();
249 LocalDisk getLocalDiskSelection() {
250 if (disks.size() > 0) {
251 int selectedRow = localDiskTable.getSelectedRow();
252 if (selectedRow >= 0 && selectedRow < disks.size()) {
253 return disks.get(selectedRow);
260 "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...",
261 "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives",
268 private LocalDiskThread worker = null;
269 private boolean ready =
false;
270 private volatile boolean loadingDisks =
false;
275 if (loadingDisks && worker != null) {
276 worker.cancel(
false);
280 errorLabel.setText(
"");
281 localDiskTable.setEnabled(
false);
284 worker =
new LocalDiskThread();
290 if (disks.isEmpty()) {
303 "LocalDiskSelectionDialog.columnName.diskName=Disk Name",
304 "LocalDiskSelectionDialog.columnName.diskSize=Disk Size"
309 switch (columnIndex) {
311 return Bundle.LocalDiskSelectionDialog_columnName_diskName();
313 return Bundle.LocalDiskSelectionDialog_columnName_diskSize();
332 if (disks.isEmpty()) {
333 return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives();
335 switch (columnIndex) {
337 return disks.get(rowIndex).getName();
339 return disks.get(rowIndex).getReadableSize();
341 return disks.get(rowIndex).getPath();
344 return Bundle.LocalDiskSelectionDialog_tableMessage_loading();
349 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
367 class LocalDiskThread
extends SwingWorker<Object, Void> {
370 private List<LocalDisk> physicalDrives =
new ArrayList<>();
371 private List<LocalDisk> partitions =
new ArrayList<>();
374 protected Object doInBackground() throws Exception {
376 physicalDrives =
new ArrayList<>();
377 partitions =
new ArrayList<>();
387 private void displayErrors() {
388 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
390 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
391 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
393 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
394 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
396 errorLabel.setVisible(
true);
397 localDiskTable.setEnabled(
false);
398 }
else if (physicalDrives.isEmpty()) {
399 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
400 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
401 errorLabel.setVisible(
true);
406 protected void done() {
409 }
catch (CancellationException ex) {
410 logger.log(Level.INFO,
"Loading local disks was canceled.");
411 }
catch (InterruptedException ex) {
412 logger.log(Level.INFO,
"Loading local disks was interrupted.");
413 }
catch (ExecutionException ex) {
414 logger.log(Level.SEVERE,
"Fatal error when loading local disks", ex);
416 if (!this.isCancelled()) {
419 loadingDisks =
false;
420 disks =
new ArrayList<>();
421 disks.addAll(physicalDrives);
422 disks.addAll(partitions);
423 if (disks.size() > 0) {
424 localDiskTable.setEnabled(
true);
425 localDiskTable.clearSelection();
428 String userConfigPath = PlatformUtil.getUserConfigDirectory();
429 for (Iterator<LocalDisk> iterator = disks.iterator(); iterator.hasNext();) {
430 LocalDisk disk = iterator.next();
431 String diskPath = disk.getPath();
432 if (diskPath.startsWith(
"\\\\.\\")) {
434 diskPath = diskPath.substring(4);
436 if (userConfigPath.startsWith(diskPath)) {
441 Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
447 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)