19 package org.sleuthkit.autopsy.casemodule;
21 import java.awt.BorderLayout;
22 import java.awt.Color;
23 import java.awt.Component;
25 import java.beans.PropertyChangeListener;
26 import java.beans.PropertyChangeSupport;
27 import java.util.ArrayList;
28 import java.util.Calendar;
29 import java.util.List;
30 import java.util.SimpleTimeZone;
31 import java.util.TimeZone;
32 import java.util.concurrent.CancellationException;
33 import java.util.logging.Level;
34 import javax.swing.ComboBoxModel;
35 import javax.swing.JLabel;
36 import javax.swing.JList;
37 import javax.swing.JPanel;
38 import javax.swing.JSeparator;
39 import javax.swing.ListCellRenderer;
40 import javax.swing.SwingWorker;
41 import javax.swing.border.EmptyBorder;
42 import javax.swing.event.ListDataListener;
43 import org.openide.util.NbBundle;
54 final class LocalDiskPanel
extends JPanel {
56 private static final Logger logger = Logger.getLogger(LocalDiskPanel.class.getName());
58 private static LocalDiskPanel instance;
60 private PropertyChangeSupport pcs = null;
62 private List<LocalDisk> disks;
64 private LocalDiskModel model;
66 private boolean enableNext =
false;
71 public LocalDiskPanel() {
72 this.disks =
new ArrayList<>();
83 public static synchronized LocalDiskPanel getDefault() {
84 if (instance == null) {
85 instance =
new LocalDiskPanel();
90 @SuppressWarnings(
"unchecked")
91 private
void customInit() {
92 model =
new LocalDiskModel();
93 diskComboBox.setModel(model);
94 diskComboBox.setRenderer(model);
96 errorLabel.setVisible(
false);
97 errorLabel.setText(
"");
98 diskComboBox.setEnabled(
false);
106 @SuppressWarnings(
"unchecked")
108 private
void initComponents() {
110 diskLabel =
new javax.swing.JLabel();
111 diskComboBox =
new javax.swing.JComboBox<>();
112 errorLabel =
new javax.swing.JLabel();
113 timeZoneLabel =
new javax.swing.JLabel();
114 timeZoneComboBox =
new javax.swing.JComboBox<>();
115 noFatOrphansCheckbox =
new javax.swing.JCheckBox();
116 descLabel =
new javax.swing.JLabel();
118 setMinimumSize(
new java.awt.Dimension(0, 65));
119 setPreferredSize(
new java.awt.Dimension(485, 65));
121 diskLabel.setFont(diskLabel.getFont().deriveFont(diskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
122 org.openide.awt.Mnemonics.setLocalizedText(diskLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.diskLabel.text"));
124 diskComboBox.setFont(diskComboBox.getFont().deriveFont(diskComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
126 errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
127 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
128 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.errorLabel.text"));
130 timeZoneLabel.setFont(timeZoneLabel.getFont().deriveFont(timeZoneLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
131 org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.timeZoneLabel.text"));
133 timeZoneComboBox.setFont(timeZoneComboBox.getFont().deriveFont(timeZoneComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
134 timeZoneComboBox.setMaximumRowCount(30);
136 noFatOrphansCheckbox.setFont(noFatOrphansCheckbox.getFont().deriveFont(noFatOrphansCheckbox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
137 org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.noFatOrphansCheckbox.text"));
138 noFatOrphansCheckbox.setToolTipText(
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.noFatOrphansCheckbox.toolTipText"));
140 descLabel.setFont(descLabel.getFont().deriveFont(descLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
141 org.openide.awt.Mnemonics.setLocalizedText(descLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.descLabel.text"));
143 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
144 this.setLayout(layout);
145 layout.setHorizontalGroup(
146 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
147 .addGroup(layout.createSequentialGroup()
148 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
149 .addComponent(diskLabel)
150 .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE)
151 .addComponent(errorLabel)
152 .addGroup(layout.createSequentialGroup()
153 .addComponent(timeZoneLabel)
154 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
155 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
156 .addComponent(noFatOrphansCheckbox)
157 .addGroup(layout.createSequentialGroup()
159 .addComponent(descLabel)))
160 .addGap(0, 102, Short.MAX_VALUE))
162 layout.setVerticalGroup(
163 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
164 .addGroup(layout.createSequentialGroup()
165 .addComponent(diskLabel)
166 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
167 .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
169 .addComponent(errorLabel)
170 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
171 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
172 .addComponent(timeZoneLabel)
173 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
175 .addComponent(noFatOrphansCheckbox)
176 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
177 .addComponent(descLabel)
178 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
182 private javax.swing.JLabel descLabel;
183 private javax.swing.JComboBox<LocalDisk> diskComboBox;
184 private javax.swing.JLabel diskLabel;
185 private javax.swing.JLabel errorLabel;
186 private javax.swing.JCheckBox noFatOrphansCheckbox;
187 private javax.swing.JComboBox<String> timeZoneComboBox;
188 private javax.swing.JLabel timeZoneLabel;
197 public String getContentPaths() {
198 if (disks.size() > 0) {
199 LocalDisk selected = (LocalDisk) diskComboBox.getSelectedItem();
200 return selected.getPath();
210 public void setContentPath(String s) {
211 for (
int i = 0; i < disks.size(); i++) {
212 if (disks.get(i).getPath().equals(s)) {
213 diskComboBox.setSelectedIndex(i);
218 public String getTimeZone() {
219 String tz = timeZoneComboBox.getSelectedItem().toString();
220 return tz.substring(tz.indexOf(
")") + 2).trim();
224 boolean getNoFatOrphans() {
225 return noFatOrphansCheckbox.isSelected();
235 public boolean validatePanel() {
240 public void reset() {
249 public void select() {
250 diskComboBox.requestFocusInWindow();
256 public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
257 super.addPropertyChangeListener(pcl);
260 pcs =
new PropertyChangeSupport(
this);
263 pcs.addPropertyChangeListener(pcl);
267 public void removePropertyChangeListener(PropertyChangeListener pcl) {
268 super.removePropertyChangeListener(pcl);
270 pcs.removePropertyChangeListener(pcl);
277 public void createTimeZoneList() {
279 String[] ids = SimpleTimeZone.getAvailableIDs();
280 for (String
id : ids) {
281 TimeZone zone = TimeZone.getTimeZone(
id);
282 int offset = zone.getRawOffset() / 1000;
283 int hour = offset / 3600;
284 int minutes = (offset % 3600) / 60;
285 String item = String.format(
"(GMT%+d:%02d) %s", hour, minutes,
id);
296 timeZoneComboBox.addItem(item);
299 TimeZone thisTimeZone = Calendar.getInstance().getTimeZone();
300 int thisOffset = thisTimeZone.getRawOffset() / 1000;
301 int thisHour = thisOffset / 3600;
302 int thisMinutes = (thisOffset % 3600) / 60;
303 String formatted = String.format(
"(GMT%+d:%02d) %s", thisHour, thisMinutes, thisTimeZone.getID());
306 timeZoneComboBox.setSelectedItem(formatted);
309 @SuppressWarnings(
"rawtypes")
314 private boolean ready =
false;
316 private volatile boolean loadingDisks =
false;
318 List<LocalDisk> physicalDrives =
new ArrayList<>();
319 List<LocalDisk> partitions =
new ArrayList<>();
322 private String LOADING = NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.localDiskModel.loading.msg");
323 private String NO_DRIVES = NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.localDiskModel.nodrives.msg");
325 LocalDiskThread worker = null;
330 if (loadingDisks && worker != null) {
331 worker.cancel(
false);
335 errorLabel.setText(
"");
336 disks =
new ArrayList<>();
337 physicalDrives =
new ArrayList<>();
338 partitions =
new ArrayList<>();
339 diskComboBox.setEnabled(
false);
344 worker =
new LocalDiskThread();
357 }
catch (Exception e) {
358 logger.log(Level.SEVERE,
"LocalDiskPanel listener threw exception", e);
360 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.moduleErr.msg"),
369 if (disks.isEmpty()) {
381 if (disks.isEmpty()) {
393 if (disks.isEmpty()) {
396 return disks.get(index);
410 @SuppressWarnings(
"rawtypes")
413 JPanel panel =
new JPanel(
new BorderLayout());
414 JLabel label =
new JLabel();
415 if ((index == physicalDrives.size() - 1) && (physicalDrives.size() > 0)) {
416 panel.add(
new JSeparator(JSeparator.HORIZONTAL), BorderLayout.SOUTH);
420 label.setBackground(list.getSelectionBackground());
421 label.setForeground(list.getSelectionForeground());
423 label.setBackground(list.getBackground());
424 label.setForeground(list.getForeground());
428 String localDiskString = value.toString();
429 label.setText(value.toString());
430 if ((localDiskString.equals(LOADING)) || (localDiskString.equals(NO_DRIVES))) {
431 label.setFont(label.getFont().deriveFont(Font.ITALIC));
432 label.setBackground(Color.GRAY);
435 label.setOpaque(
true);
436 label.setBorder(
new EmptyBorder(2, 2, 2, 2));
438 panel.add(label, BorderLayout.CENTER);
442 class LocalDiskThread
extends SwingWorker<Object, Void> {
447 protected Object doInBackground() throws Exception {
455 private void displayErrors() {
456 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
459 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.disksNotDetected.text"));
460 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
461 "LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
464 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.drivesNotDetected.text"));
465 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
466 "LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
468 diskComboBox.setEnabled(
false);
469 }
else if (physicalDrives.isEmpty()) {
471 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.someDisksNotDetected.text"));
472 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
473 "LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
478 protected void done() {
481 }
catch (CancellationException ex) {
482 logger.log(Level.INFO,
"Loading local disks was canceled, which should not be possible.");
483 }
catch (InterruptedException ex) {
484 logger.log(Level.INFO,
"Loading local disks was interrupted.");
485 }
catch (Exception ex) {
486 logger.log(Level.SEVERE,
"Fatal error when loading local disks", ex);
488 if (!this.isCancelled()) {
493 loadingDisks =
false;
495 disks.addAll(physicalDrives);
496 disks.addAll(partitions);
498 if (disks.size() > 0) {
499 diskComboBox.setEnabled(
true);
500 diskComboBox.setSelectedIndex(0);
504 logger.log(Level.INFO,
"Loading local disks was canceled, which should not be possible.");
void setSelectedItem(Object anItem)
void addListDataListener(ListDataListener l)
Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
Object getElementAt(int index)
synchronized static Logger getLogger(String name)
static void show(String title, String message, MessageType type, ActionListener actionListener)
void removeListDataListener(ListDataListener l)