19 package org.sleuthkit.autopsy.discovery.ui;
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;
29 import javax.swing.JCheckBox;
30 import javax.swing.JLabel;
31 import javax.swing.JList;
32 import javax.swing.JSpinner;
33 import javax.swing.event.ListSelectionListener;
34 import org.openide.util.NbBundle;
42 class DateFilterPanel
extends AbstractDiscoveryFilterPanel {
44 private static final long serialVersionUID = 1L;
45 private static final long SECS_PER_DAY = 86400;
50 @NbBundle.Messages({
"# {0} - timeZone",
51 "DateFilterPanel.dateRange.text=Date Range ({0}):"})
52 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
55 rangeRadioButton.setText(Bundle.DateFilterPanel_dateRange_text(Utils.getUserPreferredZoneId().toString()));
57 ((JSpinner.DefaultEditor) daysSpinner.getEditor()).getTextField().setEditable(
false);
59 startDatePicker.getComponentDateTextField().setEditable(
false);
60 endDatePicker.getComponentDateTextField().setEditable(
false);
68 @SuppressWarnings(
"unchecked")
70 private
void initComponents() {
72 buttonGroup1 =
new javax.swing.ButtonGroup();
73 dateFilterCheckBox =
new javax.swing.JCheckBox();
74 jPanel1 =
new javax.swing.JPanel();
75 daysSpinner =
new javax.swing.JSpinner();
76 daysLabel =
new javax.swing.JLabel();
77 mostRecentRadioButton =
new javax.swing.JRadioButton();
78 startCheckBox =
new javax.swing.JCheckBox();
79 startDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
80 endDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
81 endCheckBox =
new javax.swing.JCheckBox();
82 rangeRadioButton =
new javax.swing.JRadioButton();
84 org.openide.awt.Mnemonics.setLocalizedText(dateFilterCheckBox,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.dateFilterCheckBox.text"));
85 dateFilterCheckBox.addActionListener(
new java.awt.event.ActionListener() {
86 public void actionPerformed(java.awt.event.ActionEvent evt) {
87 dateFilterCheckBoxActionPerformed(evt);
91 daysSpinner.setModel(
new javax.swing.SpinnerNumberModel(7, 1, 100000, 1));
92 daysSpinner.setEditor(
new javax.swing.JSpinner.NumberEditor(daysSpinner,
""));
93 daysSpinner.setEnabled(
false);
94 daysSpinner.setPreferredSize(
new java.awt.Dimension(75, 26));
95 daysSpinner.setValue(7);
97 org.openide.awt.Mnemonics.setLocalizedText(daysLabel,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.daysLabel.text"));
98 daysLabel.setEnabled(
false);
100 buttonGroup1.add(mostRecentRadioButton);
101 mostRecentRadioButton.setSelected(
true);
102 org.openide.awt.Mnemonics.setLocalizedText(mostRecentRadioButton,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.mostRecentRadioButton.text"));
103 mostRecentRadioButton.setEnabled(
false);
104 mostRecentRadioButton.addChangeListener(
new javax.swing.event.ChangeListener() {
105 public void stateChanged(javax.swing.event.ChangeEvent evt) {
106 mostRecentRadioButtonStateChanged(evt);
110 org.openide.awt.Mnemonics.setLocalizedText(startCheckBox,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.startCheckBox.text"));
111 startCheckBox.setEnabled(
false);
112 startCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
113 public void stateChanged(javax.swing.event.ChangeEvent evt) {
114 startCheckBoxStateChanged(evt);
118 startDatePicker.setDate(LocalDate.now());
119 startDatePicker.setEnabled(
false);
120 startDatePicker.setMinimumSize(
new java.awt.Dimension(60, 22));
121 startDatePicker.setPreferredSize(
new java.awt.Dimension(110, 22));
123 endDatePicker.setDate(LocalDate.now());
124 endDatePicker.setEnabled(
false);
125 endDatePicker.setMinimumSize(
new java.awt.Dimension(60, 22));
126 endDatePicker.setPreferredSize(
new java.awt.Dimension(110, 22));
128 org.openide.awt.Mnemonics.setLocalizedText(endCheckBox,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.endCheckBox.text"));
129 endCheckBox.setEnabled(
false);
130 endCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
131 public void stateChanged(javax.swing.event.ChangeEvent evt) {
132 endCheckBoxStateChanged(evt);
136 buttonGroup1.add(rangeRadioButton);
137 rangeRadioButton.setEnabled(
false);
138 rangeRadioButton.addChangeListener(
new javax.swing.event.ChangeListener() {
139 public void stateChanged(javax.swing.event.ChangeEvent evt) {
140 rangeRadioButtonStateChanged(evt);
144 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(jPanel1);
145 jPanel1.setLayout(jPanel1Layout);
146 jPanel1Layout.setHorizontalGroup(
147 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
148 .addGroup(jPanel1Layout.createSequentialGroup()
149 .addComponent(mostRecentRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
150 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
151 .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
152 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
153 .addComponent(daysLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE))
154 .addComponent(rangeRadioButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
155 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
157 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
158 .addComponent(endCheckBox)
159 .addComponent(startCheckBox))
160 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
161 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
162 .addComponent(endDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
163 .addComponent(startDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
165 jPanel1Layout.setVerticalGroup(
166 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
167 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
168 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
169 .addComponent(mostRecentRadioButton)
170 .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
171 .addComponent(daysLabel))
172 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
173 .addComponent(rangeRadioButton)
174 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
175 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
176 .addComponent(startCheckBox)
177 .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
178 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
179 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
180 .addComponent(endCheckBox)
181 .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
185 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
186 this.setLayout(layout);
187 layout.setHorizontalGroup(
188 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
189 .addGroup(layout.createSequentialGroup()
191 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
194 layout.setVerticalGroup(
195 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
196 .addGroup(layout.createSequentialGroup()
198 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
203 private void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {
204 startDatePicker.setEnabled(startCheckBox.isEnabled() && startCheckBox.isSelected());
207 private void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {
208 endDatePicker.setEnabled(endCheckBox.isEnabled() && endCheckBox.isSelected());
211 private void dateFilterCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
212 rangeRadioButton.setEnabled(dateFilterCheckBox.isSelected());
213 mostRecentRadioButton.setEnabled(dateFilterCheckBox.isSelected());
214 rangeRadioButton.firePropertyChange(
"DateFilterChange", !rangeRadioButton.isEnabled(), rangeRadioButton.isEnabled());
215 mostRecentRadioButton.firePropertyChange(
"DateFilterChange", !mostRecentRadioButton.isEnabled(), mostRecentRadioButton.isEnabled());
218 private void mostRecentRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {
219 daysSpinner.setEnabled(mostRecentRadioButton.isSelected());
220 daysLabel.setEnabled(mostRecentRadioButton.isSelected());
223 private void rangeRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {
224 startCheckBox.setEnabled(rangeRadioButton.isEnabled() && rangeRadioButton.isSelected());
225 endCheckBox.setEnabled(rangeRadioButton.isEnabled() && rangeRadioButton.isSelected());
226 startCheckBox.firePropertyChange(
"StartButtonChange",
true,
false);
227 endCheckBox.firePropertyChange(
"EndButtonChange",
true,
false);
230 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
232 void configurePanel(
boolean selected,
int[] indicesSelected) {
233 dateFilterCheckBox.setSelected(selected);
234 if (dateFilterCheckBox.isEnabled() && dateFilterCheckBox.isSelected()) {
235 mostRecentRadioButton.setEnabled(
true);
236 rangeRadioButton.setEnabled(
true);
237 mostRecentRadioButton.setSelected(
true);
239 mostRecentRadioButton.setEnabled(
false);
240 rangeRadioButton.setEnabled(
false);
244 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
246 JCheckBox getCheckbox() {
247 return dateFilterCheckBox;
256 JLabel getAdditionalLabel() {
260 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
262 void addListeners(ActionListener actionListener, ListSelectionListener listListener) {
263 dateFilterCheckBox.addActionListener(actionListener);
264 startCheckBox.addActionListener(actionListener);
265 endCheckBox.addActionListener(actionListener);
266 rangeRadioButton.addActionListener(actionListener);
267 mostRecentRadioButton.addActionListener(actionListener);
268 startDatePicker.addDateChangeListener(
new DateChangeListener() {
270 public void dateChanged(DateChangeEvent event) {
271 actionListener.actionPerformed(
new ActionEvent(startDatePicker, ActionEvent.ACTION_PERFORMED,
"StartDateChanged"));
274 endDatePicker.addDateChangeListener(
new DateChangeListener() {
276 public void dateChanged(DateChangeEvent event) {
277 actionListener.actionPerformed(
new ActionEvent(endDatePicker, ActionEvent.ACTION_PERFORMED,
"EndDateChanged"));
282 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
284 void removeListeners() {
285 for (ActionListener listener : dateFilterCheckBox.getActionListeners()) {
286 dateFilterCheckBox.removeActionListener(listener);
288 for (ActionListener listener : rangeRadioButton.getActionListeners()) {
289 rangeRadioButton.removeActionListener(listener);
291 for (ActionListener listener : mostRecentRadioButton.getActionListeners()) {
292 mostRecentRadioButton.removeActionListener(listener);
294 for (ActionListener listener : rangeRadioButton.getActionListeners()) {
295 rangeRadioButton.removeActionListener(listener);
297 for (ActionListener listener : startCheckBox.getActionListeners()) {
298 startCheckBox.removeActionListener(listener);
300 for (ActionListener listener : endCheckBox.getActionListeners()) {
301 endCheckBox.removeActionListener(listener);
303 for (DateChangeListener listener : endDatePicker.getDateChangeListeners()) {
304 endDatePicker.removeDateChangeListener(listener);
306 for (DateChangeListener listener : startDatePicker.getDateChangeListeners()) {
307 startDatePicker.removeDateChangeListener(listener);
311 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
312 @NbBundle.Messages({
"DateFilterPanel.invalidRange.text=Range or Only Last must be selected.",
313 "DateFilterPanel.startOrEndNeeded.text=A start or end date must be specified to use the range filter.",
314 "DateFilterPanel.startAfterEnd.text=Start date should be before the end date when both are enabled."})
316 String checkForError() {
317 if (dateFilterCheckBox.isSelected()) {
318 if (!(rangeRadioButton.isSelected() || mostRecentRadioButton.isSelected())) {
319 return Bundle.DateFilterPanel_invalidRange_text();
320 }
else if (rangeRadioButton.isSelected() && !(startCheckBox.isSelected() || endCheckBox.isSelected())) {
321 return Bundle.DateFilterPanel_startOrEndNeeded_text();
322 }
else if (startCheckBox.isSelected() && endCheckBox.isSelected() && startDatePicker.getDate().isAfter(endDatePicker.getDate())) {
324 return Bundle.DateFilterPanel_startAfterEnd_text();
330 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
332 AbstractFilter getFilter() {
333 if (dateFilterCheckBox.isSelected()) {
334 LocalDate startDate = LocalDate.MIN;
335 LocalDate endDate = LocalDate.MAX;
336 ZoneId zone = Utils.getUserPreferredZoneId();
337 if (rangeRadioButton.isSelected() && (startCheckBox.isSelected() || endCheckBox.isSelected())) {
338 if (startCheckBox.isSelected() && startDatePicker.getDate() != null) {
339 startDate = startDatePicker.getDate();
341 if (endCheckBox.isSelected() && endDatePicker.getDate() != null) {
342 endDate = endDatePicker.getDate();
344 }
else if (dateFilterCheckBox.isSelected() && mostRecentRadioButton.isSelected()) {
345 endDate = LocalDate.now();
346 startDate = LocalDate.now().minus(Period.ofDays((Integer) daysSpinner.getValue()));
348 return new SearchFiltering.ArtifactDateRangeFilter(startDate.atStartOfDay(zone).toEpochSecond(), endDate.atStartOfDay(zone).toEpochSecond() + SECS_PER_DAY);
353 private javax.swing.ButtonGroup buttonGroup1;
354 private javax.swing.JCheckBox dateFilterCheckBox;
355 private javax.swing.JLabel daysLabel;
356 private javax.swing.JSpinner daysSpinner;
357 private javax.swing.JCheckBox endCheckBox;
358 private com.github.lgooddatepicker.components.DatePicker endDatePicker;
359 private javax.swing.JPanel jPanel1;
360 private javax.swing.JRadioButton mostRecentRadioButton;
361 private javax.swing.JRadioButton rangeRadioButton;
362 private javax.swing.JCheckBox startCheckBox;
363 private com.github.lgooddatepicker.components.DatePicker startDatePicker;