diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index ba910c4391..9c04508c1f 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -27,11 +27,9 @@ OpenRecentCasePanel.openButton.text=Open ImageFilePanel.pathLabel.text=Browse for an image file: ImageFilePanel.browseButton.text=Browse ImageFilePanel.pathTextField.text= -LocalDiskPanel.diskLabel.text=Select a local disk: MissingImageDialog.selectButton.text=Select Image MissingImageDialog.titleLabel.text=Search for missing image MissingImageDialog.cancelButton.text=Cancel -LocalDiskPanel.errorLabel.text=Error Label AddImageWizardAddingProgressVisual.statusLabel.text=Data source has been added to the local database. Files are being analyzed. AddImageWizardAddingProgressVisual.progressLabel.text= AddImageWizardAddingProgressVisual.viewLogButton.text=View Log @@ -40,14 +38,10 @@ ImageFilePanel.timeZoneLabel.text=Please select the input timezone: ImageFilePanel.noFatOrphansCheckbox.text=Ignore orphan files in FAT file systems ImageFilePanel.noFatOrphansCheckbox.toolTipText= ImageFilePanel.descLabel.text=(faster results, although some data will not be searched) -LocalDiskPanel.timeZoneLabel.text=Please select the input timezone: +LocalDiskPanel.timeZoneLabel.text=Timezone: LocalDiskPanel.noFatOrphansCheckbox.toolTipText= LocalDiskPanel.noFatOrphansCheckbox.text=Ignore orphan files in FAT file systems LocalDiskPanel.descLabel.text=(faster results, although some data will not be searched) -LocalDiskPanel.imageWriterDirError.text=Error - directory does not exist -LocalDiskPanel.imageWriterEmptyPathError.text=Error - enter path for VHD -LocalDiskPanel.imageWriterIsDirError.text=Error - VHD path is a directory -LocalDiskPanel.imageWriterFileExistsError.text=Error - VHD path already exists MissingImageDialog.browseButton.text=Browse MissingImageDialog.pathNameTextField.text= AddImageWizardAddingProgressVisual.progressTextArea.border.title=Status @@ -115,16 +109,6 @@ CueBannerPanel.title.text=Open Recent Case ImageDSProcessor.dsType.text=Disk Image or VM File ImageDSProcessor.allDesc.text=All Supported Types LocalDiskDSProcessor.dsType.text=Local Disk -LocalDiskPanel.localDiskModel.loading.msg=Loading local disks... -LocalDiskPanel.localDiskModel.nodrives.msg=No Accessible Drives -LocalDiskPanel.moduleErr=Module Error -LocalDiskPanel.moduleErr.msg=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete. -LocalDiskPanel.errLabel.disksNotDetected.text=Disks were not detected. On some systems it requires admin privileges (or "Run as administrator"). -LocalDiskPanel.errLabel.disksNotDetected.toolTipText=Disks were not detected. On some systems it requires admin privileges (or "Run as administrator"). -LocalDiskPanel.errLabel.drivesNotDetected.text=Local drives were not detected. Auto-detection not supported on this OS or admin privileges required -LocalDiskPanel.errLabel.drivesNotDetected.toolTipText=Local drives were not detected. Auto-detection not supported on this OS or admin privileges required -LocalDiskPanel.errLabel.someDisksNotDetected.text=Some disks were not detected. On some systems it requires admin privileges (or "Run as administrator"). -LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText=Some disks were not detected. On some systems it requires admin privileges (or "Run as administrator"). LocalFilesDSProcessor.dsType=Logical Files LocalFilesDSProcessor.toString.text=Logical Files LocalFilesPanel.contentType.text=LOCAL @@ -184,7 +168,6 @@ IngestJobInfoPanel.jLabel1.text=Ingest Modules IngestJobInfoPanel.jLabel2.text=Ingest Jobs CaseInformationPanel.closeButton.text=Close LocalDiskPanel.copyImageCheckbox.text=Make a VHD image of the drive while it is being analyzed -LocalDiskPanel.imageWriterErrorLabel.text=Error Label LocalDiskPanel.jLabel1.text=Note that at least one ingest module must be run to create a complete copy LocalDiskPanel.pathTextField.text= LocalDiskPanel.browseButton.text=Browse @@ -220,7 +203,6 @@ MultiUserCasesPanel.cancelButton.text=Cancel ImageFilePanel.pathErrorLabel.text=Error Label ImageFilePanel.sectorSizeLabel.text=Sector size: LocalDiskPanel.sectorSizeLabel.text=Sector Size: -LocalDiskPanel.refreshTableButton.text=Refresh Local Disks LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default LocalFilesPanel.errorLabel.text=Error Label LocalFilesPanel.selectedPaths.toolTipText= @@ -241,3 +223,12 @@ LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonToolTipText= LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonText=Select LogicalEvidenceFilePanel.logicalEvidencePathField.text= LocalFilesPanel.changeNameButton.text=Change +LocalDiskPanel.selectDiskButton.text=Select Disk +LocalDiskSelectionDialog.refreshLocalDisksButton.text=Refresh Local Disks +LocalDiskSelectionDialog.errorLabel.text=Error Label +LocalDiskSelectionDialog.selectLocalDiskLabel.text=Select a local disk: +LocalDiskSelectionDialog.cancelButton.text=Cancel +LocalDiskSelectionDialog.okButton.text=OK +LocalDiskPanel.localDiskLabel.text=Local Disk: +LocalDiskPanel.imageWriterErrorLabel.text=Error Label +LocalDiskSelectionDialog.title=Select Local Disk diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties index 0400c3ac3e..8e405adec4 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties @@ -22,11 +22,9 @@ AddImageErrorsDialog.closeButton.text=\u9589\u3058\u308b OpenRecentCasePanel.openButton.text=\u958b\u304f ImageFilePanel.pathLabel.text=\u30a4\u30e1\u30fc\u30b8\u30d5\u30a1\u30a4\u30eb\u3092\u95b2\u89a7\uff1a ImageFilePanel.browseButton.text=\u95b2\u89a7 -LocalDiskPanel.diskLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30b9\u30af\u3092\u9078\u629e\uff1a MissingImageDialog.selectButton.text=\u30a4\u30e1\u30fc\u30b8\u3092\u9078\u629e MissingImageDialog.titleLabel.text=\u6b20\u843d\u3057\u305f\u30a4\u30e1\u30fc\u30b8\u306e\u691c\u7d22 MissingImageDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb -LocalDiskPanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb AddImageWizardAddingProgressVisual.statusLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d\u3067\u3059\u3002 AddImageWizardAddingProgressVisual.progressLabel.text=\uff1c\u30d7\u30ed\u30b0\u30ec\u30b9\uff1e AddImageWizardAddingProgressVisual.viewLogButton.text=\u30ed\u30b0\u3092\u8868\u793a @@ -205,3 +203,5 @@ LogicalEvidenceFilePanel.selectButton.text=\u8ffd\u52a0 LogicalEvidenceFilePanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb LogicalEvidenceFilePanel.logicalEvidenceFileChooser.dialogTitle=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonText=\u9078\u629e +LocalDiskSelectionDialog.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb +LocalDiskSelectionDialog.selectLocalDiskLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30b9\u30af\u3092\u9078\u629e\uff1a diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java index 1df465e02a..bc3d2d1f71 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java @@ -103,7 +103,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor, AutoIngestData */ @Override public JPanel getPanel() { - configPanel.refreshTable(); + configPanel.resetLocalDiskSelection(); return configPanel; } @@ -137,7 +137,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor, AutoIngestData public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) { if (!setDataSourceOptionsCalled) { deviceId = UUID.randomUUID().toString(); - drivePath = configPanel.getContentPaths(); + drivePath = configPanel.getContentPath(); sectorSize = configPanel.getSectorSize(); timeZone = configPanel.getTimeZone(); ignoreFatOrphanFiles = configPanel.getNoFatOrphans(); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.form index 940346b4e3..b46cf5ef1f 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.form @@ -26,52 +26,48 @@ - - - - - - - - - + + + - + + + + - + + + + + + + + + - - + + + + + + + + + + + - - - - - - + - - - - - - - - - - - - - - + - + @@ -81,73 +77,44 @@ - - - - - - + + + + + + - + - - - - - - + - + - + - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -203,22 +170,6 @@ - - - - - - - - - - - - - - - - @@ -278,16 +229,6 @@ - - - - - - - - - - @@ -305,5 +246,27 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java index 7e7d2dd4af..b22f858b63 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java @@ -20,20 +20,12 @@ package org.sleuthkit.autopsy.casemodule; import java.io.File; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Calendar; -import java.util.List; import java.util.SimpleTimeZone; import java.util.TimeZone; -import java.util.concurrent.CancellationException; import java.util.logging.Level; import javax.swing.JFileChooser; import javax.swing.JPanel; -import javax.swing.SwingWorker; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelListener; -import javax.swing.table.TableModel; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor; import org.sleuthkit.autopsy.coreutils.LocalDisk; @@ -42,9 +34,16 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings; -@NbBundle.Messages({"LocalDiskPanel.refreshTablebutton.text=Refresh Local Disks", - "LocalDiskPanel.listener.getOpenCase.errTitle=No open case available", - "LocalDiskPanel.listener.getOpenCase.errMsg=LocalDiskPanel listener couldn't get the open case." +@NbBundle.Messages({ + "LocalDiskPanel.errorMessage.noOpenCaseTitle=No open case available", + "LocalDiskPanel.errorMessage.noOpenCaseBody=LocalDiskPanel listener couldn't get the open case.", + "LocalDiskPanel.imageWriterError.directoryNotExist=Error - directory does not exist", + "LocalDiskPanel.imageWriterError.emptyPath=Error - enter path for VHD", + "LocalDiskPanel.imageWriterError.isDirectory=Error - VHD path is a directory", + "LocalDiskPanel.imageWriterError.fileExists=Error - VHD path already exists", + "LocalDiskPanel.moduleErrorMessage.title=Module Error", + "LocalDiskPanel.moduleErrorMessage.body=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete.", + "LocalDiskPanel.localDiskMessage.unspecified=Unspecified" }) /** * ImageTypePanel for adding a local disk or partition such as PhysicalDrive0 or @@ -56,55 +55,18 @@ final class LocalDiskPanel extends JPanel { private static final String[] SECTOR_SIZE_CHOICES = {"Auto Detect", "512", "1024", "2048", "4096"}; private static LocalDiskPanel instance; private static final long serialVersionUID = 1L; - private List disks; + private LocalDisk localDisk; private boolean enableNext = false; - private final LocalDiskModel model; private final JFileChooser fc = new JFileChooser(); /** * Creates new form LocalDiskPanel */ LocalDiskPanel() { - this.model = new LocalDiskModel(); - - this.disks = new ArrayList<>(); initComponents(); customInit(); createTimeZoneList(); createSectorSizeList(); - refreshTable(); - diskTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - if (diskTable.getSelectedRow() >= 0 && diskTable.getSelectedRow() < disks.size()) { - enableNext = true; - try { - setPotentialImageWriterPath(disks.get(diskTable.getSelectedRow())); - firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", e); //NON-NLS - MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_listener_getOpenCase_errTitle(), - Bundle.LocalDiskPanel_listener_getOpenCase_errMsg(), - MessageNotifyUtil.MessageType.ERROR); - } catch (Exception ex) { - logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS - MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr"), - NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"), - MessageNotifyUtil.MessageType.ERROR); - } - } else { //The selection changed to nothing valid being selected, such as with ctrl+click - enableNext = false; - try { - firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true); - } catch (Exception ex) { - logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS - MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr"), - NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"), - MessageNotifyUtil.MessageType.ERROR); - } - } - } - }); } /** @@ -119,9 +81,6 @@ final class LocalDiskPanel extends JPanel { @SuppressWarnings("unchecked") private void customInit() { - errorLabel.setVisible(false); - errorLabel.setText(""); - diskTable.setEnabled(false); imageWriterErrorLabel.setVisible(false); imageWriterErrorLabel.setText(""); if (!PlatformUtil.isWindowsOS()) { @@ -142,34 +101,25 @@ final class LocalDiskPanel extends JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - diskLabel = new javax.swing.JLabel(); - errorLabel = new javax.swing.JLabel(); timeZoneLabel = new javax.swing.JLabel(); timeZoneComboBox = new javax.swing.JComboBox<>(); noFatOrphansCheckbox = new javax.swing.JCheckBox(); descLabel = new javax.swing.JLabel(); - jScrollPane1 = new javax.swing.JScrollPane(); - diskTable = new javax.swing.JTable(); copyImageCheckbox = new javax.swing.JCheckBox(); pathTextField = new javax.swing.JTextField(); browseButton = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); imageWriterErrorLabel = new javax.swing.JLabel(); changeDatabasePathCheckbox = new javax.swing.JCheckBox(); - refreshTableButton = new javax.swing.JButton(); sectorSizeLabel = new javax.swing.JLabel(); sectorSizeComboBox = new javax.swing.JComboBox<>(); + selectDiskButton = new javax.swing.JButton(); + localDiskLabel = new javax.swing.JLabel(); + localDiskNameTextField = new javax.swing.JTextField(); setMinimumSize(new java.awt.Dimension(0, 420)); setPreferredSize(new java.awt.Dimension(485, 410)); - diskLabel.setFont(diskLabel.getFont().deriveFont(diskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(diskLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.diskLabel.text")); // NOI18N - - errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - errorLabel.setForeground(new java.awt.Color(255, 0, 0)); - org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.errorLabel.text")); // NOI18N - timeZoneLabel.setFont(timeZoneLabel.getFont().deriveFont(timeZoneLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.timeZoneLabel.text")); // NOI18N @@ -183,10 +133,6 @@ final class LocalDiskPanel extends JPanel { descLabel.setFont(descLabel.getFont().deriveFont(descLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.descLabel.text")); // NOI18N - diskTable.setModel(model); - diskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - jScrollPane1.setViewportView(diskTable); - org.openide.awt.Mnemonics.setLocalizedText(copyImageCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.copyImageCheckbox.text")); // NOI18N copyImageCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -216,14 +162,18 @@ final class LocalDiskPanel extends JPanel { org.openide.awt.Mnemonics.setLocalizedText(changeDatabasePathCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.changeDatabasePathCheckbox.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(refreshTableButton, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.refreshTableButton.text")); // NOI18N - refreshTableButton.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.sectorSizeLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(selectDiskButton, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.selectDiskButton.text")); // NOI18N + selectDiskButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - refreshTableButtonActionPerformed(evt); + selectDiskButtonActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.sectorSizeLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(localDiskLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.localDiskLabel.text")); // NOI18N + + localDiskNameTextField.setEditable(false); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -232,78 +182,73 @@ final class LocalDiskPanel extends JPanel { .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(diskLabel) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(refreshTableButton)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(localDiskLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(localDiskNameTextField) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(selectDiskButton)) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() .addComponent(timeZoneLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(timeZoneComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(noFatOrphansCheckbox) + .addComponent(copyImageCheckbox) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 342, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(browseButton)) + .addGroup(layout.createSequentialGroup() + .addGap(2, 2, 2) + .addComponent(sectorSizeLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(descLabel) + .addComponent(changeDatabasePathCheckbox) + .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(changeDatabasePathCheckbox, javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(imageWriterErrorLabel, javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(descLabel, javax.swing.GroupLayout.Alignment.LEADING))) - .addComponent(copyImageCheckbox, javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(errorLabel, javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(sectorSizeLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addGap(21, 21, 21) - .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 342, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(browseButton)) - .addComponent(noFatOrphansCheckbox, javax.swing.GroupLayout.Alignment.LEADING)) - .addGap(0, 0, Short.MAX_VALUE))))) + .addComponent(jLabel1)) + .addComponent(imageWriterErrorLabel)))) + .addGap(0, 39, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(diskLabel) - .addGap(1, 1, 1) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(refreshTableButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(localDiskLabel) + .addComponent(selectDiskButton) + .addComponent(localDiskNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(timeZoneLabel) .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(18, 18, 18) .addComponent(noFatOrphansCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(descLabel) - .addGap(10, 10, 10) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(sectorSizeLabel) - .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(18, 18, 18) .addComponent(copyImageCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(browseButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(13, 13, 13) .addComponent(changeDatabasePathCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(imageWriterErrorLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(errorLabel) - .addContainerGap(43, Short.MAX_VALUE)) + .addGap(12, 12, 12) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(sectorSizeLabel) + .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(127, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -334,26 +279,46 @@ final class LocalDiskPanel extends JPanel { fireUpdateEvent(); }//GEN-LAST:event_browseButtonActionPerformed - private void refreshTableButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshTableButtonActionPerformed - refreshTable(); - }//GEN-LAST:event_refreshTableButtonActionPerformed + private void selectDiskButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDiskButtonActionPerformed + LocalDiskSelectionDialog selectionDialog = new LocalDiskSelectionDialog(); + selectionDialog.display(); + LocalDisk selectedLocalDisk = selectionDialog.getLocalDiskSelection(); + if (selectedLocalDisk != null) { + localDisk = selectedLocalDisk; + localDiskNameTextField.setText(selectedLocalDisk.getName()); + + enableNext = true; + try { + setPotentialImageWriterPath(localDisk); + firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true); + } catch (NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS + MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_errorMessage_noOpenCaseTitle(), + Bundle.LocalDiskPanel_errorMessage_noOpenCaseBody(), + MessageNotifyUtil.MessageType.ERROR); + } catch (Exception ex) { + logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", ex); //NON-NLS + MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_moduleErrorMessage_title(), + Bundle.LocalDiskPanel_moduleErrorMessage_body(), + MessageNotifyUtil.MessageType.ERROR); + } + } + }//GEN-LAST:event_selectDiskButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton browseButton; private javax.swing.JCheckBox changeDatabasePathCheckbox; private javax.swing.JCheckBox copyImageCheckbox; private javax.swing.JLabel descLabel; - private javax.swing.JLabel diskLabel; - private javax.swing.JTable diskTable; - private javax.swing.JLabel errorLabel; private javax.swing.JLabel imageWriterErrorLabel; private javax.swing.JLabel jLabel1; - private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel localDiskLabel; + private javax.swing.JTextField localDiskNameTextField; private javax.swing.JCheckBox noFatOrphansCheckbox; private javax.swing.JTextField pathTextField; - private javax.swing.JButton refreshTableButton; private javax.swing.JComboBox sectorSizeComboBox; private javax.swing.JLabel sectorSizeLabel; + private javax.swing.JButton selectDiskButton; private javax.swing.JComboBox timeZoneComboBox; private javax.swing.JLabel timeZoneLabel; // End of variables declaration//GEN-END:variables @@ -363,22 +328,29 @@ final class LocalDiskPanel extends JPanel { firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true); } catch (Exception e) { logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS - MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr"), - NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"), + MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_moduleErrorMessage_title(), + Bundle.LocalDiskPanel_moduleErrorMessage_body(), MessageNotifyUtil.MessageType.ERROR); } } + + /** + * Reset the local disk selection to "Unspecified". + */ + void resetLocalDiskSelection() { + localDisk = null; + localDiskNameTextField.setText(Bundle.LocalDiskPanel_localDiskMessage_unspecified()); + enableNext = false; + } /** * Return the currently selected disk path. * * @return String selected disk path */ - String getContentPaths() { - if (disks.size() > 0) { - int selectedRow = diskTable.getSelectedRow(); - LocalDisk selected = disks.get(selectedRow); - return selected.getPath(); + String getContentPath() { + if (localDisk != null) { + return localDisk.getPath(); } else { return ""; } @@ -435,7 +407,7 @@ final class LocalDiskPanel extends JPanel { } private boolean imageWriterPathIsValid() { - if ((!copyImageCheckbox.isSelected()) || !(diskTable.getSelectedRow() >= 0 && diskTable.getSelectedRow() < disks.size())) { + if ((!copyImageCheckbox.isSelected()) || localDisk == null) { imageWriterErrorLabel.setVisible(false); imageWriterErrorLabel.setText(""); return true; @@ -443,7 +415,7 @@ final class LocalDiskPanel extends JPanel { if (pathTextField.getText().isEmpty()) { imageWriterErrorLabel.setVisible(true); - imageWriterErrorLabel.setText(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.imageWriterEmptyPathError.text")); + imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_emptyPath()); return false; } @@ -451,17 +423,17 @@ final class LocalDiskPanel extends JPanel { if (((f.getParentFile() != null) && (!f.getParentFile().exists())) || (f.getParentFile() == null)) { imageWriterErrorLabel.setVisible(true); - imageWriterErrorLabel.setText(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.imageWriterDirError.text")); + imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_directoryNotExist()); return false; } if (f.isDirectory()) { imageWriterErrorLabel.setVisible(true); - imageWriterErrorLabel.setText(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.imageWriterIsDirError.text")); + imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_isDirectory()); return false; } if (f.exists()) { imageWriterErrorLabel.setVisible(true); - imageWriterErrorLabel.setText(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.imageWriterFileExistsError.text")); + imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_fileExists()); return false; } imageWriterErrorLabel.setVisible(false); @@ -490,13 +462,6 @@ final class LocalDiskPanel extends JPanel { return enableNext; } - /** - * Refreshes the list of disks in the table. - */ - public void refreshTable() { - model.loadDisks(); - } - /** * Creates the drop down list for the time zones and defaults the selection * to the local machine time zone. @@ -544,189 +509,4 @@ final class LocalDiskPanel extends JPanel { } sectorSizeComboBox.setSelectedIndex(0); } - - /** - * Table model for displaing information from LocalDisk Objects in a table. - */ - private class LocalDiskModel implements TableModel { - - private LocalDiskThread worker = null; - private boolean ready = false; - private volatile boolean loadingDisks = false; - - //private String SELECT = "Select a local disk:"; - private final String LOADING = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.loading.msg"); - private final String NO_DRIVES = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.nodrives.msg"); - - private void loadDisks() { - - // if there is a worker already building the lists, then cancel it first. - if (loadingDisks && worker != null) { - worker.cancel(false); - } - - // Clear the lists - errorLabel.setText(""); - diskTable.setEnabled(false); - ready = false; - enableNext = false; - loadingDisks = true; - worker = new LocalDiskThread(); - worker.execute(); - } - - @Override - public int getRowCount() { - if (disks.isEmpty()) { - return 0; - } - return disks.size(); - } - - @Override - public int getColumnCount() { - return 2; - - } - - @NbBundle.Messages({"LocalDiskPanel.diskTable.column1.title=Disk Name", - "LocalDiskPanel.diskTable.column2.title=Disk Size" - }) - - @Override - public String getColumnName(int columnIndex) { - switch (columnIndex) { - case 0: - return NbBundle.getMessage(this.getClass(), "LocalDiskPanel.diskTable.column1.title"); - case 1: - return NbBundle.getMessage(this.getClass(), "LocalDiskPanel.diskTable.column2.title"); - default: - return "Unnamed"; //NON-NLS - } - } - - @Override - public Class getColumnClass(int columnIndex) { - return String.class; - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return false; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - if (ready) { - if (disks.isEmpty()) { - return NO_DRIVES; - } - switch (columnIndex) { - case 0: - return disks.get(rowIndex).getName(); - case 1: - return disks.get(rowIndex).getReadableSize(); - default: - return disks.get(rowIndex).getPath(); - } - } else { - return LOADING; - } - } - - @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - //setter does nothing they should not be able to modify table - } - - @Override - public void addTableModelListener(TableModelListener l) { - - } - - @Override - public void removeTableModelListener(TableModelListener l) { - - } - - /** - * Gets the lists of physical drives and partitions and combines them - * into a list of disks. - */ - class LocalDiskThread extends SwingWorker { - - private final Logger logger = Logger.getLogger(LocalDiskThread.class.getName()); - private List physicalDrives = new ArrayList<>(); - private List partitions = new ArrayList<>(); - - @Override - protected Object doInBackground() throws Exception { - // Populate the lists - physicalDrives = new ArrayList<>(); - partitions = new ArrayList<>(); - physicalDrives = PlatformUtil.getPhysicalDrives(); - partitions = PlatformUtil.getPartitions(); - return null; - } - - /** - * Display any error messages that might of occurred when getting - * the lists of physical drives or partitions. - */ - private void displayErrors() { - if (physicalDrives.isEmpty() && partitions.isEmpty()) { - if (PlatformUtil.isWindowsOS()) { - errorLabel.setText( - NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.disksNotDetected.text")); - errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(), - "LocalDiskPanel.errLabel.disksNotDetected.toolTipText")); - } else { - errorLabel.setText( - NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.drivesNotDetected.text")); - errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(), - "LocalDiskPanel.errLabel.drivesNotDetected.toolTipText")); - } - errorLabel.setVisible(true); - diskTable.setEnabled(false); - } else if (physicalDrives.isEmpty()) { - errorLabel.setText( - NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.someDisksNotDetected.text")); - errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(), - "LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText")); - errorLabel.setVisible(true); - } - } - - @Override - protected void done() { - try { - super.get(); //block and get all exceptions thrown while doInBackground() - } catch (CancellationException ex) { - logger.log(Level.INFO, "Loading local disks was canceled."); //NON-NLS - } catch (InterruptedException ex) { - logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS - } catch (Exception ex) { - logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS - } finally { - if (!this.isCancelled()) { - enableNext = false; - displayErrors(); - worker = null; - loadingDisks = false; - disks = new ArrayList<>(); - disks.addAll(physicalDrives); - disks.addAll(partitions); - if (disks.size() > 0) { - diskTable.setEnabled(true); - diskTable.clearSelection(); - } - pathTextField.setText(""); - fireUpdateEvent(); - ready = true; - } - } - diskTable.revalidate(); - } - } - } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskSelectionDialog.form b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskSelectionDialog.form new file mode 100755 index 0000000000..c3c3202705 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskSelectionDialog.form @@ -0,0 +1,150 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskSelectionDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskSelectionDialog.java new file mode 100755 index 0000000000..ed737e3672 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskSelectionDialog.java @@ -0,0 +1,434 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.awt.Window; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import javax.swing.JDialog; +import javax.swing.SwingWorker; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelListener; +import javax.swing.table.TableModel; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor; +import org.sleuthkit.autopsy.coreutils.LocalDisk; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; + +@NbBundle.Messages({ + "LocalDiskSelectionDialog.moduleErrorMessage.title=Module Error", + "LocalDiskSelectionDialog.moduleErrorMessage.body=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete.", + "LocalDiskSelectionDialog.errorMessage.disksNotDetected=Disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\").", + "LocalDiskSelectionDialog.errorMessage.drivesNotDetected=Local drives were not detected. Auto-detection not supported on this OS or admin privileges required", + "LocalDiskSelectionDialog.errorMessage.someDisksNotDetected=Some disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\")." +}) +/** + * Local disk selection dialog for loading a disk into the LocalDiskPanel. + */ +final class LocalDiskSelectionDialog extends JDialog { + + private static final Logger logger = Logger.getLogger(LocalDiskSelectionDialog.class.getName()); + private static final long serialVersionUID = 1L; + private List disks; + private final LocalDiskModel model; + + /** + * Creates a new LocalDiskSelectionDialog instance. + */ + LocalDiskSelectionDialog() { + super((Window) LocalDiskPanel.getDefault().getTopLevelAncestor(), ModalityType.MODELESS); + + this.model = new LocalDiskModel(); + this.disks = new ArrayList<>(); + + initComponents(); + refreshTable(); + + localDiskTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + int selectedRow = localDiskTable.getSelectedRow(); + okButton.setEnabled(selectedRow >= 0 && selectedRow < disks.size()); + } + }); + } + + /** + * Display the dialog. + */ + void display() { + setModal(true); + setSize(getPreferredSize()); + setLocationRelativeTo(this.getParent()); + setAlwaysOnTop(false); + setVisible(true); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + selectLocalDiskLabel = new javax.swing.JLabel(); + errorLabel = new javax.swing.JLabel(); + localDiskScrollPane = new javax.swing.JScrollPane(); + localDiskTable = new javax.swing.JTable(); + refreshLocalDisksButton = new javax.swing.JButton(); + okButton = new javax.swing.JButton(); + cancelButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.title")); // NOI18N + setAlwaysOnTop(true); + setResizable(false); + + selectLocalDiskLabel.setFont(selectLocalDiskLabel.getFont().deriveFont(selectLocalDiskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.selectLocalDiskLabel.text")); // NOI18N + + errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + errorLabel.setForeground(new java.awt.Color(255, 0, 0)); + org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.errorLabel.text")); // NOI18N + + localDiskTable.setModel(model); + localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + localDiskScrollPane.setViewportView(localDiskTable); + + org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.refreshLocalDisksButton.text")); // NOI18N + refreshLocalDisksButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + refreshLocalDisksButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.okButton.text")); // NOI18N + okButton.setEnabled(false); + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.cancelButton.text")); // NOI18N + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(refreshLocalDisksButton)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(selectLocalDiskLabel) + .addComponent(errorLabel)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(selectLocalDiskLabel) + .addGap(4, 4, 4) + .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(refreshLocalDisksButton) + .addComponent(okButton) + .addComponent(cancelButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(errorLabel) + .addContainerGap(27, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshLocalDisksButtonActionPerformed + refreshTable(); + }//GEN-LAST:event_refreshLocalDisksButtonActionPerformed + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + dispose(); + }//GEN-LAST:event_okButtonActionPerformed + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + localDiskTable.clearSelection(); + dispose(); + }//GEN-LAST:event_cancelButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton cancelButton; + private javax.swing.JLabel errorLabel; + private javax.swing.JScrollPane localDiskScrollPane; + private javax.swing.JTable localDiskTable; + private javax.swing.JButton okButton; + private javax.swing.JButton refreshLocalDisksButton; + private javax.swing.JLabel selectLocalDiskLabel; + // End of variables declaration//GEN-END:variables + + /** + * Fire a property change event to update the UI. + */ + private void fireUpdateEvent() { + try { + firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true); + } catch (Exception e) { + logger.log(Level.SEVERE, "LocalDiskSelectionDialog listener threw exception", e); //NON-NLS + MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(), + Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(), + MessageNotifyUtil.MessageType.ERROR); + } + } + + /** + * Return the currently selected disk path. + * + * @return String selected disk path + */ + String getContentPaths() { + LocalDisk selected = getLocalDiskSelection(); + if (selected != null) { + return selected.getPath(); + } + return ""; + } + + /** + * Refreshes the list of disks in the table. + */ + private void refreshTable() { + model.loadDisks(); + localDiskTable.clearSelection(); + } + + /** + * Get the local disk selected from the table. + * + * @return The LocalDisk object associated with the selection in the table. + */ + LocalDisk getLocalDiskSelection() { + if (disks.size() > 0) { + int selectedRow = localDiskTable.getSelectedRow(); + if (selectedRow >= 0 && selectedRow < disks.size()) { + return disks.get(selectedRow); + } + } + return null; + } + + @NbBundle.Messages({ + "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...", + "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives", + }) + /** + * Table model for displaing information from LocalDisk Objects in a table. + */ + private class LocalDiskModel implements TableModel { + + private LocalDiskThread worker = null; + private boolean ready = false; + private volatile boolean loadingDisks = false; + + private void loadDisks() { + + // if there is a worker already building the lists, then cancel it first. + if (loadingDisks && worker != null) { + worker.cancel(false); + } + + // Clear the lists + errorLabel.setText(""); + localDiskTable.setEnabled(false); + ready = false; + loadingDisks = true; + worker = new LocalDiskThread(); + worker.execute(); + } + + @Override + public int getRowCount() { + if (disks.isEmpty()) { + return 0; + } + return disks.size(); + } + + @Override + public int getColumnCount() { + return 2; + + } + + @NbBundle.Messages({ + "LocalDiskSelectionDialog.columnName.diskName=Disk Name", + "LocalDiskSelectionDialog.columnName.diskSize=Disk Size" + }) + + @Override + public String getColumnName(int columnIndex) { + switch (columnIndex) { + case 0: + return Bundle.LocalDiskSelectionDialog_columnName_diskName(); + case 1: + return Bundle.LocalDiskSelectionDialog_columnName_diskSize(); + default: + return "Unnamed"; //NON-NLS + } + } + + @Override + public Class getColumnClass(int columnIndex) { + return String.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (ready) { + if (disks.isEmpty()) { + return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives(); + } + switch (columnIndex) { + case 0: + return disks.get(rowIndex).getName(); + case 1: + return disks.get(rowIndex).getReadableSize(); + default: + return disks.get(rowIndex).getPath(); + } + } else { + return Bundle.LocalDiskSelectionDialog_tableMessage_loading(); + } + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + //setter does nothing they should not be able to modify table + } + + @Override + public void addTableModelListener(TableModelListener l) { + + } + + @Override + public void removeTableModelListener(TableModelListener l) { + + } + + /** + * Gets the lists of physical drives and partitions and combines them + * into a list of disks. + */ + class LocalDiskThread extends SwingWorker { + + private final Logger logger = Logger.getLogger(LocalDiskThread.class.getName()); + private List physicalDrives = new ArrayList<>(); + private List partitions = new ArrayList<>(); + + @Override + protected Object doInBackground() throws Exception { + // Populate the lists + physicalDrives = new ArrayList<>(); + partitions = new ArrayList<>(); + physicalDrives = PlatformUtil.getPhysicalDrives(); + partitions = PlatformUtil.getPartitions(); + return null; + } + + /** + * Display any error messages that might of occurred when getting + * the lists of physical drives or partitions. + */ + private void displayErrors() { + if (physicalDrives.isEmpty() && partitions.isEmpty()) { + if (PlatformUtil.isWindowsOS()) { + errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected()); + errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected()); + } else { + errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected()); + errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected()); + } + errorLabel.setVisible(true); + localDiskTable.setEnabled(false); + } else if (physicalDrives.isEmpty()) { + errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected()); + errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected()); + errorLabel.setVisible(true); + } + } + + @Override + protected void done() { + try { + super.get(); //block and get all exceptions thrown while doInBackground() + } catch (CancellationException ex) { + logger.log(Level.INFO, "Loading local disks was canceled."); //NON-NLS + } catch (InterruptedException ex) { + logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS + } catch (ExecutionException ex) { + logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS + } finally { + if (!this.isCancelled()) { + displayErrors(); + worker = null; + loadingDisks = false; + disks = new ArrayList<>(); + disks.addAll(physicalDrives); + disks.addAll(partitions); + if (disks.size() > 0) { + localDiskTable.setEnabled(true); + localDiskTable.clearSelection(); + } + fireUpdateEvent(); + ready = true; + } + } + localDiskTable.revalidate(); + } + } + } +}