19 package org.sleuthkit.autopsy.casemodule;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.List;
25 import javax.swing.JFileChooser;
26 import org.openide.util.NbBundle;
29 import java.util.logging.Level;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32 import javax.swing.AbstractListModel;
33 import javax.swing.JOptionPane;
40 @SuppressWarnings(
"PMD.SingularField")
41 final class LocalFilesPanel extends javax.swing.JPanel {
43 private static final long serialVersionUID = 1L;
45 private boolean enableNext =
false;
46 private static final Logger logger = Logger.getLogger(LocalFilesPanel.class.getName());
47 private String displayName =
"";
48 private final LocalFilesModel listModel =
new LocalFilesModel();
58 private void customInit() {
59 localFileChooser.setMultiSelectionEnabled(
true);
60 errorLabel.setVisible(
false);
61 this.fileList.setModel(listModel);
63 this.displayNameLabel.setText(NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.displayNameLabel.text"));
71 @SuppressWarnings(
"unchecked")
73 private
void initComponents() {
74 java.awt.GridBagConstraints gridBagConstraints;
76 localFileChooser =
new javax.swing.JFileChooser();
77 selectButton =
new javax.swing.JButton();
78 deleteButon =
new javax.swing.JButton();
79 clearButton =
new javax.swing.JButton();
80 javax.swing.JScrollPane fileListScrollpane =
new javax.swing.JScrollPane();
81 fileList =
new javax.swing.JList<>();
82 javax.swing.JPanel displayNamePanel =
new javax.swing.JPanel();
83 changeNameButton =
new javax.swing.JButton();
84 displayNameLabel =
new javax.swing.JLabel();
85 javax.swing.JPanel padding =
new javax.swing.JPanel();
86 javax.swing.JLabel timeStampToIncludeLabel =
new javax.swing.JLabel();
87 modifiedTimeCheckBox =
new javax.swing.JCheckBox();
88 createTimeCheckBox =
new javax.swing.JCheckBox();
89 accessTimeCheckBox =
new javax.swing.JCheckBox();
90 javax.swing.JLabel timeStampNoteLabel =
new javax.swing.JLabel();
91 errorLabel =
new javax.swing.JLabel();
92 javax.swing.JPanel paddingBottom =
new javax.swing.JPanel();
94 localFileChooser.setApproveButtonText(
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.localFileChooser.approveButtonText"));
95 localFileChooser.setApproveButtonToolTipText(
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.localFileChooser.approveButtonToolTipText"));
96 localFileChooser.setDialogTitle(
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.localFileChooser.dialogTitle"));
97 localFileChooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_AND_DIRECTORIES);
99 setLayout(
new java.awt.GridBagLayout());
101 org.openide.awt.Mnemonics.setLocalizedText(selectButton,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.selectButton.text"));
102 selectButton.setToolTipText(
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.selectButton.toolTipText"));
103 selectButton.setActionCommand(
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.selectButton.actionCommand"));
104 selectButton.setMaximumSize(
new java.awt.Dimension(70, 23));
105 selectButton.setMinimumSize(
new java.awt.Dimension(70, 23));
106 selectButton.setPreferredSize(
new java.awt.Dimension(70, 23));
107 selectButton.addActionListener(
new java.awt.event.ActionListener() {
108 public void actionPerformed(java.awt.event.ActionEvent evt) {
109 selectButtonActionPerformed(evt);
112 gridBagConstraints =
new java.awt.GridBagConstraints();
113 gridBagConstraints.gridx = 1;
114 gridBagConstraints.gridy = 0;
115 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
116 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
117 gridBagConstraints.insets =
new java.awt.Insets(5, 5, 5, 5);
118 add(selectButton, gridBagConstraints);
120 org.openide.awt.Mnemonics.setLocalizedText(deleteButon,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.deleteButon.text"));
121 deleteButon.setMaximumSize(
new java.awt.Dimension(70, 23));
122 deleteButon.setMinimumSize(
new java.awt.Dimension(70, 23));
123 deleteButon.addActionListener(
new java.awt.event.ActionListener() {
124 public void actionPerformed(java.awt.event.ActionEvent evt) {
125 deleteButonActionPerformed(evt);
128 gridBagConstraints =
new java.awt.GridBagConstraints();
129 gridBagConstraints.gridx = 1;
130 gridBagConstraints.gridy = 1;
131 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
132 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
133 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 5, 5);
134 add(deleteButon, gridBagConstraints);
136 org.openide.awt.Mnemonics.setLocalizedText(clearButton,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.clearButton.text"));
137 clearButton.setToolTipText(
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.clearButton.toolTipText"));
138 clearButton.setMaximumSize(
new java.awt.Dimension(70, 23));
139 clearButton.setMinimumSize(
new java.awt.Dimension(70, 23));
140 clearButton.setPreferredSize(
new java.awt.Dimension(70, 23));
141 clearButton.addActionListener(
new java.awt.event.ActionListener() {
142 public void actionPerformed(java.awt.event.ActionEvent evt) {
143 clearButtonActionPerformed(evt);
146 gridBagConstraints =
new java.awt.GridBagConstraints();
147 gridBagConstraints.gridx = 1;
148 gridBagConstraints.gridy = 2;
149 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
150 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
151 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 5, 5);
152 add(clearButton, gridBagConstraints);
154 fileListScrollpane.setMaximumSize(
new java.awt.Dimension(32767, 100));
155 fileListScrollpane.setMinimumSize(
new java.awt.Dimension(100, 100));
156 fileListScrollpane.setPreferredSize(
new java.awt.Dimension(258, 100));
158 fileListScrollpane.setViewportView(fileList);
160 gridBagConstraints =
new java.awt.GridBagConstraints();
161 gridBagConstraints.gridx = 0;
162 gridBagConstraints.gridy = 0;
163 gridBagConstraints.gridheight = 3;
164 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
165 gridBagConstraints.weightx = 1.0;
166 gridBagConstraints.insets =
new java.awt.Insets(5, 5, 5, 0);
167 add(fileListScrollpane, gridBagConstraints);
169 displayNamePanel.setLayout(
new java.awt.GridBagLayout());
171 org.openide.awt.Mnemonics.setLocalizedText(changeNameButton,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.changeNameButton.text"));
172 changeNameButton.addActionListener(
new java.awt.event.ActionListener() {
173 public void actionPerformed(java.awt.event.ActionEvent evt) {
174 changeNameButtonActionPerformed(evt);
177 gridBagConstraints =
new java.awt.GridBagConstraints();
178 gridBagConstraints.gridx = 1;
179 gridBagConstraints.gridy = 0;
180 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
181 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
182 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 0, 0);
183 displayNamePanel.add(changeNameButton, gridBagConstraints);
185 org.openide.awt.Mnemonics.setLocalizedText(displayNameLabel,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.displayNameLabel.text"));
186 gridBagConstraints =
new java.awt.GridBagConstraints();
187 gridBagConstraints.gridx = 0;
188 gridBagConstraints.gridy = 0;
189 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
190 displayNamePanel.add(displayNameLabel, gridBagConstraints);
192 padding.setMinimumSize(
new java.awt.Dimension(0, 0));
193 padding.setPreferredSize(
new java.awt.Dimension(0, 0));
195 javax.swing.GroupLayout paddingLayout =
new javax.swing.GroupLayout(padding);
196 padding.setLayout(paddingLayout);
197 paddingLayout.setHorizontalGroup(
198 paddingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
199 .addGap(0, 0, Short.MAX_VALUE)
201 paddingLayout.setVerticalGroup(
202 paddingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
203 .addGap(0, 0, Short.MAX_VALUE)
206 gridBagConstraints =
new java.awt.GridBagConstraints();
207 gridBagConstraints.gridx = 2;
208 gridBagConstraints.gridy = 0;
209 gridBagConstraints.weightx = 1.0;
210 displayNamePanel.add(padding, gridBagConstraints);
212 gridBagConstraints =
new java.awt.GridBagConstraints();
213 gridBagConstraints.gridx = 0;
214 gridBagConstraints.gridy = 3;
215 gridBagConstraints.gridwidth = 2;
216 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
217 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
218 gridBagConstraints.weightx = 1.0;
219 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 5, 5);
220 add(displayNamePanel, gridBagConstraints);
222 org.openide.awt.Mnemonics.setLocalizedText(timeStampToIncludeLabel,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.timeStampToIncludeLabel.text"));
223 gridBagConstraints =
new java.awt.GridBagConstraints();
224 gridBagConstraints.gridx = 0;
225 gridBagConstraints.gridy = 4;
226 gridBagConstraints.gridwidth = 2;
227 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
228 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 5, 5);
229 add(timeStampToIncludeLabel, gridBagConstraints);
231 org.openide.awt.Mnemonics.setLocalizedText(modifiedTimeCheckBox,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.modifiedTimeCheckBox.text"));
232 gridBagConstraints =
new java.awt.GridBagConstraints();
233 gridBagConstraints.gridx = 0;
234 gridBagConstraints.gridy = 5;
235 gridBagConstraints.gridwidth = 2;
236 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
237 gridBagConstraints.insets =
new java.awt.Insets(0, 15, 5, 5);
238 add(modifiedTimeCheckBox, gridBagConstraints);
240 org.openide.awt.Mnemonics.setLocalizedText(createTimeCheckBox,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.createTimeCheckBox.text"));
241 gridBagConstraints =
new java.awt.GridBagConstraints();
242 gridBagConstraints.gridx = 0;
243 gridBagConstraints.gridy = 6;
244 gridBagConstraints.gridwidth = 2;
245 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
246 gridBagConstraints.insets =
new java.awt.Insets(0, 15, 5, 5);
247 add(createTimeCheckBox, gridBagConstraints);
249 org.openide.awt.Mnemonics.setLocalizedText(accessTimeCheckBox,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.accessTimeCheckBox.text"));
250 gridBagConstraints =
new java.awt.GridBagConstraints();
251 gridBagConstraints.gridx = 0;
252 gridBagConstraints.gridy = 7;
253 gridBagConstraints.gridwidth = 2;
254 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
255 gridBagConstraints.insets =
new java.awt.Insets(0, 15, 5, 5);
256 add(accessTimeCheckBox, gridBagConstraints);
258 org.openide.awt.Mnemonics.setLocalizedText(timeStampNoteLabel,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.timeStampNoteLabel.text"));
259 gridBagConstraints =
new java.awt.GridBagConstraints();
260 gridBagConstraints.gridx = 0;
261 gridBagConstraints.gridy = 8;
262 gridBagConstraints.gridwidth = 2;
263 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
264 gridBagConstraints.insets =
new java.awt.Insets(10, 5, 5, 5);
265 add(timeStampNoteLabel, gridBagConstraints);
267 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
268 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(LocalFilesPanel.class,
"LocalFilesPanel.errorLabel.text"));
269 gridBagConstraints =
new java.awt.GridBagConstraints();
270 gridBagConstraints.gridx = 0;
271 gridBagConstraints.gridy = 9;
272 gridBagConstraints.gridwidth = 2;
273 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
274 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
275 gridBagConstraints.weightx = 1.0;
276 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 5, 5);
277 add(errorLabel, gridBagConstraints);
279 paddingBottom.setMinimumSize(
new java.awt.Dimension(0, 0));
281 javax.swing.GroupLayout paddingBottomLayout =
new javax.swing.GroupLayout(paddingBottom);
282 paddingBottom.setLayout(paddingBottomLayout);
283 paddingBottomLayout.setHorizontalGroup(
284 paddingBottomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
285 .addGap(0, 0, Short.MAX_VALUE)
287 paddingBottomLayout.setVerticalGroup(
288 paddingBottomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
289 .addGap(0, 0, Short.MAX_VALUE)
292 gridBagConstraints =
new java.awt.GridBagConstraints();
293 gridBagConstraints.gridx = 0;
294 gridBagConstraints.gridy = 10;
295 gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
296 gridBagConstraints.weighty = 1.0;
297 add(paddingBottom, gridBagConstraints);
300 private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {
301 int returnVal = localFileChooser.showOpenDialog(
this);
303 if (returnVal == JFileChooser.APPROVE_OPTION) {
304 File[] files = localFileChooser.getSelectedFiles();
305 this.listModel.add(files);
308 enableNext = !this.listModel.getFiles().isEmpty();
311 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
312 }
catch (Exception e) {
313 logger.log(Level.SEVERE,
"LocalFilesPanel listener threw exception", e);
314 MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.moduleErr"),
315 NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.moduleErr.msg"),
316 MessageNotifyUtil.MessageType.ERROR);
320 private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {
324 private void changeNameButtonActionPerformed(java.awt.event.ActionEvent evt) {
325 final String selectedDisplayName = JOptionPane.showInputDialog(
"New Display Name: ");
326 if (selectedDisplayName != null && !selectedDisplayName.isEmpty()) {
327 this.displayName = selectedDisplayName;
328 this.displayNameLabel.setText(
"Display Name: " + this.displayName);
332 private void deleteButonActionPerformed(java.awt.event.ActionEvent evt) {
333 int minIdx = this.fileList.getMinSelectionIndex();
334 int maxIdx = this.fileList.getMaxSelectionIndex();
336 if (minIdx >= 0 && maxIdx >= minIdx) {
337 this.listModel.remove(minIdx, maxIdx);
339 this.fileList.clearSelection();
341 enableNext = !this.listModel.getFiles().isEmpty();
344 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
345 }
catch (Exception e) {
346 logger.log(Level.SEVERE,
"LocalFilesPanel listener threw exception", e);
347 MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.moduleErr"),
348 NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.moduleErr.msg"),
349 MessageNotifyUtil.MessageType.ERROR);
357 this.listModel.clear();
359 errorLabel.setVisible(
false);
361 this.displayNameLabel.setText(NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.displayNameLabel.text"));
363 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
364 }
catch (Exception e) {
365 logger.log(Level.SEVERE,
"LocalFilesPanel listener threw exception", e);
366 MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.moduleErr"),
367 NbBundle.getMessage(
this.getClass(),
"LocalFilesPanel.moduleErr.msg"),
368 MessageNotifyUtil.MessageType.ERROR);
378 List<String> getContentPaths() {
379 return this.listModel.getFiles().stream()
380 .map(File::getAbsolutePath)
381 .collect(Collectors.toList());
389 Boolean getCreateTimestamps() {
390 return createTimeCheckBox.isSelected();
398 Boolean getModifiedTimestamps() {
399 return modifiedTimeCheckBox.isSelected();
407 Boolean getAccessTimestamps() {
408 return accessTimeCheckBox.isSelected();
417 boolean validatePanel() {
419 warnIfPathIsInvalid(getContentPaths());
430 "LocalFilesPanel.pathValidation.dataSourceOnCDriveError=Warning: Path to multi-user data source is on \"C:\" drive",
431 "LocalFilesPanel.pathValidation.getOpenCase=WARNING: Exception while gettting open case."
433 private void warnIfPathIsInvalid(
final List<String> pathsList) {
434 errorLabel.setVisible(
false);
437 final Case.CaseType currentCaseType = Case.getCurrentCaseThrows().getCaseType();
439 for (String currentPath : pathsList) {
440 if (!PathValidator.isValidForCaseType(currentPath, currentCaseType)) {
441 errorLabel.setVisible(
true);
442 errorLabel.setText(Bundle.LocalFilesPanel_pathValidation_dataSourceOnCDriveError());
446 }
catch (NoCurrentCaseException ex) {
447 errorLabel.setVisible(
true);
448 errorLabel.setText(Bundle.LocalFilesPanel_pathValidation_getOpenCase());
457 String getFileSetName() {
458 return this.displayName;
475 return file == null ?
"" : file.getAbsolutePath();
491 private List<File> items = Collections.emptyList();
500 File f = items.get(index);
509 void add(File... files) {
510 items = Stream.concat(items.stream(), Stream.of(files))
511 .sorted(Comparator.comparing(f -> f.getAbsolutePath().toLowerCase()))
513 .collect(Collectors.toList());
515 this.fireContentsChanged(
this, 0, items.size() - 1);
524 void remove(
int minIdx,
int maxIdx) {
525 for (
int i = maxIdx; i >= minIdx; i--) {
528 this.fireContentsChanged(
this, 0, items.size() - 1);
534 List<File> getFiles() {
543 this.fireContentsChanged(
this, 0, 0);
549 private javax.swing.JCheckBox accessTimeCheckBox;
550 private javax.swing.JButton changeNameButton;
551 private javax.swing.JButton clearButton;
552 private javax.swing.JCheckBox createTimeCheckBox;
553 private javax.swing.JButton deleteButon;
554 private javax.swing.JLabel displayNameLabel;
555 private javax.swing.JLabel errorLabel;
556 private javax.swing.JList<FileRecord> fileList;
557 private javax.swing.JFileChooser localFileChooser;
558 private javax.swing.JCheckBox modifiedTimeCheckBox;
559 private javax.swing.JButton selectButton;
FileRecord getElementAt(int index)