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;
41 class DateFilterPanel
extends AbstractDiscoveryFilterPanel {
43 private static final long serialVersionUID = 1L;
44 private static final long SECS_PER_DAY = 86400;
49 @NbBundle.Messages({
"# {0} - timeZone",
50 "DateFilterPanel.dateRange.text=Date Range ({0}):"})
53 rangeRadioButton.setText(Bundle.DateFilterPanel_dateRange_text(Utils.getUserPreferredZoneId().toString()));
55 ((JSpinner.DefaultEditor) daysSpinner.getEditor()).getTextField().setEditable(
false);
57 startDatePicker.getComponentDateTextField().setEditable(
false);
58 endDatePicker.getComponentDateTextField().setEditable(
false);
66 @SuppressWarnings(
"unchecked")
68 private
void initComponents() {
70 buttonGroup1 =
new javax.swing.ButtonGroup();
71 dateFilterCheckBox =
new javax.swing.JCheckBox();
72 jPanel1 =
new javax.swing.JPanel();
73 daysSpinner =
new javax.swing.JSpinner();
74 daysLabel =
new javax.swing.JLabel();
75 mostRecentRadioButton =
new javax.swing.JRadioButton();
76 startCheckBox =
new javax.swing.JCheckBox();
77 startDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
78 endDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
79 endCheckBox =
new javax.swing.JCheckBox();
80 rangeRadioButton =
new javax.swing.JRadioButton();
82 org.openide.awt.Mnemonics.setLocalizedText(dateFilterCheckBox,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.dateFilterCheckBox.text"));
83 dateFilterCheckBox.addActionListener(
new java.awt.event.ActionListener() {
84 public void actionPerformed(java.awt.event.ActionEvent evt) {
85 dateFilterCheckBoxActionPerformed(evt);
89 daysSpinner.setModel(
new javax.swing.SpinnerNumberModel(7, 1, 100000, 1));
90 daysSpinner.setEditor(
new javax.swing.JSpinner.NumberEditor(daysSpinner,
""));
91 daysSpinner.setEnabled(
false);
92 daysSpinner.setPreferredSize(
new java.awt.Dimension(75, 26));
93 daysSpinner.setValue(7);
95 org.openide.awt.Mnemonics.setLocalizedText(daysLabel,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.daysLabel.text"));
96 daysLabel.setEnabled(
false);
98 buttonGroup1.add(mostRecentRadioButton);
99 mostRecentRadioButton.setSelected(
true);
100 org.openide.awt.Mnemonics.setLocalizedText(mostRecentRadioButton,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.mostRecentRadioButton.text"));
101 mostRecentRadioButton.setEnabled(
false);
102 mostRecentRadioButton.addChangeListener(
new javax.swing.event.ChangeListener() {
103 public void stateChanged(javax.swing.event.ChangeEvent evt) {
104 mostRecentRadioButtonStateChanged(evt);
108 org.openide.awt.Mnemonics.setLocalizedText(startCheckBox,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.startCheckBox.text"));
109 startCheckBox.setEnabled(
false);
110 startCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
111 public void stateChanged(javax.swing.event.ChangeEvent evt) {
112 startCheckBoxStateChanged(evt);
116 startDatePicker.setDate(LocalDate.now());
117 startDatePicker.setEnabled(
false);
118 startDatePicker.setMinimumSize(
new java.awt.Dimension(60, 22));
119 startDatePicker.setPreferredSize(
new java.awt.Dimension(110, 22));
121 endDatePicker.setDate(LocalDate.now());
122 endDatePicker.setEnabled(
false);
123 endDatePicker.setMinimumSize(
new java.awt.Dimension(60, 22));
124 endDatePicker.setPreferredSize(
new java.awt.Dimension(110, 22));
126 org.openide.awt.Mnemonics.setLocalizedText(endCheckBox,
org.openide.util.NbBundle.getMessage(DateFilterPanel.class,
"DateFilterPanel.endCheckBox.text"));
127 endCheckBox.setEnabled(
false);
128 endCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
129 public void stateChanged(javax.swing.event.ChangeEvent evt) {
130 endCheckBoxStateChanged(evt);
134 buttonGroup1.add(rangeRadioButton);
135 rangeRadioButton.setEnabled(
false);
136 rangeRadioButton.addChangeListener(
new javax.swing.event.ChangeListener() {
137 public void stateChanged(javax.swing.event.ChangeEvent evt) {
138 rangeRadioButtonStateChanged(evt);
142 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(jPanel1);
143 jPanel1.setLayout(jPanel1Layout);
144 jPanel1Layout.setHorizontalGroup(
145 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
146 .addGroup(jPanel1Layout.createSequentialGroup()
147 .addComponent(mostRecentRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
148 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
149 .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
150 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
151 .addComponent(daysLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE))
152 .addComponent(rangeRadioButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
153 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
155 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
156 .addComponent(endCheckBox)
157 .addComponent(startCheckBox))
158 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
159 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
160 .addComponent(endDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
161 .addComponent(startDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
163 jPanel1Layout.setVerticalGroup(
164 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
165 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
166 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
167 .addComponent(mostRecentRadioButton)
168 .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
169 .addComponent(daysLabel))
170 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
171 .addComponent(rangeRadioButton)
172 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
173 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
174 .addComponent(startCheckBox)
175 .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
176 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
177 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
178 .addComponent(endCheckBox)
179 .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
183 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
184 this.setLayout(layout);
185 layout.setHorizontalGroup(
186 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
187 .addGroup(layout.createSequentialGroup()
189 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
192 layout.setVerticalGroup(
193 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
194 .addGroup(layout.createSequentialGroup()
196 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
201 private void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {
202 startDatePicker.setEnabled(startCheckBox.isEnabled() && startCheckBox.isSelected());
205 private void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {
206 endDatePicker.setEnabled(endCheckBox.isEnabled() && endCheckBox.isSelected());
209 private void dateFilterCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
210 rangeRadioButton.setEnabled(dateFilterCheckBox.isSelected());
211 mostRecentRadioButton.setEnabled(dateFilterCheckBox.isSelected());
212 rangeRadioButton.firePropertyChange(
"DateFilterChange", !rangeRadioButton.isEnabled(), rangeRadioButton.isEnabled());
213 mostRecentRadioButton.firePropertyChange(
"DateFilterChange", !mostRecentRadioButton.isEnabled(), mostRecentRadioButton.isEnabled());
216 private void mostRecentRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {
217 daysSpinner.setEnabled(mostRecentRadioButton.isSelected());
218 daysLabel.setEnabled(mostRecentRadioButton.isSelected());
221 private void rangeRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {
222 startCheckBox.setEnabled(rangeRadioButton.isEnabled() && rangeRadioButton.isSelected());
223 endCheckBox.setEnabled(rangeRadioButton.isEnabled() && rangeRadioButton.isSelected());
224 startCheckBox.firePropertyChange(
"StartButtonChange",
true,
false);
225 endCheckBox.firePropertyChange(
"EndButtonChange",
true,
false);
229 void configurePanel(
boolean selected,
int[] indicesSelected) {
230 dateFilterCheckBox.setSelected(selected);
231 if (dateFilterCheckBox.isEnabled() && dateFilterCheckBox.isSelected()) {
232 mostRecentRadioButton.setEnabled(
true);
233 rangeRadioButton.setEnabled(
true);
234 mostRecentRadioButton.setSelected(
true);
236 mostRecentRadioButton.setEnabled(
false);
237 rangeRadioButton.setEnabled(
false);
242 JCheckBox getCheckbox() {
243 return dateFilterCheckBox;
252 JLabel getAdditionalLabel() {
257 void addListeners(ActionListener actionListener, ListSelectionListener listListener) {
258 dateFilterCheckBox.addActionListener(actionListener);
259 startCheckBox.addActionListener(actionListener);
260 endCheckBox.addActionListener(actionListener);
261 rangeRadioButton.addActionListener(actionListener);
262 mostRecentRadioButton.addActionListener(actionListener);
263 startDatePicker.addDateChangeListener(
new DateChangeListener() {
265 public void dateChanged(DateChangeEvent event) {
266 actionListener.actionPerformed(
new ActionEvent(startDatePicker, ActionEvent.ACTION_PERFORMED,
"StartDateChanged"));
269 endDatePicker.addDateChangeListener(
new DateChangeListener() {
271 public void dateChanged(DateChangeEvent event) {
272 actionListener.actionPerformed(
new ActionEvent(endDatePicker, ActionEvent.ACTION_PERFORMED,
"EndDateChanged"));
278 void removeListeners() {
279 for (ActionListener listener : dateFilterCheckBox.getActionListeners()) {
280 dateFilterCheckBox.removeActionListener(listener);
282 for (ActionListener listener : rangeRadioButton.getActionListeners()) {
283 rangeRadioButton.removeActionListener(listener);
285 for (ActionListener listener : mostRecentRadioButton.getActionListeners()) {
286 mostRecentRadioButton.removeActionListener(listener);
288 for (ActionListener listener : rangeRadioButton.getActionListeners()) {
289 rangeRadioButton.removeActionListener(listener);
291 for (ActionListener listener : startCheckBox.getActionListeners()) {
292 startCheckBox.removeActionListener(listener);
294 for (ActionListener listener : endCheckBox.getActionListeners()) {
295 endCheckBox.removeActionListener(listener);
297 for (DateChangeListener listener : endDatePicker.getDateChangeListeners()) {
298 endDatePicker.removeDateChangeListener(listener);
300 for (DateChangeListener listener : startDatePicker.getDateChangeListeners()) {
301 startDatePicker.removeDateChangeListener(listener);
305 @NbBundle.Messages({
"DateFilterPanel.invalidRange.text=Range or Only Last must be selected.",
306 "DateFilterPanel.startOrEndNeeded.text=A start or end date must be specified to use the range filter.",
307 "DateFilterPanel.startAfterEnd.text=Start date should be before the end date when both are enabled."})
309 String checkForError() {
310 if (dateFilterCheckBox.isSelected()) {
311 if (!(rangeRadioButton.isSelected() || mostRecentRadioButton.isSelected())) {
312 return Bundle.DateFilterPanel_invalidRange_text();
313 }
else if (rangeRadioButton.isSelected() && !(startCheckBox.isSelected() || endCheckBox.isSelected())) {
314 return Bundle.DateFilterPanel_startOrEndNeeded_text();
315 }
else if (startCheckBox.isSelected() && endCheckBox.isSelected() && startDatePicker.getDate().isAfter(endDatePicker.getDate())) {
317 return Bundle.DateFilterPanel_startAfterEnd_text();
324 AbstractFilter getFilter() {
325 if (dateFilterCheckBox.isSelected()) {
326 LocalDate startDate = LocalDate.MIN;
327 LocalDate endDate = LocalDate.MAX;
328 ZoneId zone = Utils.getUserPreferredZoneId();
329 if (rangeRadioButton.isSelected() && (startCheckBox.isSelected() || endCheckBox.isSelected())) {
330 if (startCheckBox.isSelected() && startDatePicker.getDate() != null) {
331 startDate = startDatePicker.getDate();
333 if (endCheckBox.isSelected() && endDatePicker.getDate() != null) {
334 endDate = endDatePicker.getDate();
336 }
else if (dateFilterCheckBox.isSelected() && mostRecentRadioButton.isSelected()) {
337 endDate = LocalDate.now();
338 startDate = LocalDate.now().minus(Period.ofDays((Integer) daysSpinner.getValue()));
340 return new SearchFiltering.ArtifactDateRangeFilter(startDate.atStartOfDay(zone).toEpochSecond(), endDate.atStartOfDay(zone).toEpochSecond() + SECS_PER_DAY);
345 private javax.swing.ButtonGroup buttonGroup1;
346 private javax.swing.JCheckBox dateFilterCheckBox;
347 private javax.swing.JLabel daysLabel;
348 private javax.swing.JSpinner daysSpinner;
349 private javax.swing.JCheckBox endCheckBox;
350 private com.github.lgooddatepicker.components.DatePicker endDatePicker;
351 private javax.swing.JPanel jPanel1;
352 private javax.swing.JRadioButton mostRecentRadioButton;
353 private javax.swing.JRadioButton rangeRadioButton;
354 private javax.swing.JCheckBox startCheckBox;
355 private com.github.lgooddatepicker.components.DatePicker startDatePicker;