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;
70 import static org.
sleuthkit.datamodel.Relationship.Type.CALL_LOG;
71 import static org.
sleuthkit.datamodel.Relationship.Type.CONTACT;
72 import static org.
sleuthkit.datamodel.Relationship.Type.MESSAGE;
80 @SuppressWarnings(
"PMD.SingularField")
83 private static final long serialVersionUID = 1L;
91 private final Map<Account.Type, JCheckBox> accountTypeMap = new HashMap<>();
97 private final Map<String, JCheckBox> devicesMap = new HashMap<>();
102 private final PropertyChangeListener ingestListener;
103 private final PropertyChangeListener ingestJobListener;
109 private
boolean needsRefresh;
116 private final ItemListener validationListener;
124 private
boolean deviceAccountTypeEnabled;
128 @NbBundle.Messages({
"refreshText=Refresh Results",
"applyText=Apply"})
132 CheckBoxIconPanel panel = createAccoutTypeCheckBoxPanel(Account.Type.DEVICE,
true);
133 accountTypeMap.put(Account.Type.DEVICE, panel.getCheckBox());
134 accountTypeListPane.add(panel);
136 deviceRequiredLabel.setVisible(
false);
137 accountTypeRequiredLabel.setVisible(
false);
138 startDatePicker.setDate(LocalDate.now().minusWeeks(3));
139 endDatePicker.setDateToToday();
140 startDatePicker.getSettings().setVetoPolicy(
142 startDate -> endCheckBox.isSelected() ==
false
143 || startDate.compareTo(endDatePicker.getDate()) <= 0
145 endDatePicker.getSettings().setVetoPolicy(
147 endDate -> startCheckBox.isSelected() ==
false
148 || endDate.compareTo(startDatePicker.getDate()) >= 0
152 validationListener = itemEvent -> validateFilters();
162 this.ingestListener = pce -> {
163 String eventType = pce.getPropertyName();
164 if (eventType.equals(DATA_ADDED.toString())) {
167 if (null != eventData
179 this.ingestJobListener = pce -> {
180 String eventType = pce.getPropertyName();
181 if (eventType.equals(COMPLETED.toString())
182 && updateFilters(
true)) {
189 applyFiltersButton.addActionListener(e -> applyFilters());
190 refreshButton.addActionListener(e -> applyFilters());
200 boolean someDevice = devicesMap.values().stream().anyMatch(JCheckBox::isSelected);
201 boolean someAccountType = accountTypeMap.values().stream().anyMatch(JCheckBox::isSelected);
202 boolean validLimit = validateLimitValue();
204 deviceRequiredLabel.setVisible(someDevice ==
false);
205 accountTypeRequiredLabel.setVisible(someAccountType ==
false);
206 limitErrorMsgLabel.setVisible(!validLimit);
208 applyFiltersButton.setEnabled(someDevice && someAccountType && validLimit);
209 refreshButton.setEnabled(someDevice && someAccountType && needsRefresh && validLimit);
210 needsRefreshLabel.setVisible(needsRefresh);
214 String selectedValue = (String) limitComboBox.getSelectedItem();
215 if (selectedValue.trim().equalsIgnoreCase(
"all")) {
219 int value = Integer.parseInt(selectedValue);
221 }
catch (NumberFormatException ex) {
230 void updateAndApplyFilters(
boolean initialState) {
231 updateFilters(initialState);
233 initalizeDateTimeFilters();
244 boolean newAccountType = updateAccountTypeFilter(initialState);
245 boolean newDeviceFilter = updateDeviceFilter(initialState);
248 return newAccountType || newDeviceFilter;
259 devicesListPane.removeAll();
261 accountTypeMap.clear();
262 accountTypeListPane.removeAll();
268 super.removeNotify();
281 boolean newOneFound =
false;
284 List<Account.Type> accountTypesInUse = communicationsManager.getAccountTypesInUse();
286 for (Account.Type type : accountTypesInUse) {
288 if (!accountTypeMap.containsKey(type) && !type.equals(Account.Type.CREDIT_CARD)) {
289 CheckBoxIconPanel panel = createAccoutTypeCheckBoxPanel(type, selected);
290 accountTypeMap.put(type, panel.getCheckBox());
291 accountTypeListPane.add(panel);
297 }
catch (TskCoreException ex) {
298 logger.log(Level.WARNING,
"Unable to update to update Account Types Filter", ex);
300 logger.log(Level.WARNING,
"A case is required to update the account types filter.", ex);
304 accountTypeListPane.revalidate();
320 CheckBoxIconPanel panel =
new CheckBoxIconPanel(
321 type.getDisplayName(),
324 panel.setSelected(initalState);
325 panel.addItemListener(validationListener);
337 boolean newOneFound =
false;
341 for (DataSource dataSource : sleuthkitCase.getDataSources()) {
342 String dsName = sleuthkitCase.getContentById(dataSource.getId()).getName();
343 if (devicesMap.containsKey(dataSource.getDeviceId())) {
347 final JCheckBox jCheckBox =
new JCheckBox(dsName, selected);
348 jCheckBox.addItemListener(validationListener);
349 devicesListPane.add(jCheckBox);
350 devicesMap.put(dataSource.getDeviceId(), jCheckBox);
356 logger.log(Level.INFO,
"Filter update cancelled. Case is closed.");
357 }
catch (TskCoreException tskCoreException) {
358 logger.log(Level.SEVERE,
"There was a error loading the datasources for the case.", tskCoreException);
362 devicesListPane.revalidate();
375 List<CommunicationsFilter.SubFilter> subFilters = commFilter.getAndFilters();
376 subFilters.forEach(subFilter -> {
377 if (subFilter instanceof DeviceFilter) {
378 setDeviceFilter((DeviceFilter) subFilter);
379 }
else if (subFilter instanceof AccountTypeFilter) {
380 setAccountTypeFilter((AccountTypeFilter) subFilter);
381 }
else if (subFilter instanceof MostRecentFilter) {
382 setMostRecentFilter((MostRecentFilter) subFilter);
393 Collection<String> deviceIDs = deviceFilter.getDevices();
394 devicesMap.forEach((type, cb) -> {
395 cb.setSelected(deviceIDs.contains(type));
407 accountTypeMap.forEach((type, cb) -> {
408 cb.setSelected(typeFilter.getAccountTypes().contains(type));
419 startDatePicker.setDate(state.getDate());
420 startCheckBox.setSelected(state.isEnabled());
421 startDatePicker.setEnabled(state.isEnabled());
431 endDatePicker.setDate(state.getDate());
432 endCheckBox.setSelected(state.isEnabled());
433 endDatePicker.setEnabled(state.isEnabled());
443 int limit = filter.getLimit();
445 limitComboBox.setSelectedItem(filter.getLimit());
447 limitComboBox.setSelectedItem(
"All");
452 void filtersBack(CVTEvents.StateChangeEvent event) {
453 if (event.getCommunicationsState().getCommunicationsFilter() != null) {
454 setFilters(event.getCommunicationsState().getCommunicationsFilter());
455 setStartDateControlState(event.getCommunicationsState().getStartControlState());
456 setEndDateControlState(event.getCommunicationsState().getEndControlState());
457 needsRefresh =
false;
467 @SuppressWarnings(
"unchecked")
469 private
void initComponents() {
470 java.awt.GridBagConstraints gridBagConstraints;
472 setLayout(
new java.awt.GridBagLayout());
474 scrollPane.setBorder(null);
476 mainPanel.setLayout(
new java.awt.GridBagLayout());
478 limitPane.setLayout(
new java.awt.GridBagLayout());
480 mostRecentLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.mostRecentLabel.text"));
481 gridBagConstraints =
new java.awt.GridBagConstraints();
482 gridBagConstraints.gridx = 0;
483 gridBagConstraints.gridy = 1;
484 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
485 gridBagConstraints.insets =
new java.awt.Insets(0, 9, 0, 9);
486 limitPane.add(mostRecentLabel, gridBagConstraints);
488 limitComboBox.setEditable(
true);
489 limitComboBox.setModel(
new javax.swing.DefaultComboBoxModel<>(
new String[] {
"All",
"10000",
"5000",
"1000",
"500",
"100" }));
490 limitComboBox.addActionListener(
new java.awt.event.ActionListener() {
491 public void actionPerformed(java.awt.event.ActionEvent evt) {
492 limitComboBoxActionPerformed(evt);
495 gridBagConstraints =
new java.awt.GridBagConstraints();
496 gridBagConstraints.gridx = 1;
497 gridBagConstraints.gridy = 1;
498 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
499 limitPane.add(limitComboBox, gridBagConstraints);
501 limitTitlePanel.setLayout(
new java.awt.GridBagLayout());
503 limitHeaderLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.limitHeaderLabel.text"));
504 gridBagConstraints =
new java.awt.GridBagConstraints();
505 gridBagConstraints.gridx = 0;
506 gridBagConstraints.gridy = 0;
507 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
508 gridBagConstraints.weightx = 1.0;
509 limitTitlePanel.add(limitHeaderLabel, gridBagConstraints);
511 limitErrorMsgLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/error-icon-16.png")));
512 limitErrorMsgLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.limitErrorMsgLabel.text"));
513 limitErrorMsgLabel.setForeground(
new java.awt.Color(255, 0, 0));
514 limitErrorMsgLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
515 gridBagConstraints =
new java.awt.GridBagConstraints();
516 gridBagConstraints.gridx = 1;
517 gridBagConstraints.gridy = 0;
518 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
519 limitTitlePanel.add(limitErrorMsgLabel, gridBagConstraints);
521 gridBagConstraints =
new java.awt.GridBagConstraints();
522 gridBagConstraints.gridx = 0;
523 gridBagConstraints.gridy = 0;
524 gridBagConstraints.gridwidth = 2;
525 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
526 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
527 gridBagConstraints.weightx = 1.0;
528 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 9, 0);
529 limitPane.add(limitTitlePanel, gridBagConstraints);
531 gridBagConstraints =
new java.awt.GridBagConstraints();
532 gridBagConstraints.gridx = 0;
533 gridBagConstraints.gridy = 4;
534 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
535 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
536 gridBagConstraints.weightx = 1.0;
537 gridBagConstraints.weighty = 1.0;
538 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 15, 0);
539 mainPanel.add(limitPane, gridBagConstraints);
541 startDatePicker.setEnabled(
false);
543 dateRangeLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/calendar.png")));
544 dateRangeLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.dateRangeLabel.text"));
546 startCheckBox.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.startCheckBox.text"));
547 startCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
548 public void stateChanged(javax.swing.event.ChangeEvent evt) {
549 startCheckBoxStateChanged(evt);
553 endCheckBox.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.endCheckBox.text"));
554 endCheckBox.addChangeListener(
new javax.swing.event.ChangeListener() {
555 public void stateChanged(javax.swing.event.ChangeEvent evt) {
556 endCheckBoxStateChanged(evt);
560 endDatePicker.setEnabled(
false);
562 javax.swing.GroupLayout dateRangePaneLayout =
new javax.swing.GroupLayout(dateRangePane);
563 dateRangePane.setLayout(dateRangePaneLayout);
564 dateRangePaneLayout.setHorizontalGroup(
565 dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
566 .addGroup(dateRangePaneLayout.createSequentialGroup()
567 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
568 .addComponent(dateRangeLabel)
569 .addGroup(dateRangePaneLayout.createSequentialGroup()
571 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
572 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, dateRangePaneLayout.createSequentialGroup()
573 .addComponent(endCheckBox)
575 .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
576 .addGroup(dateRangePaneLayout.createSequentialGroup()
577 .addComponent(startCheckBox)
579 .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
580 .addGap(0, 0, Short.MAX_VALUE))
583 dateRangePaneLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {endCheckBox, startCheckBox});
585 dateRangePaneLayout.setVerticalGroup(
586 dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
587 .addGroup(dateRangePaneLayout.createSequentialGroup()
588 .addComponent(dateRangeLabel)
590 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
591 .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
592 .addComponent(startCheckBox))
593 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
594 .addGroup(dateRangePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
595 .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
596 .addComponent(endCheckBox)))
599 gridBagConstraints =
new java.awt.GridBagConstraints();
600 gridBagConstraints.gridx = 0;
601 gridBagConstraints.gridy = 3;
602 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
603 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
604 gridBagConstraints.weightx = 1.0;
605 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 0, 0);
606 mainPanel.add(dateRangePane, gridBagConstraints);
608 devicesPane.setLayout(
new java.awt.GridBagLayout());
610 unCheckAllDevicesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.unCheckAllDevicesButton.text"));
611 unCheckAllDevicesButton.addActionListener(
new java.awt.event.ActionListener() {
612 public void actionPerformed(java.awt.event.ActionEvent evt) {
613 unCheckAllDevicesButtonActionPerformed(evt);
616 gridBagConstraints =
new java.awt.GridBagConstraints();
617 gridBagConstraints.gridx = 0;
618 gridBagConstraints.gridy = 2;
619 gridBagConstraints.gridwidth = 2;
620 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
621 gridBagConstraints.weightx = 1.0;
622 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 9);
623 devicesPane.add(unCheckAllDevicesButton, gridBagConstraints);
625 devicesLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/image.png")));
626 devicesLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.devicesLabel.text"));
627 gridBagConstraints =
new java.awt.GridBagConstraints();
628 gridBagConstraints.gridx = 0;
629 gridBagConstraints.gridy = 0;
630 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
631 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 9, 0);
632 devicesPane.add(devicesLabel, gridBagConstraints);
634 checkAllDevicesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.checkAllDevicesButton.text"));
635 checkAllDevicesButton.addActionListener(
new java.awt.event.ActionListener() {
636 public void actionPerformed(java.awt.event.ActionEvent evt) {
637 checkAllDevicesButtonActionPerformed(evt);
640 gridBagConstraints =
new java.awt.GridBagConstraints();
641 gridBagConstraints.gridx = 2;
642 gridBagConstraints.gridy = 2;
643 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
644 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 0);
645 devicesPane.add(checkAllDevicesButton, gridBagConstraints);
647 devicesScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
648 devicesScrollPane.setMinimumSize(
new java.awt.Dimension(27, 75));
650 devicesListPane.setMinimumSize(
new java.awt.Dimension(4, 100));
651 devicesListPane.setLayout(
new javax.swing.BoxLayout(devicesListPane, javax.swing.BoxLayout.Y_AXIS));
652 devicesScrollPane.setViewportView(devicesListPane);
654 gridBagConstraints =
new java.awt.GridBagConstraints();
655 gridBagConstraints.gridx = 0;
656 gridBagConstraints.gridy = 1;
657 gridBagConstraints.gridwidth = 3;
658 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
659 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
660 gridBagConstraints.weightx = 1.0;
661 gridBagConstraints.weighty = 1.0;
662 devicesPane.add(devicesScrollPane, gridBagConstraints);
664 deviceRequiredLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/error-icon-16.png")));
665 deviceRequiredLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.deviceRequiredLabel.text"));
666 deviceRequiredLabel.setForeground(
new java.awt.Color(255, 0, 0));
667 deviceRequiredLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
668 gridBagConstraints =
new java.awt.GridBagConstraints();
669 gridBagConstraints.gridx = 1;
670 gridBagConstraints.gridy = 0;
671 gridBagConstraints.gridwidth = 2;
672 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
673 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 9, 0);
674 devicesPane.add(deviceRequiredLabel, gridBagConstraints);
676 gridBagConstraints =
new java.awt.GridBagConstraints();
677 gridBagConstraints.gridx = 0;
678 gridBagConstraints.gridy = 2;
679 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
680 gridBagConstraints.ipady = 100;
681 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
682 gridBagConstraints.weightx = 1.0;
683 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 0, 0);
684 mainPanel.add(devicesPane, gridBagConstraints);
686 accountTypesPane.setLayout(
new java.awt.GridBagLayout());
688 unCheckAllAccountTypesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.unCheckAllAccountTypesButton.text"));
689 unCheckAllAccountTypesButton.addActionListener(
new java.awt.event.ActionListener() {
690 public void actionPerformed(java.awt.event.ActionEvent evt) {
691 unCheckAllAccountTypesButtonActionPerformed(evt);
694 gridBagConstraints =
new java.awt.GridBagConstraints();
695 gridBagConstraints.gridx = 0;
696 gridBagConstraints.gridy = 2;
697 gridBagConstraints.gridwidth = 2;
698 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
699 gridBagConstraints.weightx = 1.0;
700 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 9);
701 accountTypesPane.add(unCheckAllAccountTypesButton, gridBagConstraints);
703 accountTypesLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/accounts.png")));
704 accountTypesLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.accountTypesLabel.text"));
705 gridBagConstraints =
new java.awt.GridBagConstraints();
706 gridBagConstraints.gridx = 0;
707 gridBagConstraints.gridy = 0;
708 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
709 accountTypesPane.add(accountTypesLabel, gridBagConstraints);
711 checkAllAccountTypesButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.checkAllAccountTypesButton.text"));
712 checkAllAccountTypesButton.addActionListener(
new java.awt.event.ActionListener() {
713 public void actionPerformed(java.awt.event.ActionEvent evt) {
714 checkAllAccountTypesButtonActionPerformed(evt);
717 gridBagConstraints =
new java.awt.GridBagConstraints();
718 gridBagConstraints.gridx = 2;
719 gridBagConstraints.gridy = 2;
720 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
721 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 0);
722 accountTypesPane.add(checkAllAccountTypesButton, gridBagConstraints);
724 accountTypesScrollPane.setPreferredSize(
new java.awt.Dimension(2, 200));
726 accountTypeListPane.setLayout(
new javax.swing.BoxLayout(accountTypeListPane, javax.swing.BoxLayout.PAGE_AXIS));
727 accountTypesScrollPane.setViewportView(accountTypeListPane);
729 gridBagConstraints =
new java.awt.GridBagConstraints();
730 gridBagConstraints.gridx = 0;
731 gridBagConstraints.gridy = 1;
732 gridBagConstraints.gridwidth = 3;
733 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
734 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
735 gridBagConstraints.weightx = 1.0;
736 gridBagConstraints.weighty = 1.0;
737 gridBagConstraints.insets =
new java.awt.Insets(9, 0, 0, 0);
738 accountTypesPane.add(accountTypesScrollPane, gridBagConstraints);
740 accountTypeRequiredLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/error-icon-16.png")));
741 accountTypeRequiredLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.accountTypeRequiredLabel.text"));
742 accountTypeRequiredLabel.setForeground(
new java.awt.Color(255, 0, 0));
743 accountTypeRequiredLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
744 gridBagConstraints =
new java.awt.GridBagConstraints();
745 gridBagConstraints.gridx = 1;
746 gridBagConstraints.gridy = 0;
747 gridBagConstraints.gridwidth = 2;
748 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
749 accountTypesPane.add(accountTypeRequiredLabel, gridBagConstraints);
751 gridBagConstraints =
new java.awt.GridBagConstraints();
752 gridBagConstraints.gridx = 0;
753 gridBagConstraints.gridy = 1;
754 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
755 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
756 gridBagConstraints.weightx = 1.0;
757 gridBagConstraints.insets =
new java.awt.Insets(15, 0, 0, 0);
758 mainPanel.add(accountTypesPane, gridBagConstraints);
760 topPane.setLayout(
new java.awt.GridBagLayout());
762 filtersTitleLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/communications/images/funnel.png")));
763 filtersTitleLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.filtersTitleLabel.text"));
764 gridBagConstraints =
new java.awt.GridBagConstraints();
765 gridBagConstraints.gridx = 0;
766 gridBagConstraints.gridy = 0;
767 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
768 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
769 gridBagConstraints.weightx = 1.0;
770 topPane.add(filtersTitleLabel, gridBagConstraints);
772 refreshButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/communications/images/arrow-circle-double-135.png")));
773 refreshButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.refreshButton.text"));
774 gridBagConstraints =
new java.awt.GridBagConstraints();
775 gridBagConstraints.gridx = 2;
776 gridBagConstraints.gridy = 0;
777 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
778 topPane.add(refreshButton, gridBagConstraints);
780 applyFiltersButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/communications/images/tick.png")));
781 applyFiltersButton.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.applyFiltersButton.text"));
782 gridBagConstraints =
new java.awt.GridBagConstraints();
783 gridBagConstraints.gridx = 1;
784 gridBagConstraints.gridy = 0;
785 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
786 gridBagConstraints.weightx = 1.0;
787 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 0, 5);
788 topPane.add(applyFiltersButton, gridBagConstraints);
790 needsRefreshLabel.setText(
org.openide.util.NbBundle.getMessage(
FiltersPanel.class,
"FiltersPanel.needsRefreshLabel.text"));
791 needsRefreshLabel.setForeground(
new java.awt.Color(255, 0, 0));
792 gridBagConstraints =
new java.awt.GridBagConstraints();
793 gridBagConstraints.gridx = 0;
794 gridBagConstraints.gridy = 1;
795 gridBagConstraints.gridwidth = 3;
796 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
797 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
798 gridBagConstraints.weightx = 1.0;
799 topPane.add(needsRefreshLabel, gridBagConstraints);
801 gridBagConstraints =
new java.awt.GridBagConstraints();
802 gridBagConstraints.gridx = 0;
803 gridBagConstraints.gridy = 0;
804 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
805 gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_END;
806 gridBagConstraints.weightx = 1.0;
807 mainPanel.add(topPane, gridBagConstraints);
809 scrollPane.setViewportView(mainPanel);
811 gridBagConstraints =
new java.awt.GridBagConstraints();
812 gridBagConstraints.gridx = 0;
813 gridBagConstraints.gridy = 0;
814 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
815 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
816 gridBagConstraints.weightx = 1.0;
817 gridBagConstraints.weighty = 1.0;
818 gridBagConstraints.insets =
new java.awt.Insets(9, 15, 0, 0);
819 add(scrollPane, gridBagConstraints);
826 CVTEvents.getCVTEventBus().post(
new CVTEvents.FilterChangeEvent(getFilter(), getStartControlState(), getEndControlState()));
827 needsRefresh =
false;
837 CommunicationsFilter commsFilter =
new CommunicationsFilter();
838 commsFilter.addAndFilter(getDeviceFilter());
839 commsFilter.addAndFilter(getAccountTypeFilter());
840 commsFilter.addAndFilter(getDateRangeFilter());
841 commsFilter.addAndFilter(
new CommunicationsFilter.RelationshipTypeFilter(
842 ImmutableSet.of(CALL_LOG, MESSAGE, CONTACT)));
843 commsFilter.addAndFilter(getMostRecentFilter());
853 DeviceFilter deviceFilter =
new DeviceFilter(
854 devicesMap.entrySet().stream()
855 .filter(entry -> entry.getValue().isSelected())
857 .collect(Collectors.toSet()));
867 AccountTypeFilter accountTypeFilter =
new AccountTypeFilter(
868 accountTypeMap.entrySet().stream()
869 .filter(entry -> entry.getValue().isSelected())
870 .map(entry -> entry.getKey())
871 .collect(Collectors.toSet()));
872 return accountTypeFilter;
883 return new DateRangeFilter(startCheckBox.isSelected() ? startDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0,
884 endCheckBox.isSelected() ? endDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0);
894 String value = (String) limitComboBox.getSelectedItem();
895 if (value.trim().equalsIgnoreCase(
"all")) {
896 return new MostRecentFilter(-1);
899 int count = Integer.parseInt(value);
900 return new MostRecentFilter(count);
901 }
catch (NumberFormatException ex) {
908 return new DateControlState(startDatePicker.getDate(), startCheckBox.isSelected());
912 return new DateControlState(endDatePicker.getDate(), endCheckBox.isSelected());
921 private
void setAllAccountTypesSelected(
boolean selected) {
922 setAllSelected(accountTypeMap, selected);
931 private
void setAllDevicesSelected(
boolean selected) {
932 setAllSelected(devicesMap, selected);
943 private
void setAllSelected(Map<?, JCheckBox> map,
boolean selected) {
944 map.values().forEach(box -> box.setSelected(selected));
952 Case currentCase = null;
956 logger.log(Level.INFO,
"Tried to intialize communication filters date range filters without an open case, using default values");
959 if (currentCase == null) {
960 setDateTimeFiltersToDefault();
965 if (!currentCase.equals(openCase)) {
966 setDateTimeFiltersToDefault();
967 openCase = currentCase;
968 (
new DatePickerWorker()).execute();
973 startDatePicker.setDate(LocalDate.now().minusWeeks(3));
974 endDatePicker.setDate(LocalDate.now());
978 setAllAccountTypesSelected(
false);
982 setAllAccountTypesSelected(
true);
986 setAllDevicesSelected(
false);
990 setAllDevicesSelected(
true);
994 startDatePicker.setEnabled(startCheckBox.isSelected());
999 endDatePicker.setEnabled(endCheckBox.isSelected());
1012 final class DateControlState {
1014 private final LocalDate date;
1015 private final boolean enabled;
1024 protected DateControlState(LocalDate date,
boolean enabled) {
1026 this.enabled = enabled;
1034 public LocalDate getDate() {
1043 public boolean isEnabled() {
1050 private final javax.swing.JPanel accountTypeListPane =
new javax.swing.JPanel();
1051 private final javax.swing.JLabel accountTypeRequiredLabel =
new javax.swing.JLabel();
1052 private final javax.swing.JLabel accountTypesLabel =
new javax.swing.JLabel();
1053 private final javax.swing.JPanel accountTypesPane =
new javax.swing.JPanel();
1054 private final javax.swing.JScrollPane accountTypesScrollPane =
new javax.swing.JScrollPane();
1055 private final javax.swing.JButton applyFiltersButton =
new javax.swing.JButton();
1056 private final javax.swing.JButton checkAllAccountTypesButton =
new javax.swing.JButton();
1057 private final javax.swing.JButton checkAllDevicesButton =
new javax.swing.JButton();
1058 private final javax.swing.JLabel dateRangeLabel =
new javax.swing.JLabel();
1059 private final javax.swing.JPanel dateRangePane =
new javax.swing.JPanel();
1060 private final javax.swing.JLabel deviceRequiredLabel =
new javax.swing.JLabel();
1061 private final javax.swing.JLabel devicesLabel =
new javax.swing.JLabel();
1062 private final javax.swing.JPanel devicesListPane =
new javax.swing.JPanel();
1063 private final javax.swing.JPanel devicesPane =
new javax.swing.JPanel();
1064 private final javax.swing.JScrollPane devicesScrollPane =
new javax.swing.JScrollPane();
1065 private final javax.swing.JCheckBox endCheckBox =
new javax.swing.JCheckBox();
1066 private final com.github.lgooddatepicker.components.DatePicker endDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
1067 private final javax.swing.JLabel filtersTitleLabel =
new javax.swing.JLabel();
1068 private final javax.swing.JComboBox<String> limitComboBox =
new javax.swing.JComboBox<>();
1069 private final javax.swing.JLabel limitErrorMsgLabel =
new javax.swing.JLabel();
1070 private final javax.swing.JLabel limitHeaderLabel =
new javax.swing.JLabel();
1071 private final javax.swing.JPanel limitPane =
new javax.swing.JPanel();
1072 private final javax.swing.JPanel limitTitlePanel =
new javax.swing.JPanel();
1073 private final javax.swing.JPanel mainPanel =
new javax.swing.JPanel();
1074 private final javax.swing.JLabel mostRecentLabel =
new javax.swing.JLabel();
1075 private final javax.swing.JLabel needsRefreshLabel =
new javax.swing.JLabel();
1076 private final javax.swing.JButton refreshButton =
new javax.swing.JButton();
1077 private final javax.swing.JScrollPane scrollPane =
new javax.swing.JScrollPane();
1078 private final javax.swing.JCheckBox startCheckBox =
new javax.swing.JCheckBox();
1079 private final com.github.lgooddatepicker.components.DatePicker startDatePicker =
new com.github.lgooddatepicker.components.DatePicker();
1080 private final javax.swing.JPanel topPane =
new javax.swing.JPanel();
1081 private final javax.swing.JButton unCheckAllAccountTypesButton =
new javax.swing.JButton();
1082 private final javax.swing.JButton unCheckAllDevicesButton =
new javax.swing.JButton();
1090 final class CheckBoxIconPanel
extends JPanel {
1092 private static final long serialVersionUID = 1L;
1094 private final JCheckBox checkbox;
1095 private final JLabel label;
1103 private CheckBoxIconPanel(String labelText, Icon image) {
1104 checkbox =
new JCheckBox();
1105 label =
new JLabel(labelText);
1106 label.setIcon(image);
1107 setLayout(
new BoxLayout(
this, BoxLayout.X_AXIS));
1111 add(Box.createHorizontalGlue());
1119 void setSelected(
boolean selected) {
1120 checkbox.setSelected(selected);
1124 public void setEnabled(
boolean enabled) {
1125 checkbox.setEnabled(enabled);
1133 JCheckBox getCheckBox() {
1142 void addItemListener(ItemListener l) {
1143 checkbox.addItemListener(l);
1151 class FilterPanelQueryCallback
implements CaseDbAccessQueryCallback {
1154 public void process(ResultSet rs) {
1159 final class DatePickerWorker
extends SwingWorker<Map<String, Integer>, Void> {
1162 protected Map<String, Integer> doInBackground() throws Exception {
1163 if (openCase == null) {
1167 Map<String, Integer> resultMap =
new HashMap<>();
1168 String queryString =
"max(date_time) as end, min(date_time) as start from account_relationships";
1170 openCase.getSleuthkitCase().getCaseDbAccessManager().select(queryString,
new FilterPanelQueryCallback() {
1172 public void process(ResultSet rs) {
1175 int startDate = rs.getInt(
"start");
1176 int endDate = rs.getInt(
"end");
1178 resultMap.put(
"start", startDate);
1179 resultMap.put(
"end", endDate);
1181 }
catch (SQLException ex) {
1183 logger.log(Level.WARNING, String.format(
"SQL Exception thrown from Query: %s", queryString), ex);
1192 protected void done() {
1194 Map<String, Integer> resultMap =
get();
1195 if (resultMap != null) {
1196 Integer start = resultMap.get(
"start");
1197 Integer end = resultMap.get(
"end");
1199 if (start != null && start != 0) {
1200 startDatePicker.setDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(start), Utils.getUserPreferredZoneId()).toLocalDate());
1203 if (end != null && end != 0) {
1204 endDatePicker.setDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(end), Utils.getUserPreferredZoneId()).toLocalDate());
1207 }
catch (InterruptedException | ExecutionException ex) {
1208 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()
boolean updateDeviceFilter(boolean selected)
void setMostRecentFilter(MostRecentFilter filter)
void setDeviceFilter(DeviceFilter deviceFilter)
void unCheckAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt)
boolean updateAccountTypeFilter(boolean selected)
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)
DeviceFilter getDeviceFilter()
DateRangeFilter getDateRangeFilter()
AccountTypeFilter getAccountTypeFilter()
static final String TIME_ZONE_FOR_DISPLAYS