19 package org.sleuthkit.autopsy.filesearch;
 
   21 import java.awt.event.ActionEvent;
 
   22 import java.awt.event.ActionListener;
 
   23 import java.text.DateFormat;
 
   24 import java.util.List;
 
   25 import javax.swing.JCheckBox;
 
   26 import javax.swing.JComboBox;
 
   27 import javax.swing.JFormattedTextField;
 
   28 import javax.swing.JMenuItem;
 
   29 import javax.swing.JPopupMenu;
 
   30 import com.github.lgooddatepicker.components.DatePicker;
 
   31 import com.github.lgooddatepicker.optionalusertools.PickerUtilities;
 
   32 import com.github.lgooddatepicker.components.DatePickerSettings;        
 
   33 import com.github.lgooddatepicker.optionalusertools.DateChangeListener;
 
   34 import com.github.lgooddatepicker.zinternaltools.DateChangeEvent;
 
   35 import java.text.ParseException;
 
   36 import java.time.Instant;
 
   37 import java.util.Date;
 
   42 @SuppressWarnings(
"PMD.SingularField") 
 
   43 class DateSearchPanel extends javax.swing.JPanel {
 
   45     private final DatePickerSettings fromDateSettings = 
new DatePickerSettings();
 
   46     private final DatePickerSettings toDateSettings = 
new DatePickerSettings();
 
   47     DateFormat dateFormat;
 
   48     List<String> timeZones;
 
   50     DateSearchPanel(DateFormat dateFormat, List<String> timeZones) {
 
   51         this.dateFormat = dateFormat;
 
   52         this.timeZones = timeZones;
 
   55         customizeComponents();
 
   58     private void customizeComponents() {
 
   59         fromDateSettings.setFormatForDatesCommonEra(PickerUtilities.createFormatterFromPatternString(
"MM/dd/yyyy", fromDateSettings.getLocale()));
 
   60         toDateSettings.setFormatForDatesCommonEra(PickerUtilities.createFormatterFromPatternString(
"MM/dd/yyyy", toDateSettings.getLocale()));
 
   61         fromDateSettings.setAllowKeyboardEditing(
false);
 
   62         toDateSettings.setAllowKeyboardEditing(
false);
 
   64         ActionListener actList = 
new ActionListener() {
 
   66             public void actionPerformed(ActionEvent e) {
 
   67                 JMenuItem jmi = (JMenuItem) e.getSource();
 
   72                 JFormattedTextField jftf = (JFormattedTextField) ((JPopupMenu) jmi.getParent()).getInvoker();
 
   73                 if (jmi.equals(cutMenuItem)) {
 
   75                 } 
else if (jmi.equals(copyMenuItem)) {
 
   77                 } 
else if (jmi.equals(pasteMenuItem)) {
 
   79                 } 
else if (jmi.equals(selectAllMenuItem)) {
 
   84         cutMenuItem.addActionListener(actList);
 
   85         copyMenuItem.addActionListener(actList);
 
   86         pasteMenuItem.addActionListener(actList);
 
   87         selectAllMenuItem.addActionListener(actList);
 
   89         this.setComponentsEnabled();
 
   92     JCheckBox getAccessedCheckBox() {
 
   93         return accessedCheckBox;
 
   96     JCheckBox getChangedCheckBox() {
 
   97         return changedCheckBox;
 
  100     JCheckBox getCreatedCheckBox() {
 
  101         return createdCheckBox;
 
  104     JCheckBox getDateCheckBox() {
 
  108     String getFromDate() {
 
  109         return fromDatePicker.getText();
 
  113         return toDatePicker.getText();
 
  116     JCheckBox getModifiedCheckBox() {
 
  117         return modifiedCheckBox;
 
  120     JComboBox<String> getTimeZoneComboBox() {
 
  121         return timeZoneComboBox;
 
  124     void setTimeZones(List<String> newTimeZones) {
 
  125         this.timeZones = newTimeZones;
 
  126         this.timeZoneComboBox.removeAllItems();
 
  127         for (String tz : newTimeZones) {
 
  128             this.timeZoneComboBox.addItem(tz);
 
  132     private void setComponentsEnabled() {
 
  133         boolean enable = this.dateCheckBox.isSelected();
 
  134         this.fromDatePicker.setEnabled(enable);
 
  135         this.jLabel1.setEnabled(enable);
 
  136         this.toDatePicker.setEnabled(enable);
 
  137         this.jLabel2.setEnabled(enable);
 
  138         this.jLabel3.setEnabled(enable);
 
  139         this.jLabel4.setEnabled(enable);
 
  140         this.timeZoneComboBox.setEnabled(enable);
 
  141         this.modifiedCheckBox.setEnabled(enable);
 
  142         this.accessedCheckBox.setEnabled(enable);
 
  143         this.changedCheckBox.setEnabled(enable);
 
  144         this.createdCheckBox.setEnabled(enable);
 
  152     @SuppressWarnings(
"unchecked")
 
  154     private 
void initComponents() {
 
  156         rightClickMenu = 
new javax.swing.JPopupMenu();
 
  157         cutMenuItem = 
new javax.swing.JMenuItem();
 
  158         copyMenuItem = 
new javax.swing.JMenuItem();
 
  159         pasteMenuItem = 
new javax.swing.JMenuItem();
 
  160         selectAllMenuItem = 
new javax.swing.JMenuItem();
 
  161         jLabel1 = 
new javax.swing.JLabel();
 
  162         jLabel4 = 
new javax.swing.JLabel();
 
  163         dateCheckBox = 
new javax.swing.JCheckBox();
 
  164         timeZoneComboBox = 
new JComboBox<>(this.timeZones.toArray(
new String[this.timeZones.size()]));
 
  165         timeZoneComboBox.setRenderer(
new DateSearchFilter.ComboBoxRenderer());
 
  166         jLabel3 = 
new javax.swing.JLabel();
 
  167         jLabel2 = 
new javax.swing.JLabel();
 
  168         modifiedCheckBox = 
new javax.swing.JCheckBox();
 
  169         changedCheckBox = 
new javax.swing.JCheckBox();
 
  170         accessedCheckBox = 
new javax.swing.JCheckBox();
 
  171         createdCheckBox = 
new javax.swing.JCheckBox();
 
  172         fromDatePicker = 
new DatePicker(fromDateSettings);
 
  173         toDatePicker = 
new DatePicker(toDateSettings);
 
  175         cutMenuItem.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.cutMenuItem.text")); 
 
  176         rightClickMenu.add(cutMenuItem);
 
  178         copyMenuItem.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.copyMenuItem.text")); 
 
  179         rightClickMenu.add(copyMenuItem);
 
  181         pasteMenuItem.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.pasteMenuItem.text")); 
 
  182         rightClickMenu.add(pasteMenuItem);
 
  184         selectAllMenuItem.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.selectAllMenuItem.text")); 
 
  185         rightClickMenu.add(selectAllMenuItem);
 
  187         jLabel1.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.jLabel1.text")); 
 
  189         jLabel4.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.jLabel4.text")); 
 
  191         dateCheckBox.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.dateCheckBox.text")); 
 
  192         dateCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  193             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  194                 dateCheckBoxActionPerformed(evt);
 
  198         jLabel3.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.jLabel3.text")); 
 
  199         jLabel3.setFont(
new java.awt.Font(
"Tahoma", 0, 10)); 
 
  201         jLabel2.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.jLabel2.text")); 
 
  202         jLabel2.setFont(
new java.awt.Font(
"Tahoma", 0, 10)); 
 
  204         modifiedCheckBox.setSelected(
true);
 
  205         modifiedCheckBox.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.modifiedCheckBox.text")); 
 
  206         modifiedCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  207             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  208                 modifiedCheckBoxActionPerformed(evt);
 
  212         changedCheckBox.setSelected(
true);
 
  213         changedCheckBox.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.changedCheckBox.text")); 
 
  214         changedCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  215             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  216                 changedCheckBoxActionPerformed(evt);
 
  220         accessedCheckBox.setSelected(
true);
 
  221         accessedCheckBox.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.accessedCheckBox.text")); 
 
  222         accessedCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  223             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  224                 accessedCheckBoxActionPerformed(evt);
 
  228         createdCheckBox.setSelected(
true);
 
  229         createdCheckBox.setText(
org.openide.util.NbBundle.getMessage(DateSearchPanel.class, 
"DateSearchPanel.createdCheckBox.text")); 
 
  230         createdCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  231             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  232                 createdCheckBoxActionPerformed(evt);
 
  236         fromDatePicker.setOpaque(
false);
 
  237         fromDatePicker.addFocusListener(
new java.awt.event.FocusAdapter() {
 
  238             public void focusLost(java.awt.event.FocusEvent evt) {
 
  239                 fromDatePickerFocusLost(evt);
 
  242         fromDatePicker.addPropertyChangeListener(
new java.beans.PropertyChangeListener() {
 
  243             public void propertyChange(java.beans.PropertyChangeEvent evt) {
 
  244                 fromDatePickerPropertyChange(evt);
 
  248         toDatePicker.setOpaque(
false);
 
  249         toDatePicker.addFocusListener(
new java.awt.event.FocusAdapter() {
 
  250             public void focusLost(java.awt.event.FocusEvent evt) {
 
  251                 toDatePickerFocusLost(evt);
 
  254         toDatePicker.addPropertyChangeListener(
new java.beans.PropertyChangeListener() {
 
  255             public void propertyChange(java.beans.PropertyChangeEvent evt) {
 
  256                 toDatePickerPropertyChange(evt);
 
  260         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  261         this.setLayout(layout);
 
  262         layout.setHorizontalGroup(
 
  263             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  264             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 
  265                 .addGap(0, 0, Short.MAX_VALUE)
 
  266                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  267                     .addGroup(layout.createSequentialGroup()
 
  268                         .addComponent(jLabel4)
 
  269                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  270                         .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  271                     .addGroup(layout.createSequentialGroup()
 
  272                         .addComponent(modifiedCheckBox)
 
  274                         .addComponent(accessedCheckBox)
 
  275                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  276                         .addComponent(createdCheckBox)
 
  277                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  278                         .addComponent(changedCheckBox)))
 
  280             .addGroup(layout.createSequentialGroup()
 
  281                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  282                     .addGroup(layout.createSequentialGroup()
 
  284                         .addComponent(jLabel2)
 
  286                         .addComponent(jLabel3))
 
  287                     .addGroup(layout.createSequentialGroup()
 
  288                         .addComponent(dateCheckBox)
 
  289                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  290                         .addComponent(fromDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  291                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  292                         .addComponent(jLabel1)
 
  294                         .addComponent(toDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
 
  295                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  297         layout.setVerticalGroup(
 
  298             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  299             .addGroup(layout.createSequentialGroup()
 
  300                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, 
false)
 
  301                     .addGroup(layout.createSequentialGroup()
 
  302                         .addComponent(dateCheckBox)
 
  304                     .addGroup(layout.createSequentialGroup()
 
  305                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  306                             .addComponent(jLabel1)
 
  307                             .addComponent(fromDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  308                             .addComponent(toDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  309                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  310                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  311                             .addComponent(jLabel3)
 
  312                             .addComponent(jLabel2))
 
  313                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
 
  314                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  315                     .addComponent(jLabel4)
 
  316                     .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  317                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  318                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  319                     .addComponent(modifiedCheckBox, javax.swing.GroupLayout.Alignment.TRAILING)
 
  320                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  321                         .addComponent(accessedCheckBox)
 
  322                         .addComponent(createdCheckBox)
 
  323                         .addComponent(changedCheckBox)))
 
  328     private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  329         this.setComponentsEnabled();
 
  330         firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
 
  333     private void modifiedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  334         firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
 
  337     private void accessedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  338         firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
 
  341     private void createdCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  342         firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
 
  345     private void changedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  346         firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
 
  349     private void fromDatePickerPropertyChange(java.beans.PropertyChangeEvent evt) {
 
  350         if (evt.getNewValue() instanceof Date) {
 
  351             setFromDate((Date) evt.getNewValue());
 
  355     private void toDatePickerPropertyChange(java.beans.PropertyChangeEvent evt) {
 
  356         if (evt.getNewValue() instanceof Date) {
 
  357            setToDate((Date) evt.getNewValue());
 
  361     private void fromDatePickerFocusLost(java.awt.event.FocusEvent evt) {
 
  363         String fromDateString = this.fromDatePicker.getText();
 
  364         if (!fromDateString.equals(
"")) {
 
  366                 Date fromDate = dateFormat.parse(fromDateString);
 
  367                 fromDatePicker.setDate(fromDate.toInstant().atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
 
  368             } 
catch (ParseException ex) {
 
  374     private void toDatePickerFocusLost(java.awt.event.FocusEvent evt) {
 
  376         String toDateString = this.toDatePicker.getText();
 
  377         if (!toDateString.equals(
"")) {
 
  379                 Date toDate = dateFormat.parse(toDateString);
 
  380                 toDatePicker.setDate(toDate.toInstant().atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
 
  381             } 
catch (ParseException ex) {
 
  393     private void setFromDate(Date date) {
 
  394         String dateStringResult = 
"";
 
  397             dateStringResult = dateFormat.format(date);
 
  398             ins = date.toInstant();
 
  401         fromDatePicker.setText(dateStringResult);
 
  403             fromDatePicker.setDate(ins.atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
 
  405             fromDatePicker.setDate(null);
 
  414     private void setToDate(Date date) {
 
  415         String dateStringResult = 
"";
 
  418             dateStringResult = dateFormat.format(date);
 
  419             ins = date.toInstant();
 
  421         toDatePicker.setText(dateStringResult);
 
  423             toDatePicker.setDate(ins.atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
 
  425             toDatePicker.setDate(null);
 
  429     boolean isValidSearch() {
 
  430         return this.accessedCheckBox.isSelected() ||
 
  431                 this.changedCheckBox.isSelected() ||
 
  432                 this.createdCheckBox.isSelected() ||
 
  433                 this.modifiedCheckBox.isSelected();
 
  436     private javax.swing.JCheckBox accessedCheckBox;
 
  437     private javax.swing.JCheckBox changedCheckBox;
 
  438     private javax.swing.JMenuItem copyMenuItem;
 
  439     private javax.swing.JCheckBox createdCheckBox;
 
  440     private javax.swing.JMenuItem cutMenuItem;
 
  441     private javax.swing.JCheckBox dateCheckBox;
 
  442     private com.github.lgooddatepicker.components.DatePicker fromDatePicker;
 
  443     private javax.swing.JLabel jLabel1;
 
  444     private javax.swing.JLabel jLabel2;
 
  445     private javax.swing.JLabel jLabel3;
 
  446     private javax.swing.JLabel jLabel4;
 
  447     private javax.swing.JCheckBox modifiedCheckBox;
 
  448     private javax.swing.JMenuItem pasteMenuItem;
 
  449     private javax.swing.JPopupMenu rightClickMenu;
 
  450     private javax.swing.JMenuItem selectAllMenuItem;
 
  451     private javax.swing.JComboBox<String> timeZoneComboBox;
 
  452     private com.github.lgooddatepicker.components.DatePicker toDatePicker;
 
  455     void addDateChangeListener() {
 
  456         DateChangeListener dcl = (DateChangeEvent event) -> {
 
  457             firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);            
 
  460         fromDatePicker.addDateChangeListener(dcl);
 
  461         toDatePicker.addDateChangeListener(dcl);