diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java index 205db56998..3291c5ae42 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java @@ -42,6 +42,7 @@ import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; +import org.openide.util.NbBundle.Messages; /** * Filters file date properties (modified/created/etc.. times) @@ -79,25 +80,10 @@ class DateSearchFilter extends AbstractFileSearchFilter { String query = "NULL"; DateSearchPanel panel = this.getComponent(); - // first, get the selected timeZone from the dropdown list - String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString(); - String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID - TimeZone selectedTZ = TimeZone.getTimeZone(tzID); // - // convert the date from the selected timezone to get the GMT long fromDate = 0; String startDateValue = panel.getDateFromTextField().getText(); - Calendar startDate = null; - try { - DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); - sdf.setTimeZone(selectedTZ); // get the time in the selected timezone - Date temp = sdf.parse(startDateValue); - - startDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS - startDate.setTime(temp); // convert to GMT - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } + Calendar startDate = getCalendarDate(startDateValue); if (!startDateValue.isEmpty()) { if (startDate != null) { fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds @@ -106,31 +92,13 @@ class DateSearchFilter extends AbstractFileSearchFilter { long toDate = 0; String endDateValue = panel.getDateToTextField().getText(); - Calendar endDate = null; - try { - DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); - sdf.setTimeZone(selectedTZ); // get the time in the selected timezone - Date temp2 = sdf.parse(endDateValue); - - endDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS - endDate.setTime(temp2); // convert to GMT - endDate.set(Calendar.HOUR, endDate.get(Calendar.HOUR) + 24); // get the next 24 hours - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } + Calendar endDate = getCalendarDate(endDateValue); if (!endDateValue.isEmpty()) { if (endDate != null) { toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds } } - // If they put the dates in backwards, help them out. - if (fromDate > toDate) { - long temp = toDate; - toDate = fromDate; - fromDate = temp; - } - final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected(); final boolean changedChecked = panel.getChangedCheckBox().isSelected(); final boolean accessedChecked = panel.getAccessedCheckBox().isSelected(); @@ -206,14 +174,56 @@ class DateSearchFilter extends AbstractFileSearchFilter { return timeZones; } + private TimeZone getSelectedTimeZone() { + String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString(); + String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID + TimeZone selectedTZ = TimeZone.getTimeZone(tzID); // + return selectedTZ; + } + + private Calendar getCalendarDate(String dateValue) { + TimeZone selectedTZ = getSelectedTimeZone(); + Calendar inputDate = null; + try { + DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); + sdf.setTimeZone(selectedTZ); // get the time in the selected timezone + Date temp = sdf.parse(dateValue); + + inputDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS + inputDate.setTime(temp); // convert to GMT + } catch (ParseException ex) { + // for now, no need to show the error message to the user here + } + return inputDate; + } + @Override public void addActionListener(ActionListener l) { getComponent().addActionListener(l); } @Override + @Messages ({ + "DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.", + "DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected." + }) public boolean isValid() { - return this.getComponent().isValidSearch(); + + DateSearchPanel panel = this.getComponent(); + Calendar startDate = getCalendarDate(panel.getDateFromTextField().getText()); + Calendar endDate = getCalendarDate(panel.getDateToTextField().getText()); + + if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) { + setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate()); + return false; + } + + if (!panel.isValidSearch()) { + setLastError(Bundle.DateSearchFilter_errorMessage_noCheckboxSelected()); + return false; + } + + return true; } /** diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form index e92d57fdd9..59082745da 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form @@ -149,6 +149,7 @@ + @@ -208,6 +209,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java index 7867a5ebd6..b9f490041b 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java @@ -29,6 +29,8 @@ import javax.swing.JComboBox; import javax.swing.JFormattedTextField; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; /** * Subpanel with controls for file data filtering. @@ -50,6 +52,7 @@ class DateSearchPanel extends javax.swing.JPanel { dateFromTextField.setComponentPopupMenu(rightClickMenu); dateToTextField.setComponentPopupMenu(rightClickMenu); + ActionListener actList = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -74,6 +77,41 @@ class DateSearchPanel extends javax.swing.JPanel { copyMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList); + this.dateFromTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void removeUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void changedUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + }); + + this.dateToTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void removeUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void changedUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + }); + + this.setComponentsEnabled(); } @@ -176,6 +214,7 @@ class DateSearchPanel extends javax.swing.JPanel { selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.selectAllMenuItem.text")); // NOI18N rightClickMenu.add(selectAllMenuItem); + dateToTextField.setEditable(false); dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() { public void focusLost(java.awt.event.FocusEvent evt) { @@ -197,6 +236,7 @@ class DateSearchPanel extends javax.swing.JPanel { jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N + dateFromTextField.setEditable(false); dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() { public void focusLost(java.awt.event.FocusEvent evt) { @@ -365,6 +405,7 @@ class DateSearchPanel extends javax.swing.JPanel { if (evt.getNewValue() instanceof Date) { setToDate((Date) evt.getNewValue()); } + }//GEN-LAST:event_dateToPopupChanged private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed @@ -399,6 +440,7 @@ class DateSearchPanel extends javax.swing.JPanel { if (date != null) { dateStringResult = dateFormat.format(date); } + dateFromTextField.setText(dateStringResult); dateFromButtonCalendar.setTargetDate(date); } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java index 2a27be8297..f6c72df611 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java @@ -27,7 +27,6 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java index 951f4b206e..d77fe5826e 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionListener; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; /** @@ -60,7 +61,25 @@ class HashSearchFilter extends AbstractFileSearchFilter { } @Override + @Messages({ + "HashSearchFilter.errorMessage.emptyHash=Hash data is empty.", + "# {0} - hash data length", "HashSearchFilter.errorMessage.wrongLength=Input length({0}), doesn''t match the MD5 length(32).", + "HashSearchFilter.errorMessage.wrongCharacter=MD5 contains invalid hex characters." + }) public boolean isValid() { - return !this.getComponent().getSearchTextField().getText().isEmpty(); + String inputHashData = this.getComponent().getSearchTextField().getText(); + if (inputHashData.isEmpty()) { + setLastError(Bundle.HashSearchFilter_errorMessage_emptyHash()); + return false; + } + if (inputHashData.length() != 32) { + setLastError(Bundle.HashSearchFilter_errorMessage_wrongLength(inputHashData.length())); + return false; + } + if (!inputHashData.matches("[0-9a-fA-F]+")) { + setLastError(Bundle.HashSearchFilter_errorMessage_wrongCharacter()); + return false; + } + return true; } } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java index 5f52afa035..677f0116e9 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionListener; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.TskData.FileKnown; /** @@ -85,7 +86,14 @@ class KnownStatusSearchFilter extends AbstractFileSearchFilter { } @Override + @Messages ({ + "MimeTypeFilter.errorMessage.emptyMimeType=At least one MIME type must be selected." + }) public boolean isValid() { - return !this.getComponent().getMimeTypesSelected().isEmpty(); + if(this.getComponent().getMimeTypesSelected().isEmpty()){ + setLastError(Bundle.MimeTypeFilter_errorMessage_emptyMimeType()); + return false; + } + return true; } } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java index ee70ebd5e1..2b204c8ca8 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionListener; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; /** @@ -64,7 +65,14 @@ class NameSearchFilter extends AbstractFileSearchFilter { } @Override + @Messages ({ + "NameSearchFilter.errorMessage.emtpyName=Please input a name to search." + }) public boolean isValid() { - return !this.getComponent().getSearchTextField().getText().isEmpty(); + if(this.getComponent().getSearchTextField().getText().isEmpty()) { + setLastError(Bundle.NameSearchFilter_errorMessage_emtpyName()); + return false; + } + return true; } } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java index ca43dac7e0..cf5d4f9e73 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionListener; import javax.swing.JComboBox; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; /** @@ -74,7 +75,23 @@ class SizeSearchFilter extends AbstractFileSearchFilter { } @Override + @Messages ({ + "SizeSearchFilter.errorMessage.nonNegativeNumber=Input size data is a negative number.", + "SizeSearchFilter.errorMessage.notANumber=Input size data is not a number." + }) public boolean isValid() { + String input = this.getComponent().getSizeTextField().getText(); + + try { + int inputInt = Integer.parseInt(input); + if (inputInt < 0) { + setLastError(Bundle.SizeSearchFilter_errorMessage_nonNegativeNumber()); + return false; + } + } catch (NumberFormatException | NullPointerException e) { + setLastError(Bundle.SizeSearchFilter_errorMessage_notANumber()); + return false; + } return true; } } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java index 3add979247..51aa688619 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java @@ -25,6 +25,8 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFormattedTextField; import javax.swing.JMenuItem; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; /** * @@ -65,6 +67,24 @@ class SizeSearchPanel extends javax.swing.JPanel { copyMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList); + this.sizeTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void removeUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void changedUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + }); + + }