19 package org.sleuthkit.autopsy.casemodule;
21 import java.awt.BorderLayout;
22 import java.awt.Color;
23 import java.awt.Component;
25 import java.util.ArrayList;
26 import java.util.Calendar;
27 import java.util.List;
28 import java.util.SimpleTimeZone;
29 import java.util.TimeZone;
30 import java.util.concurrent.CancellationException;
31 import java.util.logging.Level;
32 import javax.swing.ComboBoxModel;
33 import javax.swing.JLabel;
34 import javax.swing.JList;
35 import javax.swing.JPanel;
36 import javax.swing.JSeparator;
37 import javax.swing.ListCellRenderer;
38 import javax.swing.SwingWorker;
39 import javax.swing.border.EmptyBorder;
40 import javax.swing.event.ListDataListener;
41 import org.openide.util.NbBundle;
52 final class LocalDiskPanel
extends JPanel {
54 private static final Logger logger = Logger.getLogger(LocalDiskPanel.class.getName());
55 private static LocalDiskPanel instance;
56 private static final long serialVersionUID = 1L;
57 private List<LocalDisk> disks;
58 private LocalDiskModel model;
59 private boolean enableNext =
false;
64 public LocalDiskPanel() {
65 this.disks =
new ArrayList<>();
75 public static synchronized LocalDiskPanel getDefault() {
76 if (instance == null) {
77 instance =
new LocalDiskPanel();
82 @SuppressWarnings(
"unchecked")
83 private
void customInit() {
84 model =
new LocalDiskModel();
85 diskComboBox.setModel(model);
86 diskComboBox.setRenderer(model);
88 errorLabel.setVisible(
false);
89 errorLabel.setText(
"");
90 diskComboBox.setEnabled(
false);
98 @SuppressWarnings(
"unchecked")
100 private
void initComponents() {
102 diskLabel =
new javax.swing.JLabel();
103 diskComboBox =
new javax.swing.JComboBox<>();
104 errorLabel =
new javax.swing.JLabel();
105 timeZoneLabel =
new javax.swing.JLabel();
106 timeZoneComboBox =
new javax.swing.JComboBox<>();
107 noFatOrphansCheckbox =
new javax.swing.JCheckBox();
108 descLabel =
new javax.swing.JLabel();
110 setMinimumSize(
new java.awt.Dimension(0, 65));
111 setPreferredSize(
new java.awt.Dimension(485, 65));
113 diskLabel.setFont(diskLabel.getFont().deriveFont(diskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
114 org.openide.awt.Mnemonics.setLocalizedText(diskLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.diskLabel.text"));
116 diskComboBox.setFont(diskComboBox.getFont().deriveFont(diskComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
118 errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
119 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
120 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.errorLabel.text"));
122 timeZoneLabel.setFont(timeZoneLabel.getFont().deriveFont(timeZoneLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
123 org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.timeZoneLabel.text"));
125 timeZoneComboBox.setFont(timeZoneComboBox.getFont().deriveFont(timeZoneComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
126 timeZoneComboBox.setMaximumRowCount(30);
128 noFatOrphansCheckbox.setFont(noFatOrphansCheckbox.getFont().deriveFont(noFatOrphansCheckbox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
129 org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.noFatOrphansCheckbox.text"));
130 noFatOrphansCheckbox.setToolTipText(
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.noFatOrphansCheckbox.toolTipText"));
132 descLabel.setFont(descLabel.getFont().deriveFont(descLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
133 org.openide.awt.Mnemonics.setLocalizedText(descLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.descLabel.text"));
135 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
136 this.setLayout(layout);
137 layout.setHorizontalGroup(
138 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
139 .addGroup(layout.createSequentialGroup()
140 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
141 .addComponent(diskLabel)
142 .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE)
143 .addComponent(errorLabel)
144 .addGroup(layout.createSequentialGroup()
145 .addComponent(timeZoneLabel)
146 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
147 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
148 .addComponent(noFatOrphansCheckbox)
149 .addGroup(layout.createSequentialGroup()
151 .addComponent(descLabel)))
152 .addGap(0, 102, Short.MAX_VALUE))
154 layout.setVerticalGroup(
155 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
156 .addGroup(layout.createSequentialGroup()
157 .addComponent(diskLabel)
158 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
159 .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
161 .addComponent(errorLabel)
162 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
163 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
164 .addComponent(timeZoneLabel)
165 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
167 .addComponent(noFatOrphansCheckbox)
168 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
169 .addComponent(descLabel)
170 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
174 private javax.swing.JLabel descLabel;
175 private javax.swing.JComboBox<LocalDisk> diskComboBox;
176 private javax.swing.JLabel diskLabel;
177 private javax.swing.JLabel errorLabel;
178 private javax.swing.JCheckBox noFatOrphansCheckbox;
179 private javax.swing.JComboBox<String> timeZoneComboBox;
180 private javax.swing.JLabel timeZoneLabel;
188 public String getContentPaths() {
189 if (disks.size() > 0) {
190 LocalDisk selected = (LocalDisk) diskComboBox.getSelectedItem();
191 return selected.getPath();
200 public void setContentPath(String s) {
201 for (
int i = 0; i < disks.size(); i++) {
202 if (disks.get(i).getPath().equals(s)) {
203 diskComboBox.setSelectedIndex(i);
208 public String getTimeZone() {
209 String tz = timeZoneComboBox.getSelectedItem().toString();
210 return tz.substring(tz.indexOf(
")") + 2).trim();
214 boolean getNoFatOrphans() {
215 return noFatOrphansCheckbox.isSelected();
224 public boolean validatePanel() {
228 public void reset() {
235 public void select() {
236 diskComboBox.requestFocusInWindow();
244 public void createTimeZoneList() {
246 String[] ids = SimpleTimeZone.getAvailableIDs();
247 for (String
id : ids) {
248 TimeZone zone = TimeZone.getTimeZone(
id);
249 int offset = zone.getRawOffset() / 1000;
250 int hour = offset / 3600;
251 int minutes = (offset % 3600) / 60;
252 String item = String.format(
"(GMT%+d:%02d) %s", hour, minutes,
id);
263 timeZoneComboBox.addItem(item);
266 TimeZone thisTimeZone = Calendar.getInstance().getTimeZone();
267 int thisOffset = thisTimeZone.getRawOffset() / 1000;
268 int thisHour = thisOffset / 3600;
269 int thisMinutes = (thisOffset % 3600) / 60;
270 String formatted = String.format(
"(GMT%+d:%02d) %s", thisHour, thisMinutes, thisTimeZone.getID());
273 timeZoneComboBox.setSelectedItem(formatted);
276 @SuppressWarnings(
"rawtypes")
281 private boolean ready =
false;
283 private volatile boolean loadingDisks =
false;
285 List<LocalDisk> physicalDrives =
new ArrayList<>();
286 List<LocalDisk> partitions =
new ArrayList<>();
289 private final String LOADING = NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.localDiskModel.loading.msg");
290 private final String NO_DRIVES = NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.localDiskModel.nodrives.msg");
292 LocalDiskThread worker = null;
297 if (loadingDisks && worker != null) {
298 worker.cancel(
false);
302 errorLabel.setText(
"");
303 disks =
new ArrayList<>();
304 physicalDrives =
new ArrayList<>();
305 partitions =
new ArrayList<>();
306 diskComboBox.setEnabled(
false);
311 worker =
new LocalDiskThread();
324 }
catch (Exception e) {
325 logger.log(Level.SEVERE,
"LocalDiskPanel listener threw exception", e);
327 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.moduleErr.msg"),
336 if (disks.isEmpty()) {
348 if (disks.isEmpty()) {
360 if (disks.isEmpty()) {
363 return disks.get(index);
377 @SuppressWarnings(
"rawtypes")
380 JPanel panel =
new JPanel(
new BorderLayout());
381 JLabel label =
new JLabel();
382 if ((index == physicalDrives.size() - 1) && (physicalDrives.size() > 0)) {
383 panel.add(
new JSeparator(JSeparator.HORIZONTAL), BorderLayout.SOUTH);
387 label.setBackground(list.getSelectionBackground());
388 label.setForeground(list.getSelectionForeground());
390 label.setBackground(list.getBackground());
391 label.setForeground(list.getForeground());
395 String localDiskString = value.toString();
396 label.setText(value.toString());
397 if ((localDiskString.equals(LOADING)) || (localDiskString.equals(NO_DRIVES))) {
398 label.setFont(label.getFont().deriveFont(Font.ITALIC));
399 label.setBackground(Color.GRAY);
402 label.setOpaque(
true);
403 label.setBorder(
new EmptyBorder(2, 2, 2, 2));
405 panel.add(label, BorderLayout.CENTER);
409 class LocalDiskThread
extends SwingWorker<Object, Void> {
414 protected Object doInBackground() throws Exception {
422 private void displayErrors() {
423 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
426 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.disksNotDetected.text"));
427 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
428 "LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
431 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.drivesNotDetected.text"));
432 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
433 "LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
435 diskComboBox.setEnabled(
false);
436 }
else if (physicalDrives.isEmpty()) {
438 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.someDisksNotDetected.text"));
439 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
440 "LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
445 protected void done() {
448 }
catch (CancellationException ex) {
449 logger.log(Level.INFO,
"Loading local disks was canceled, which should not be possible.");
450 }
catch (InterruptedException ex) {
451 logger.log(Level.INFO,
"Loading local disks was interrupted.");
452 }
catch (Exception ex) {
453 logger.log(Level.SEVERE,
"Fatal error when loading local disks", ex);
455 if (!this.isCancelled()) {
460 loadingDisks =
false;
462 disks.addAll(physicalDrives);
463 disks.addAll(partitions);
465 if (disks.size() > 0) {
466 diskComboBox.setEnabled(
true);
467 diskComboBox.setSelectedIndex(0);
471 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)