Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
DateFilterPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy
3  *
4  * Copyright 2020-2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.discovery.ui;
20 
21 import com.github.lgooddatepicker.optionalusertools.DateChangeListener;
22 import com.github.lgooddatepicker.zinternaltools.DateChangeEvent;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.time.LocalDate;
26 import java.time.Period;
27 import java.time.ZoneId;
28 import java.util.List;
29 import java.util.logging.Level;
31 import javax.swing.JCheckBox;
32 import javax.swing.JLabel;
33 import javax.swing.JSpinner;
34 import javax.swing.event.ListSelectionListener;
35 import org.openide.util.NbBundle;
41 import org.sleuthkit.datamodel.TskCoreException;
42 
46 class DateFilterPanel extends AbstractDiscoveryFilterPanel {
47 
48  private static final long serialVersionUID = 1L;
49  private static final long SECS_PER_DAY = 86400;
50  private static final Logger logger = Logger.getLogger(DateFilterPanel.class.getName());
51 
55  @NbBundle.Messages({"# {0} - timeZone",
56  "DateFilterPanel.dateRange.text=Date Range ({0}):"})
57  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
58  DateFilterPanel() {
59  initComponents();
60  rangeRadioButton.setText(Bundle.DateFilterPanel_dateRange_text(Utils.getUserPreferredZoneId().toString()));
61  //Disable manual entry in the spinner
62  ((JSpinner.DefaultEditor) daysSpinner.getEditor()).getTextField().setEditable(false);
63  //Disable manual entry in the date pickers
64  startDatePicker.getComponentDateTextField().setEditable(false);
65  endDatePicker.getComponentDateTextField().setEditable(false);
66  }
67 
73  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
74  private void initComponents() {
75 
76  buttonGroup1 = new javax.swing.ButtonGroup();
77  dateFilterCheckBox = new javax.swing.JCheckBox();
78  jPanel1 = new javax.swing.JPanel();
79  daysSpinner = new javax.swing.JSpinner();
80  daysLabel = new javax.swing.JLabel();
81  mostRecentRadioButton = new javax.swing.JRadioButton();
82  startCheckBox = new javax.swing.JCheckBox();
83  startDatePicker = new com.github.lgooddatepicker.components.DatePicker();
84  endDatePicker = new com.github.lgooddatepicker.components.DatePicker();
85  endCheckBox = new javax.swing.JCheckBox();
86  rangeRadioButton = new javax.swing.JRadioButton();
87 
88  org.openide.awt.Mnemonics.setLocalizedText(dateFilterCheckBox, org.openide.util.NbBundle.getMessage(DateFilterPanel.class, "DateFilterPanel.dateFilterCheckBox.text")); // NOI18N
89  dateFilterCheckBox.addActionListener(new java.awt.event.ActionListener() {
90  public void actionPerformed(java.awt.event.ActionEvent evt) {
91  dateFilterCheckBoxActionPerformed(evt);
92  }
93  });
94 
95  daysSpinner.setModel(new javax.swing.SpinnerNumberModel(7, 1, 100000, 1));
96  daysSpinner.setEditor(new javax.swing.JSpinner.NumberEditor(daysSpinner, ""));
97  daysSpinner.setEnabled(false);
98  daysSpinner.setPreferredSize(new java.awt.Dimension(75, 26));
99  daysSpinner.setValue(7);
100 
101  org.openide.awt.Mnemonics.setLocalizedText(daysLabel, org.openide.util.NbBundle.getMessage(DateFilterPanel.class, "DateFilterPanel.daysLabel.text")); // NOI18N
102  daysLabel.setEnabled(false);
103 
104  buttonGroup1.add(mostRecentRadioButton);
105  mostRecentRadioButton.setSelected(true);
106  org.openide.awt.Mnemonics.setLocalizedText(mostRecentRadioButton, org.openide.util.NbBundle.getMessage(DateFilterPanel.class, "DateFilterPanel.mostRecentRadioButton.text")); // NOI18N
107  mostRecentRadioButton.setEnabled(false);
108  mostRecentRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
109  public void stateChanged(javax.swing.event.ChangeEvent evt) {
110  mostRecentRadioButtonStateChanged(evt);
111  }
112  });
113 
114  org.openide.awt.Mnemonics.setLocalizedText(startCheckBox, org.openide.util.NbBundle.getMessage(DateFilterPanel.class, "DateFilterPanel.startCheckBox.text")); // NOI18N
115  startCheckBox.setEnabled(false);
116  startCheckBox.addChangeListener(new javax.swing.event.ChangeListener() {
117  public void stateChanged(javax.swing.event.ChangeEvent evt) {
118  startCheckBoxStateChanged(evt);
119  }
120  });
121 
122  startDatePicker.setDate(LocalDate.now());
123  startDatePicker.setEnabled(false);
124  startDatePicker.setMinimumSize(new java.awt.Dimension(60, 22));
125  startDatePicker.setPreferredSize(new java.awt.Dimension(110, 22));
126 
127  endDatePicker.setDate(LocalDate.now());
128  endDatePicker.setEnabled(false);
129  endDatePicker.setMinimumSize(new java.awt.Dimension(60, 22));
130  endDatePicker.setPreferredSize(new java.awt.Dimension(110, 22));
131 
132  org.openide.awt.Mnemonics.setLocalizedText(endCheckBox, org.openide.util.NbBundle.getMessage(DateFilterPanel.class, "DateFilterPanel.endCheckBox.text")); // NOI18N
133  endCheckBox.setEnabled(false);
134  endCheckBox.addChangeListener(new javax.swing.event.ChangeListener() {
135  public void stateChanged(javax.swing.event.ChangeEvent evt) {
136  endCheckBoxStateChanged(evt);
137  }
138  });
139 
140  buttonGroup1.add(rangeRadioButton);
141  rangeRadioButton.setEnabled(false);
142  rangeRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
143  public void stateChanged(javax.swing.event.ChangeEvent evt) {
144  rangeRadioButtonStateChanged(evt);
145  }
146  });
147 
148  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
149  jPanel1.setLayout(jPanel1Layout);
150  jPanel1Layout.setHorizontalGroup(
151  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
152  .addGroup(jPanel1Layout.createSequentialGroup()
153  .addComponent(mostRecentRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
154  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
155  .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
156  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
157  .addComponent(daysLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE))
158  .addComponent(rangeRadioButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
159  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
160  .addGap(30, 30, 30)
161  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
162  .addComponent(endCheckBox)
163  .addComponent(startCheckBox))
164  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
165  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
166  .addComponent(endDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
167  .addComponent(startDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
168  );
169  jPanel1Layout.setVerticalGroup(
170  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
171  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
172  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
173  .addComponent(mostRecentRadioButton)
174  .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
175  .addComponent(daysLabel))
176  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
177  .addComponent(rangeRadioButton)
178  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
179  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
180  .addComponent(startCheckBox)
181  .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
182  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
183  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
184  .addComponent(endCheckBox)
185  .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
186  .addGap(0, 0, 0))
187  );
188 
189  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
190  this.setLayout(layout);
191  layout.setHorizontalGroup(
192  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
193  .addGroup(layout.createSequentialGroup()
194  .addGap(0, 0, 0)
195  .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
196  .addGap(0, 0, 0))
197  );
198  layout.setVerticalGroup(
199  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
200  .addGroup(layout.createSequentialGroup()
201  .addGap(0, 0, 0)
202  .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
203  .addGap(8, 8, 8))
204  );
205  }// </editor-fold>//GEN-END:initComponents
206 
207  private void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_startCheckBoxStateChanged
208  startDatePicker.setEnabled(startCheckBox.isEnabled() && startCheckBox.isSelected());
209  }//GEN-LAST:event_startCheckBoxStateChanged
210 
211  private void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_endCheckBoxStateChanged
212  endDatePicker.setEnabled(endCheckBox.isEnabled() && endCheckBox.isSelected());
213  }//GEN-LAST:event_endCheckBoxStateChanged
214 
215  private void dateFilterCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateFilterCheckBoxActionPerformed
216  rangeRadioButton.setEnabled(dateFilterCheckBox.isSelected());
217  mostRecentRadioButton.setEnabled(dateFilterCheckBox.isSelected());
218  rangeRadioButton.firePropertyChange("DateFilterChange", !rangeRadioButton.isEnabled(), rangeRadioButton.isEnabled());
219  mostRecentRadioButton.firePropertyChange("DateFilterChange", !mostRecentRadioButton.isEnabled(), mostRecentRadioButton.isEnabled());
220  }//GEN-LAST:event_dateFilterCheckBoxActionPerformed
221 
222  private void mostRecentRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_mostRecentRadioButtonStateChanged
223  daysSpinner.setEnabled(mostRecentRadioButton.isSelected());
224  daysLabel.setEnabled(mostRecentRadioButton.isSelected());
225  }//GEN-LAST:event_mostRecentRadioButtonStateChanged
226 
227  private void rangeRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_rangeRadioButtonStateChanged
228  startCheckBox.setEnabled(rangeRadioButton.isEnabled() && rangeRadioButton.isSelected());
229  endCheckBox.setEnabled(rangeRadioButton.isEnabled() && rangeRadioButton.isSelected());
230  startCheckBox.firePropertyChange("StartButtonChange", true, false);
231  endCheckBox.firePropertyChange("EndButtonChange", true, false);
232  }//GEN-LAST:event_rangeRadioButtonStateChanged
233 
234  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
235  @Override
236  void configurePanel(boolean selected, List<?> selectedItems) {
237  dateFilterCheckBox.setSelected(selected);
238  if (dateFilterCheckBox.isEnabled() && dateFilterCheckBox.isSelected()) {
239  mostRecentRadioButton.setEnabled(true);
240  rangeRadioButton.setEnabled(true);
241  mostRecentRadioButton.setSelected(true);
242  } else {
243  mostRecentRadioButton.setEnabled(false);
244  rangeRadioButton.setEnabled(false);
245  }
246  }
247 
248  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
249  @Override
250  JCheckBox getCheckbox() {
251  return dateFilterCheckBox;
252  }
253 
254  @Override
255  JLabel getAdditionalLabel() {
256  return null;
257  }
258 
259  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
260  @Override
261  void addListeners(ActionListener actionListener, ListSelectionListener listListener) {
262  dateFilterCheckBox.addActionListener(actionListener);
263  startCheckBox.addActionListener(actionListener);
264  endCheckBox.addActionListener(actionListener);
265  rangeRadioButton.addActionListener(actionListener);
266  mostRecentRadioButton.addActionListener(actionListener);
267  startDatePicker.addDateChangeListener(new DateChangeListener() {
268  @Override
269  public void dateChanged(DateChangeEvent event) {
270  actionListener.actionPerformed(new ActionEvent(startDatePicker, ActionEvent.ACTION_PERFORMED, "StartDateChanged"));
271  }
272  });
273  endDatePicker.addDateChangeListener(new DateChangeListener() {
274  @Override
275  public void dateChanged(DateChangeEvent event) {
276  actionListener.actionPerformed(new ActionEvent(endDatePicker, ActionEvent.ACTION_PERFORMED, "EndDateChanged"));
277  }
278  });
279  }
280 
281  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
282  @NbBundle.Messages({"DateFilterPanel.invalidRange.text=Range or Only Last must be selected.",
283  "DateFilterPanel.startOrEndNeeded.text=A start or end date must be specified to use the range filter.",
284  "DateFilterPanel.startAfterEnd.text=Start date should be before the end date when both are enabled."})
285  @Override
286  String checkForError() {
287  if (dateFilterCheckBox.isSelected()) {
288  if (!(rangeRadioButton.isSelected() || mostRecentRadioButton.isSelected())) {
289  return Bundle.DateFilterPanel_invalidRange_text();
290  } else if (rangeRadioButton.isSelected() && !(startCheckBox.isSelected() || endCheckBox.isSelected())) {
291  return Bundle.DateFilterPanel_startOrEndNeeded_text();
292  } else if (startCheckBox.isSelected() && endCheckBox.isSelected() && startDatePicker.getDate().isAfter(endDatePicker.getDate())) {
293  //if the dates are equal it will effectively search just that day due to the rounding up of the end date in the getFilter code
294  return Bundle.DateFilterPanel_startAfterEnd_text();
295  }
296  }
297  return "";
298  }
299 
300  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
301  @Override
302  AbstractFilter getFilter() {
303  if (dateFilterCheckBox.isSelected()) {
304  LocalDate startDate = LocalDate.MIN;
305  LocalDate endDate = LocalDate.MAX;
306  ZoneId zone = Utils.getUserPreferredZoneId();
307  if (rangeRadioButton.isSelected() && (startCheckBox.isSelected() || endCheckBox.isSelected())) {
308  if (startCheckBox.isSelected() && startDatePicker.getDate() != null) {
309  startDate = startDatePicker.getDate();
310  }
311  if (endCheckBox.isSelected() && endDatePicker.getDate() != null) {
312  endDate = endDatePicker.getDate().plus(Period.ofDays(1)); //add a day to keep end date inclusive
313  }
314  } else if (dateFilterCheckBox.isSelected() && mostRecentRadioButton.isSelected()) {
315  try {
316  startDate = LocalDate.ofEpochDay(Case.getCurrentCase().getSleuthkitCase().getTimelineManager().getMaxEventTime() / SECS_PER_DAY).minus(Period.ofDays((Integer) daysSpinner.getValue()));
317  } catch (TskCoreException ex) {
318  startDate = LocalDate.now().minus(Period.ofDays((Integer) daysSpinner.getValue()));
319  logger.log(Level.WARNING, "Unable to get most recent event time from database, using current date instead.");
320  }
321  }
322  return new SearchFiltering.ArtifactDateRangeFilter(startDate.atStartOfDay(zone).toEpochSecond(), endDate.atStartOfDay(zone).toEpochSecond());
323  }
324  return null;
325  }
326  // Variables declaration - do not modify//GEN-BEGIN:variables
327  private javax.swing.ButtonGroup buttonGroup1;
328  private javax.swing.JCheckBox dateFilterCheckBox;
329  private javax.swing.JLabel daysLabel;
330  private javax.swing.JSpinner daysSpinner;
331  private javax.swing.JCheckBox endCheckBox;
332  private com.github.lgooddatepicker.components.DatePicker endDatePicker;
333  private javax.swing.JPanel jPanel1;
334  private javax.swing.JRadioButton mostRecentRadioButton;
335  private javax.swing.JRadioButton rangeRadioButton;
336  private javax.swing.JCheckBox startCheckBox;
337  private com.github.lgooddatepicker.components.DatePicker startDatePicker;
338  // End of variables declaration//GEN-END:variables
339 
340  @Override
341  void addListSelectionListener(ListSelectionListener listener) {
342  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
343  }
344 
345  @Override
346  boolean isFilterSupported() {
347  return true;
348  }
349 
350 }

Copyright © 2012-2022 Basis Technology. Generated on: Wed Oct 5 2022
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.