19 package org.sleuthkit.autopsy.communications;
21 import com.google.common.collect.ImmutableSet;
22 import com.google.common.eventbus.Subscribe;
23 import java.awt.event.ItemListener;
24 import java.beans.PropertyChangeListener;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.time.Instant;
28 import java.time.LocalDate;
29 import java.time.LocalDateTime;
30 import java.time.ZoneId;
31 import java.util.Collection;
32 import java.util.EnumSet;
33 import java.util.HashMap;
34 import java.util.List;
36 import java.util.Map.Entry;
38 import java.util.concurrent.ExecutionException;
39 import java.util.logging.Level;
40 import java.util.stream.Collectors;
41 import javax.swing.Box;
42 import javax.swing.BoxLayout;
43 import javax.swing.Icon;
44 import javax.swing.ImageIcon;
45 import javax.swing.JCheckBox;
46 import javax.swing.JLabel;
47 import javax.swing.JPanel;
48 import javax.swing.SwingWorker;
49 import org.openide.util.NbBundle;
62 import org.
sleuthkit.datamodel.CaseDbAccessManager.CaseDbAccessQueryCallback;
64 import org.
sleuthkit.datamodel.CommunicationsFilter.AccountTypeFilter;
65 import org.
sleuthkit.datamodel.CommunicationsFilter.DateRangeFilter;
66 import org.
sleuthkit.datamodel.CommunicationsFilter.DeviceFilter;
67 import org.
sleuthkit.datamodel.CommunicationsFilter.MostRecentFilter;
69 import static org.
sleuthkit.datamodel.Relationship.Type.CALL_LOG;
70 import static org.
sleuthkit.datamodel.Relationship.Type.CONTACT;
71 import static org.
sleuthkit.datamodel.Relationship.Type.MESSAGE;
79 @SuppressWarnings(
"PMD.SingularField")
82 private static final long serialVersionUID = 1L;
90 private final Map<Account.Type, JCheckBox> accountTypeMap = new HashMap<>();
96 private final Map<String, JCheckBox> devicesMap = new HashMap<>();
101 private final PropertyChangeListener ingestListener;
102 private final PropertyChangeListener ingestJobListener;
108 private
boolean needsRefresh;
115 private final ItemListener validationListener;
123 private
boolean deviceAccountTypeEnabled;
127 @NbBundle.Messages({
"refreshText=Refresh Results",
"applyText=Apply"})
131 initalizeDeviceAccountType();
133 deviceRequiredLabel.setVisible(
false);
134 accountTypeRequiredLabel.setVisible(
false);
135 startDatePicker.setDate(LocalDate.now().minusWeeks(3));
136 endDatePicker.setDateToToday();
137 startDatePicker.getSettings().setVetoPolicy(
139 startDate -> endCheckBox.isSelected() ==
false
140 || startDate.compareTo(endDatePicker.getDate()) <= 0
142 endDatePicker.getSettings().setVetoPolicy(
144 endDate -> startCheckBox.isSelected() ==
false
145 || endDate.compareTo(startDatePicker.getDate()) >= 0
149 validationListener = itemEvent -> validateFilters();
158 this.ingestListener = pce -> {
159 String eventType = pce.getPropertyName();
160 if (eventType.equals(DATA_ADDED.toString())) {
163 if (null != eventData
175 this.ingestJobListener = pce -> {
176 String eventType = pce.getPropertyName();
177 if (eventType.equals(COMPLETED.toString())
178 && updateFilters(
true)) {
185 applyFiltersButton.addActionListener(e -> applyFilters());
186 refreshButton.addActionListener(e -> applyFilters());
196 boolean someDevice = devicesMap.values().stream().anyMatch(JCheckBox::isSelected);
197 boolean someAccountType = accountTypeMap.values().stream().anyMatch(JCheckBox::isSelected);
198 boolean validLimit = validateLimitValue();
200 deviceRequiredLabel.setVisible(someDevice ==
false);
201 accountTypeRequiredLabel.setVisible(someAccountType ==
false);
202 limitErrorMsgLabel.setVisible(!validLimit);
204 applyFiltersButton.setEnabled(someDevice && someAccountType && validLimit);
205 refreshButton.setEnabled(someDevice && someAccountType && needsRefresh && validLimit);
206 needsRefreshLabel.setVisible(needsRefresh);
210 String selectedValue = (String) limitComboBox.getSelectedItem();
211 if (selectedValue.trim().equalsIgnoreCase(
"all")) {
215 int value = Integer.parseInt(selectedValue);
217 }
catch (NumberFormatException ex) {
226 void updateAndApplyFilters(
boolean initialState) {
227 updateFilters(initialState);
229 initalizeDateTimeFilters();
240 final SleuthkitCase sleuthkitCase;
244 logger.log(Level.WARNING,
"Unable to perform filter update, update has been cancelled. Case is closed.", ex);
247 boolean newAccountType = updateAccountTypeFilter(initialState, sleuthkitCase);
248 boolean newDeviceFilter = updateDeviceFilter(initialState, sleuthkitCase);
250 return newAccountType || newDeviceFilter;
261 devicesListPane.removeAll();
263 accountTypeMap.clear();
264 accountTypeListPane.removeAll();
266 initalizeDeviceAccountType();
272 super.removeNotify();
278 CheckBoxIconPanel panel = createAccoutTypeCheckBoxPanel(Account.Type.DEVICE,
true);
279 accountTypeMap.put(Account.Type.DEVICE, panel.getCheckBox());
280 accountTypeListPane.add(panel);
293 boolean newOneFound =
false;
295 List<Account.Type> accountTypesInUse = sleuthkitCase.getCommunicationsManager().getAccountTypesInUse();
297 for (Account.Type type : accountTypesInUse) {
299 if (!accountTypeMap.containsKey(type) && !type.equals(Account.Type.CREDIT_CARD)) {
300 CheckBoxIconPanel panel = createAccoutTypeCheckBoxPanel(type, selected);
301 accountTypeMap.put(type, panel.getCheckBox());
302 accountTypeListPane.add(panel);
308 }
catch (TskCoreException ex) {
309 logger.log(Level.WARNING,
"Unable to update to update Account Types Filter", ex);
312 accountTypeListPane.revalidate();
328 CheckBoxIconPanel panel =
new CheckBoxIconPanel(
329 type.getDisplayName(),
332 panel.setSelected(initalState);
333 panel.addItemListener(validationListener);
347 boolean newOneFound =
false;
349 for (DataSource dataSource : sleuthkitCase.getDataSources()) {
350 String dsName = sleuthkitCase.getContentById(dataSource.getId()).getName();
351 if (devicesMap.containsKey(dataSource.getDeviceId())) {
355 final JCheckBox jCheckBox =
new JCheckBox(dsName, selected);
356 jCheckBox.addItemListener(validationListener);
357 devicesListPane.add(jCheckBox);
358 devicesMap.put(dataSource.getDeviceId(), jCheckBox);
363 }
catch (TskCoreException tskCoreException) {
364 logger.log(Level.SEVERE,
"There was a error loading the datasources for the case.", tskCoreException);
368 devicesListPane.revalidate();
381 List<CommunicationsFilter.SubFilter> subFilters = commFilter.getAndFilters();
382 subFilters.forEach(subFilter -> {
383 if (subFilter instanceof DeviceFilter) {
384 setDeviceFilter((DeviceFilter) subFilter);
385 }
else if (subFilter instanceof AccountTypeFilter) {
386 setAccountTypeFilter((AccountTypeFilter) subFilter);
387 }
else if (subFilter instanceof MostRecentFilter) {
388 setMostRecentFilter((MostRecentFilter) subFilter);
399 Collection<String> deviceIDs = deviceFilter.getDevices();
400 devicesMap.forEach((type, cb) -> {
401 cb.setSelected(deviceIDs.contains(type));
413 accountTypeMap.forEach((type, cb) -> {
414 cb.setSelected(typeFilter.getAccountTypes().contains(type));
425 startDatePicker.setDate(state.getDate());
426 startCheckBox.setSelected(state.isEnabled());
427 startDatePicker.setEnabled(state.isEnabled());
437 endDatePicker.setDate(state.getDate());
438 endCheckBox.setSelected(state.isEnabled());
439 endDatePicker.setEnabled(state.isEnabled());
449 int limit = filter.getLimit();
451 limitComboBox.setSelectedItem(filter.getLimit());
453 limitComboBox.setSelectedItem(
"All");
458 void filtersBack(CVTEvents.StateChangeEvent event) {
459 if (event.getCommunicationsState().getCommunicationsFilter() != null) {
460 setFilters(event.getCommunicationsState().getCommunicationsFilter());
461 setStartDateControlState(event.getCommunicationsState().getStartControlState());
462 setEndDateControlState(event.getCommunicationsState().getEndControlState());
463 needsRefresh =
false;
473 @SuppressWarnings(
"unchecked")
475 private
void initComponents() {
476 java.awt.GridBagConstraints gridBagConstraints;
478 setLayout(
new java.awt.GridBagLayout());
480 scrollPane.setBorder(null);
481 scrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
482 scrollPane.setAutoscrolls(
true);
484 mainPanel.setLayout(
new java.awt.GridBagLayout());
486 limitPane.setLayout(
new java.awt.GridBagLayout());
488 mostRecentLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.mostRecentLabel.text"));
489 gridBagConstraints =
new java.awt.GridBagConstraints();
490 gridBagConstraints.gridx = 0;
491 gridBagConstraints.gridy = 1;
492 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
493 gridBagConstraints.insets =
new java.awt.Insets(0, 9, 0, 9);
494 limitPane.add(mostRecentLabel, gridBagConstraints);
496 limitComboBox.setEditable(
true);
497 limitComboBox.setModel(
new javax.swing.DefaultComboBoxModel<>(
new String[] {
"All",
"10000",
"5000",
"1000",
"500",
"100" }));
498 limitComboBox.addActionListener(
new java.awt.event.ActionListener() {
499 public void actionPerformed(java.awt.event.ActionEvent evt) {
500 limitComboBoxActionPerformed(evt);
503 gridBagConstraints =
new java.awt.GridBagConstraints();
504 gridBagConstraints.gridx = 1;
505 gridBagConstraints.gridy = 1;
506 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
507 limitPane.add(limitComboBox, gridBagConstraints);
509 limitTitlePanel.setLayout(
new java.awt.GridBagLayout());
511 limitHeaderLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.limitHeaderLabel.text"));
512 gridBagConstraints =
new java.awt.GridBagConstraints();
513 gridBagConstraints.gridx = 0;
514 gridBagConstraints.gridy = 0;
515 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
516 gridBagConstraints.weightx = 1.0;
517 limitTitlePanel.add(limitHeaderLabel, gridBagConstraints);
519 limitErrorMsgLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/error-icon-16.png")));
520 limitErrorMsgLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.limitErrorMsgLabel.text"));
521 limitErrorMsgLabel.setForeground(
new java.awt.Color(255, 0, 0));
522 limitErrorMsgLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
523 gridBagConstraints =
new java.awt.GridBagConstraints();
524 gridBagConstraints.gridx = 1;
525 gridBagConstraints.gridy = 0;
526 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
527 limitTitlePanel.add(limitErrorMsgLabel, gridBagConstraints);
529 gridBagConstraints =
new java.awt.GridBagConstraints();
530 gridBagConstraints.gridx = 0;
531 gridBagConstraints.gridy = 0;
532 gridBagConstraints.gridwidth = 2;
533 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
534 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
535 gridBagConstraints.weightx = 1.0;
536 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 9, 0);
537 limitPane.add(limitTitlePanel, gridBagConstraints);
539 gridBagConstraints =
new java.awt.GridBagConstraints();
540 gridBagConstraints.gridx = 0;
541 gridBagConstraints.gridy = 4;
542 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
543 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
544 gridBagConstraints.weightx = 1.0;
545 gridBagConstraints.weighty = 1.0;
546 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 15, 25);
547 mainPanel.add(limitPane, gridBagConstraints);
549 startDatePicker.setEnabled(
false);
551 dateRangeLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/calendar.png")));
552 dateRangeLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.dateRangeLabel.text"));
554 startCheckBox.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.startCheckBox.text"));
555 startCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
556 public void stateChanged(javax.swing.event.ChangeEvent evt) {
557 startCheckBoxStateChanged(evt);
561 endCheckBox.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.endCheckBox.text"));
562 endCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
563 public void stateChanged(javax.swing.event.ChangeEvent evt) {
564 endCheckBoxStateChanged(evt);
568 endDatePicker.setEnabled(
false);
570 javax.swing.GroupLayout dateRangePaneLayout =
new javax.swing.GroupLayout(dateRangePane);
571 dateRangePane.setLayout(dateRangePaneLayout);
572 dateRangePaneLayout.setHorizontalGroup(
573 dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
574 .addGroup(dateRangePaneLayout.createSequentialGroup()
575 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
576 .addComponent(dateRangeLabel)
577 .addGroup(dateRangePaneLayout.createSequentialGroup()
579 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
580 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, dateRangePaneLayout.createSequentialGroup()
581 .addComponent(endCheckBox)
583 .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
584 .addGroup(dateRangePaneLayout.createSequentialGroup()
585 .addComponent(startCheckBox)
587 .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
588 .addGap(0, 0, Short.MAX_VALUE))
591 dateRangePaneLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {endCheckBox, startCheckBox});
593 dateRangePaneLayout.setVerticalGroup(
594 dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
595 .addGroup(dateRangePaneLayout.createSequentialGroup()
596 .addComponent(dateRangeLabel)
598 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
599 .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
600 .addComponent(startCheckBox))
601 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
602 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
603 .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
604 .addComponent(endCheckBox)))
607 gridBagConstraints =
new java.awt.GridBagConstraints();
608 gridBagConstraints.gridx = 0;
609 gridBagConstraints.gridy = 3;
610 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
611 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
612 gridBagConstraints.weightx = 1.0;
613 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 0, 25);
614 mainPanel.add(dateRangePane, gridBagConstraints);
616 devicesPane.setLayout(
new java.awt.GridBagLayout());
618 unCheckAllDevicesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.unCheckAllDevicesButton.text"));
619 unCheckAllDevicesButton.addActionListener(
new java.awt.event.ActionListener() {
620 public void actionPerformed(java.awt.event.ActionEvent evt) {
621 unCheckAllDevicesButtonActionPerformed(evt);
624 gridBagConstraints =
new java.awt.GridBagConstraints();
625 gridBagConstraints.gridx = 0;
626 gridBagConstraints.gridy = 2;
627 gridBagConstraints.gridwidth = 2;
628 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
629 gridBagConstraints.weightx = 1.0;
630 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 9);
631 devicesPane.add(unCheckAllDevicesButton, gridBagConstraints);
633 devicesLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/image.png")));
634 devicesLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.devicesLabel.text"));
635 gridBagConstraints =
new java.awt.GridBagConstraints();
636 gridBagConstraints.gridx = 0;
637 gridBagConstraints.gridy = 0;
638 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
639 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 9, 0);
640 devicesPane.add(devicesLabel, gridBagConstraints);
642 checkAllDevicesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.checkAllDevicesButton.text"));
643 checkAllDevicesButton.addActionListener(
new java.awt.event.ActionListener() {
644 public void actionPerformed(java.awt.event.ActionEvent evt) {
645 checkAllDevicesButtonActionPerformed(evt);
648 gridBagConstraints =
new java.awt.GridBagConstraints();
649 gridBagConstraints.gridx = 2;
650 gridBagConstraints.gridy = 2;
651 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
652 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 0);
653 devicesPane.add(checkAllDevicesButton, gridBagConstraints);
655 devicesScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
656 devicesScrollPane.setMaximumSize(
new java.awt.Dimension(32767, 30));
657 devicesScrollPane.setMinimumSize(
new java.awt.Dimension(27, 30));
658 devicesScrollPane.setPreferredSize(
new java.awt.Dimension(3, 30));
660 devicesListPane.setMinimumSize(
new java.awt.Dimension(4, 100));
661 devicesListPane.setLayout(
new javax.swing.BoxLayout(devicesListPane, javax.swing.BoxLayout.Y_AXIS));
662 devicesScrollPane.setViewportView(devicesListPane);
664 gridBagConstraints =
new java.awt.GridBagConstraints();
665 gridBagConstraints.gridx = 0;
666 gridBagConstraints.gridy = 1;
667 gridBagConstraints.gridwidth = 3;
668 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
669 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
670 gridBagConstraints.weightx = 1.0;
671 gridBagConstraints.weighty = 1.0;
672 devicesPane.add(devicesScrollPane, gridBagConstraints);
674 deviceRequiredLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/error-icon-16.png")));
675 deviceRequiredLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.deviceRequiredLabel.text"));
676 deviceRequiredLabel.setForeground(
new java.awt.Color(255, 0, 0));
677 deviceRequiredLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
678 gridBagConstraints =
new java.awt.GridBagConstraints();
679 gridBagConstraints.gridx = 1;
680 gridBagConstraints.gridy = 0;
681 gridBagConstraints.gridwidth = 2;
682 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
683 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 9, 0);
684 devicesPane.add(deviceRequiredLabel, gridBagConstraints);
686 gridBagConstraints =
new java.awt.GridBagConstraints();
687 gridBagConstraints.gridx = 0;
688 gridBagConstraints.gridy = 2;
689 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
690 gridBagConstraints.ipady = 100;
691 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
692 gridBagConstraints.weightx = 1.0;
693 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 0, 25);
694 mainPanel.add(devicesPane, gridBagConstraints);
696 accountTypesPane.setLayout(
new java.awt.GridBagLayout());
698 unCheckAllAccountTypesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.unCheckAllAccountTypesButton.text"));
699 unCheckAllAccountTypesButton.addActionListener(
new java.awt.event.ActionListener() {
700 public void actionPerformed(java.awt.event.ActionEvent evt) {
701 unCheckAllAccountTypesButtonActionPerformed(evt);
704 gridBagConstraints =
new java.awt.GridBagConstraints();
705 gridBagConstraints.gridx = 0;
706 gridBagConstraints.gridy = 2;
707 gridBagConstraints.gridwidth = 2;
708 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
709 gridBagConstraints.weightx = 1.0;
710 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 9);
711 accountTypesPane.add(unCheckAllAccountTypesButton, gridBagConstraints);
713 accountTypesLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/accounts.png")));
714 accountTypesLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.accountTypesLabel.text"));
715 gridBagConstraints =
new java.awt.GridBagConstraints();
716 gridBagConstraints.gridx = 0;
717 gridBagConstraints.gridy = 0;
718 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
719 accountTypesPane.add(accountTypesLabel, gridBagConstraints);
721 checkAllAccountTypesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.checkAllAccountTypesButton.text"));
722 checkAllAccountTypesButton.addActionListener(
new java.awt.event.ActionListener() {
723 public void actionPerformed(java.awt.event.ActionEvent evt) {
724 checkAllAccountTypesButtonActionPerformed(evt);
727 gridBagConstraints =
new java.awt.GridBagConstraints();
728 gridBagConstraints.gridx = 2;
729 gridBagConstraints.gridy = 2;
730 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
731 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 0);
732 accountTypesPane.add(checkAllAccountTypesButton, gridBagConstraints);
734 accountTypesScrollPane.setMaximumSize(
new java.awt.Dimension(32767, 210));
735 accountTypesScrollPane.setMinimumSize(
new java.awt.Dimension(20, 210));
736 accountTypesScrollPane.setName(
"");
737 accountTypesScrollPane.setPreferredSize(
new java.awt.Dimension(2, 210));
739 accountTypeListPane.setLayout(
new javax.swing.BoxLayout(accountTypeListPane, javax.swing.BoxLayout.PAGE_AXIS));
740 accountTypesScrollPane.setViewportView(accountTypeListPane);
742 gridBagConstraints =
new java.awt.GridBagConstraints();
743 gridBagConstraints.gridx = 0;
744 gridBagConstraints.gridy = 1;
745 gridBagConstraints.gridwidth = 3;
746 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
747 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
748 gridBagConstraints.weightx = 1.0;
749 gridBagConstraints.weighty = 1.0;
750 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 0);
751 accountTypesPane.add(accountTypesScrollPane, gridBagConstraints);
753 accountTypeRequiredLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/error-icon-16.png")));
754 accountTypeRequiredLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.accountTypeRequiredLabel.text"));
755 accountTypeRequiredLabel.setForeground(
new java.awt.Color(255, 0, 0));
756 accountTypeRequiredLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
757 gridBagConstraints =
new java.awt.GridBagConstraints();
758 gridBagConstraints.gridx = 1;
759 gridBagConstraints.gridy = 0;
760 gridBagConstraints.gridwidth = 2;
761 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
762 accountTypesPane.add(accountTypeRequiredLabel, gridBagConstraints);
764 gridBagConstraints =
new java.awt.GridBagConstraints();
765 gridBagConstraints.gridx = 0;
766 gridBagConstraints.gridy = 1;
767 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
768 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
769 gridBagConstraints.weightx = 1.0;
770 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 0, 25);
771 mainPanel.add(accountTypesPane, gridBagConstraints);
773 topPane.setLayout(
new java.awt.GridBagLayout());
775 filtersTitleLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/communications/images/funnel.png")));
776 filtersTitleLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.filtersTitleLabel.text"));
777 gridBagConstraints =
new java.awt.GridBagConstraints();
778 gridBagConstraints.gridx = 0;
779 gridBagConstraints.gridy = 0;
780 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
781 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
782 gridBagConstraints.weightx = 1.0;
783 topPane.add(filtersTitleLabel, gridBagConstraints);
785 refreshButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/communications/images/arrow-circle-double-135.png")));
786 refreshButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.refreshButton.text"));
787 gridBagConstraints =
new java.awt.GridBagConstraints();
788 gridBagConstraints.gridx = 2;
789 gridBagConstraints.gridy = 0;
790 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
791 topPane.add(refreshButton, gridBagConstraints);
793 applyFiltersButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/communications/images/tick.png")));
794 applyFiltersButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.applyFiltersButton.text"));
795 gridBagConstraints =
new java.awt.GridBagConstraints();
796 gridBagConstraints.gridx = 1;
797 gridBagConstraints.gridy = 0;
798 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
799 gridBagConstraints.weightx = 1.0;
800 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 0, 5);
801 topPane.add(applyFiltersButton, gridBagConstraints);
803 needsRefreshLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.needsRefreshLabel.text"));
804 needsRefreshLabel.setForeground(
new java.awt.Color(255, 0, 0));
805 gridBagConstraints =
new java.awt.GridBagConstraints();
806 gridBagConstraints.gridx = 0;
807 gridBagConstraints.gridy = 1;
808 gridBagConstraints.gridwidth = 3;
809 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
810 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
811 gridBagConstraints.weightx = 1.0;
812 topPane.add(needsRefreshLabel, gridBagConstraints);
814 gridBagConstraints =
new java.awt.GridBagConstraints();
815 gridBagConstraints.gridx = 0;
816 gridBagConstraints.gridy = 0;
817 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
818 gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_END;
819 gridBagConstraints.weightx = 1.0;
820 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 0, 25);
821 mainPanel.add(topPane, gridBagConstraints);
823 scrollPane.setViewportView(mainPanel);
825 gridBagConstraints =
new java.awt.GridBagConstraints();
826 gridBagConstraints.gridx = 0;
827 gridBagConstraints.gridy = 0;
828 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
829 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
830 gridBagConstraints.weightx = 1.0;
831 gridBagConstraints.weighty = 1.0;
832 gridBagConstraints.insets =
new java.awt.Insets(9, 15, 0, 0);
833 add(scrollPane, gridBagConstraints);
840 CVTEvents.getCVTEventBus().post(
new CVTEvents.FilterChangeEvent(getFilter(), getStartControlState(), getEndControlState()));
841 needsRefresh =
false;
851 CommunicationsFilter commsFilter =
new CommunicationsFilter();
852 commsFilter.addAndFilter(getDeviceFilter());
853 commsFilter.addAndFilter(getAccountTypeFilter());
854 commsFilter.addAndFilter(getDateRangeFilter());
855 commsFilter.addAndFilter(
new CommunicationsFilter.RelationshipTypeFilter(
856 ImmutableSet.of(CALL_LOG, MESSAGE, CONTACT)));
857 commsFilter.addAndFilter(getMostRecentFilter());
867 DeviceFilter deviceFilter =
new DeviceFilter(
868 devicesMap.entrySet().stream()
869 .filter(entry -> entry.getValue().isSelected())
871 .collect(Collectors.toSet()));
881 AccountTypeFilter accountTypeFilter =
new AccountTypeFilter(
882 accountTypeMap.entrySet().stream()
883 .filter(entry -> entry.getValue().isSelected())
884 .map(entry -> entry.getKey())
885 .collect(Collectors.toSet()));
886 return accountTypeFilter;
897 return new DateRangeFilter(startCheckBox.isSelected() ? startDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0,
898 endCheckBox.isSelected() ? endDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0);
908 String value = (String) limitComboBox.getSelectedItem();
909 if (value.trim().equalsIgnoreCase(
"all")) {
910 return new MostRecentFilter(-1);
913 int count = Integer.parseInt(value);
914 return new MostRecentFilter(count);
915 }
catch (NumberFormatException ex) {
922 return new DateControlState(startDatePicker.getDate(), startCheckBox.isSelected());
926 return new DateControlState(endDatePicker.getDate(), endCheckBox.isSelected());
935 private
void setAllAccountTypesSelected(
boolean selected) {
936 setAllSelected(accountTypeMap, selected);
945 private
void setAllDevicesSelected(
boolean selected) {
946 setAllSelected(devicesMap, selected);
957 private
void setAllSelected(Map<?, JCheckBox> map,
boolean selected) {
958 map.values().forEach(box -> box.setSelected(selected));
966 Case currentCase = null;
970 logger.log(Level.INFO,
"Tried to intialize communication filters date range filters without an open case, using default values");
973 if (currentCase == null) {
974 setDateTimeFiltersToDefault();
979 if (!currentCase.equals(openCase)) {
980 setDateTimeFiltersToDefault();
981 openCase = currentCase;
982 (
new DatePickerWorker()).execute();
987 startDatePicker.setDate(LocalDate.now().minusWeeks(3));
988 endDatePicker.setDate(LocalDate.now());
992 setAllAccountTypesSelected(
false);
996 setAllAccountTypesSelected(
true);
1000 setAllDevicesSelected(
false);
1004 setAllDevicesSelected(
true);
1008 startDatePicker.setEnabled(startCheckBox.isSelected());
1013 endDatePicker.setEnabled(endCheckBox.isSelected());
1026 final class DateControlState {
1028 private final LocalDate date;
1029 private final boolean enabled;
1038 protected DateControlState(LocalDate date,
boolean enabled) {
1040 this.enabled = enabled;
1048 public LocalDate getDate() {
1057 public boolean isEnabled() {
1064 private final javax.swing.JPanel accountTypeListPane =
new javax.swing.JPanel();
1065 private final javax.swing.JLabel accountTypeRequiredLabel =
new javax.swing.JLabel();
1066 private final javax.swing.JLabel accountTypesLabel =
new javax.swing.JLabel();
1067 private final javax.swing.JPanel accountTypesPane =
new javax.swing.JPanel();
1068 private final javax.swing.JScrollPane accountTypesScrollPane =
new javax.swing.JScrollPane();
1069 private final javax.swing.JButton applyFiltersButton =
new javax.swing.JButton();
1070 private final javax.swing.JButton checkAllAccountTypesButton =
new javax.swing.JButton();
1071 private final javax.swing.JButton checkAllDevicesButton =
new javax.swing.JButton();
1072 private final javax.swing.JLabel dateRangeLabel =
new javax.swing.JLabel();
1073 private final javax.swing.JPanel dateRangePane =
new javax.swing.JPanel();
1074 private final javax.swing.JLabel deviceRequiredLabel =
new javax.swing.JLabel();
1075 private final javax.swing.JLabel devicesLabel =
new javax.swing.JLabel();
1076 private final javax.swing.JPanel devicesListPane =
new javax.swing.JPanel();
1077 private final javax.swing.JPanel devicesPane =
new javax.swing.JPanel();
1078 private final javax.swing.JScrollPane devicesScrollPane =
new javax.swing.JScrollPane();
1079 private final javax.swing.JCheckBox endCheckBox =
new javax.swing.JCheckBox();
1080 private final com.github.lgooddatepicker.components.DatePicker endDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
1081 private final javax.swing.JLabel filtersTitleLabel =
new javax.swing.JLabel();
1082 private final javax.swing.JComboBox<String> limitComboBox =
new javax.swing.JComboBox<>();
1083 private final javax.swing.JLabel limitErrorMsgLabel =
new javax.swing.JLabel();
1084 private final javax.swing.JLabel limitHeaderLabel =
new javax.swing.JLabel();
1085 private final javax.swing.JPanel limitPane =
new javax.swing.JPanel();
1086 private final javax.swing.JPanel limitTitlePanel =
new javax.swing.JPanel();
1087 private final javax.swing.JPanel mainPanel =
new javax.swing.JPanel();
1088 private final javax.swing.JLabel mostRecentLabel =
new javax.swing.JLabel();
1089 private final javax.swing.JLabel needsRefreshLabel =
new javax.swing.JLabel();
1090 private final javax.swing.JButton refreshButton =
new javax.swing.JButton();
1091 private final javax.swing.JScrollPane scrollPane =
new javax.swing.JScrollPane();
1092 private final javax.swing.JCheckBox startCheckBox =
new javax.swing.JCheckBox();
1093 private final com.github.lgooddatepicker.components.DatePicker startDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
1094 private final javax.swing.JPanel topPane =
new javax.swing.JPanel();
1095 private final javax.swing.JButton unCheckAllAccountTypesButton =
new javax.swing.JButton();
1096 private final javax.swing.JButton unCheckAllDevicesButton =
new javax.swing.JButton();
1104 final class CheckBoxIconPanel
extends JPanel {
1106 private static final long serialVersionUID = 1L;
1108 private final JCheckBox checkbox;
1109 private final JLabel label;
1117 private CheckBoxIconPanel(String labelText, Icon image) {
1118 checkbox =
new JCheckBox();
1119 label =
new JLabel(labelText);
1120 label.setIcon(image);
1121 setLayout(
new BoxLayout(
this, BoxLayout.X_AXIS));
1125 add(Box.createHorizontalGlue());
1133 void setSelected(
boolean selected) {
1134 checkbox.setSelected(selected);
1138 public void setEnabled(
boolean enabled) {
1139 checkbox.setEnabled(enabled);
1147 JCheckBox getCheckBox() {
1156 void addItemListener(ItemListener l) {
1157 checkbox.addItemListener(l);
1165 class FilterPanelQueryCallback
implements CaseDbAccessQueryCallback {
1168 public void process(ResultSet rs) {
1173 final class DatePickerWorker
extends SwingWorker<Map<String, Integer>, Void> {
1176 protected Map<String, Integer> doInBackground() throws Exception {
1177 if (openCase == null) {
1181 Map<String, Integer> resultMap =
new HashMap<>();
1182 String queryString =
"max(date_time) as end, min(date_time) as start from account_relationships";
1184 openCase.getSleuthkitCase().getCaseDbAccessManager().select(queryString,
new FilterPanelQueryCallback() {
1186 public void process(ResultSet rs) {
1189 int startDate = rs.getInt(
"start");
1190 int endDate = rs.getInt(
"end");
1192 resultMap.put(
"start", startDate);
1193 resultMap.put(
"end", endDate);
1195 }
catch (SQLException ex) {
1197 logger.log(Level.WARNING, String.format(
"SQL Exception thrown from Query: %s", queryString), ex);
1206 protected void done() {
1208 Map<String, Integer> resultMap =
get();
1209 if (resultMap != null) {
1210 Integer start = resultMap.get(
"start");
1211 Integer end = resultMap.get(
"end");
1213 if (start != null && start != 0) {
1214 startDatePicker.setDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(start), Utils.getUserPreferredZoneId()).toLocalDate());
1217 if (end != null && end != 0) {
1218 endDatePicker.setDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(end), Utils.getUserPreferredZoneId()).toLocalDate());
1221 }
catch (InterruptedException | ExecutionException ex) {
1222 logger.log(Level.WARNING,
"Exception occured after date time sql query", ex);
BlackboardArtifact.Type getBlackboardArtifactType()
void unCheckAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt)
void removeIngestModuleEventListener(final PropertyChangeListener listener)
MostRecentFilter getMostRecentFilter()
void setEndDateControlState(DateControlState state)
static synchronized IngestManager getInstance()
void initalizeDeviceAccountType()
void setMostRecentFilter(MostRecentFilter filter)
void setDeviceFilter(DeviceFilter deviceFilter)
void unCheckAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt)
void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt)
void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt)
void removeIngestJobEventListener(final PropertyChangeListener listener)
CheckBoxIconPanel createAccoutTypeCheckBoxPanel(Account.Type type, boolean initalState)
void setStartDateControlState(DateControlState state)
void limitComboBoxActionPerformed(java.awt.event.ActionEvent evt)
static final String DISPLAY_TIMES_IN_LOCAL_TIME
void addIngestJobEventListener(final PropertyChangeListener listener)
void setAccountTypeFilter(AccountTypeFilter typeFilter)
CommunicationsFilter getFilter()
void setFilters(CommunicationsFilter commFilter)
SleuthkitCase getSleuthkitCase()
void checkAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt)
static ZoneId getUserPreferredZoneId()
boolean updateFilters(boolean initialState)
DateControlState getStartControlState()
boolean validateLimitValue()
void addIngestModuleEventListener(final PropertyChangeListener listener)
void initalizeDateTimeFilters()
void setDateTimeFiltersToDefault()
DateControlState getEndControlState()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static void addChangeListener(PreferenceChangeListener listener)
void checkAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt)
static final String getIconFilePath(Account.Type type)
boolean updateAccountTypeFilter(boolean selected, SleuthkitCase sleuthkitCase)
boolean updateDeviceFilter(boolean selected, SleuthkitCase sleuthkitCase)
DeviceFilter getDeviceFilter()
DateRangeFilter getDateRangeFilter()
AccountTypeFilter getAccountTypeFilter()
static final String TIME_ZONE_FOR_DISPLAYS