diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle.properties index 39759e3eb7..b3375cda0d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle.properties @@ -4,3 +4,6 @@ DataContentViewerOtherCases.table.toolTip.text=Click column name to sort. Right- DataContentViewerOtherCases.exportToCSVMenuItem.text=Export Selected Rows to CSV DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Frequency DataContentViewerOtherCases.addCommentMenuItem.text=Add/Edit Comment +DataContentViewerOtherCases.earliestCaseDate.text=Earliest Case Date +DataContentViewerOtherCases.earliestCaseLabel.toolTipText= +DataContentViewerOtherCases.earliestCaseLabel.text=Central Repository Starting Date: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form index 0097313943..60667bae46 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form @@ -80,7 +80,7 @@ - + @@ -103,10 +103,10 @@ - + - + @@ -124,17 +124,36 @@ - - + + + + + + + + + + + + + - - - + + + + + + + + + + + - + @@ -174,6 +193,23 @@ + + + + + + + + + + + + + + + + + @@ -185,37 +221,22 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index 15ed21d753..b56dd20beb 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -25,11 +25,15 @@ import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.logging.Level; @@ -45,6 +49,8 @@ import javax.swing.JPanel; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; +import org.joda.time.DateTimeZone; +import org.joda.time.LocalDateTime; import org.openide.nodes.Node; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; @@ -78,6 +84,8 @@ import org.sleuthkit.datamodel.TskData; "DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",}) public class DataContentViewerOtherCases extends JPanel implements DataContentViewer { + private static final long serialVersionUID = -1L; + private final static Logger logger = Logger.getLogger(DataContentViewerOtherCases.class.getName()); private final DataContentViewerOtherCasesTableModel tableModel; @@ -140,6 +148,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi TableCellRenderer renderer = new DataContentViewerOtherCasesTableCellRenderer(); otherCasesTable.setDefaultRenderer(Object.class, renderer); tableStatusPanelLabel.setVisible(false); + } @Messages({"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.", @@ -160,7 +169,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(), DEFAULT_OPTION, PLAIN_MESSAGE); } else { - StringBuilder msg = new StringBuilder(); + StringBuilder msg = new StringBuilder(correlationAttributes.size()); int percentage; try { EamDb dbManager = EamDb.getInstance(); @@ -310,6 +319,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // start with empty table tableModel.clearTable(); correlationAttributes.clear(); + earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable()); } @Override @@ -456,6 +466,40 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi return ret; } + @Messages({"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."}) + /** + * Gets the list of Eam Cases and determines the earliest case creation date. + * Sets the label to display the earliest date string to the user. + */ + private void setEarliestCaseDate() { + String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable(); + + if (EamDb.isEnabled()) { + LocalDateTime earliestDate = LocalDateTime.now(DateTimeZone.UTC); + DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US); + try { + EamDb dbManager = EamDb.getInstance(); + List cases = dbManager.getCases(); + for (CorrelationCase aCase : cases) { + LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate())); + + if (caseDate.isBefore(earliestDate)) { + earliestDate = caseDate; + dateStringDisplay = aCase.getCreationDate(); + } + + } + + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Error getting list of cases from database.", ex); // NON-NLS + } catch (ParseException ex) { + logger.log(Level.SEVERE, "Error parsing date of cases from database.", ex); // NON-NLS + } + + } + earliestCaseDate.setText(dateStringDisplay); + } + /** * Query the central repo database (if enabled) and the case database to find all * artifact instances correlated to the given central repository artifact. If the @@ -532,7 +576,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi */ private List getCaseDbMatches(CorrelationAttribute corAttr, Case openCase) throws NoCurrentCaseException, TskCoreException, EamDbException { String md5 = corAttr.getCorrelationValue(); - SleuthkitCase tsk = openCase.getSleuthkitCase(); List matches = tsk.findAllFilesWhere(String.format("md5 = '%s'", new Object[]{md5})); @@ -667,6 +710,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi clearMessageOnTableStatusPanel(); setColumnWidths(); } + setEarliestCaseDate(); } private void setColumnWidths() { @@ -708,6 +752,8 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi tableContainerPanel = new javax.swing.JPanel(); tableScrollPane = new javax.swing.JScrollPane(); otherCasesTable = new javax.swing.JTable(); + earliestCaseLabel = new javax.swing.JLabel(); + earliestCaseDate = new javax.swing.JLabel(); tableStatusPanel = new javax.swing.JPanel(); tableStatusPanelLabel = new javax.swing.JLabel(); @@ -753,44 +799,55 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi otherCasesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); tableScrollPane.setViewportView(otherCasesTable); - tableStatusPanel.setPreferredSize(new java.awt.Dimension(1500, 16)); + org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseLabel.text")); // NOI18N + earliestCaseLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseLabel.toolTipText")); // NOI18N - tableStatusPanelLabel.setForeground(new java.awt.Color(255, 0, 51)); + org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseDate.text")); // NOI18N + + tableStatusPanel.setPreferredSize(new java.awt.Dimension(1500, 16)); javax.swing.GroupLayout tableStatusPanelLayout = new javax.swing.GroupLayout(tableStatusPanel); tableStatusPanel.setLayout(tableStatusPanelLayout); tableStatusPanelLayout.setHorizontalGroup( tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 0, Short.MAX_VALUE) - .addGroup(tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(tableStatusPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 780, Short.MAX_VALUE) - .addContainerGap())) ); tableStatusPanelLayout.setVerticalGroup( tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 16, Short.MAX_VALUE) - .addGroup(tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(tableStatusPanelLayout.createSequentialGroup() - .addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) ); + tableStatusPanelLabel.setForeground(new java.awt.Color(255, 0, 51)); + javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel); tableContainerPanel.setLayout(tableContainerPanelLayout); tableContainerPanelLayout.setHorizontalGroup( tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tableScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(tableStatusPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup() + .addComponent(tableStatusPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1282, Short.MAX_VALUE) + .addGap(218, 218, 218)) + .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(tableContainerPanelLayout.createSequentialGroup() + .addComponent(earliestCaseLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(earliestCaseDate) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); tableContainerPanelLayout.setVerticalGroup( tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(tableContainerPanelLayout.createSequentialGroup() - .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup() + .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE) + .addGap(0, 0, 0) + .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(earliestCaseLabel) + .addComponent(earliestCaseDate)) + .addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0) .addComponent(tableStatusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addGap(0, 0, 0)) ); javax.swing.GroupLayout otherCasesPanelLayout = new javax.swing.GroupLayout(otherCasesPanel); @@ -803,10 +860,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi ); otherCasesPanelLayout.setVerticalGroup( otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 60, Short.MAX_VALUE) + .addGap(0, 483, Short.MAX_VALUE) .addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(otherCasesPanelLayout.createSequentialGroup() - .addComponent(tableContainerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 52, Short.MAX_VALUE) + .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE) .addGap(0, 0, 0))) ); @@ -818,7 +875,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 52, Short.MAX_VALUE) + .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -841,6 +898,8 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JFileChooser CSVFileChooser; private javax.swing.JMenuItem addCommentMenuItem; + private javax.swing.JLabel earliestCaseDate; + private javax.swing.JLabel earliestCaseLabel; private javax.swing.JMenuItem exportToCSVMenuItem; private javax.swing.JPanel otherCasesPanel; private javax.swing.JTable otherCasesTable; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties index 0106566831..5514e3316b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties @@ -65,3 +65,13 @@ GlobalSettingsPanel.manageOrganizationButton.text=Manage Organizations GlobalSettingsPanel.lbCentralRepository.text=A central repository allows you to correlate files and results between cases. GlobalSettingsPanel.pnCorrelationProperties.border.title=Correlation Properties GlobalSettingsPanel.organizationPanel.border.title=Organizations +GlobalSettingsPanel.casesPanel.border.title=Case Details +GlobalSettingsPanel.showCasesButton.text=Show Cases +ShowCasesDialog.closeButton.AccessibleContext.accessibleName=Close +ShowCasesDialog.closeButton.actionCommand=Close +ShowCasesDialog.closeButton.text=Close +ShowCasesDialog.caseDetailsTable.toolTipText=Click column name to sort. Right-click on the table for more options. +ShowCasesDialog.title=Case Details +GlobalSettingsPanel.Case\ Details.AccessibleContext.accessibleName=Cases Details +ShowCasesDialog.caseDetailsTable.AccessibleContext.accessibleDescription=Click column name to sort. +GlobalSettingsPanel.casesTextArea.text=Display table that lists central repository case details. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 788fef4660..33c94bea0b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -27,7 +27,7 @@ - + @@ -57,24 +57,26 @@ - + - - - - - - - - - - + - - + + + + + + + + + + + + + @@ -90,8 +92,10 @@ + + - + @@ -328,7 +332,7 @@ - + @@ -398,6 +402,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index a1daad3a71..925edee795 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -124,6 +124,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i manageOrganizationButton = new javax.swing.JButton(); organizationScrollPane = new javax.swing.JScrollPane(); organizationTextArea = new javax.swing.JTextArea(); + casesPanel = new javax.swing.JPanel(); + showCasesButton = new javax.swing.JButton(); + casesScrollPane = new javax.swing.JScrollPane(); + casesTextArea = new javax.swing.JTextArea(); tbOops = new javax.swing.JTextField(); setName(""); // NOI18N @@ -276,7 +280,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(organizationPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(organizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(organizationScrollPane) + .addComponent(organizationScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 992, Short.MAX_VALUE) .addGroup(organizationPanelLayout.createSequentialGroup() .addComponent(manageOrganizationButton) .addGap(0, 0, Short.MAX_VALUE))) @@ -292,6 +296,52 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGap(8, 8, 8)) ); + casesPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.casesPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N + casesPanel.setName("Case Details"); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(showCasesButton, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.showCasesButton.text")); // NOI18N + showCasesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + showCasesButtonActionPerformed(evt); + } + }); + + casesScrollPane.setBorder(null); + + casesTextArea.setEditable(false); + casesTextArea.setBackground(new java.awt.Color(240, 240, 240)); + casesTextArea.setColumns(20); + casesTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N + casesTextArea.setLineWrap(true); + casesTextArea.setRows(2); + casesTextArea.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.casesTextArea.text")); // NOI18N + casesTextArea.setWrapStyleWord(true); + casesTextArea.setBorder(null); + casesScrollPane.setViewportView(casesTextArea); + + javax.swing.GroupLayout casesPanelLayout = new javax.swing.GroupLayout(casesPanel); + casesPanel.setLayout(casesPanelLayout); + casesPanelLayout.setHorizontalGroup( + casesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(casesPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(casesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(casesScrollPane) + .addGroup(casesPanelLayout.createSequentialGroup() + .addComponent(showCasesButton) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + casesPanelLayout.setVerticalGroup( + casesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, casesPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(casesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(showCasesButton) + .addGap(8, 8, 8)) + ); + tbOops.setEditable(false); tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12)); tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N @@ -301,20 +351,21 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lbCentralRepository, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbCentralRepository, javax.swing.GroupLayout.DEFAULT_SIZE, 1022, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(cbUseCentralRepo) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 974, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(36, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnCorrelationProperties, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 1012, Short.MAX_VALUE) - .addComponent(organizationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1016, Short.MAX_VALUE) + .addComponent(organizationPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(casesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(cbUseCentralRepo) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 974, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(0, 0, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -329,10 +380,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(organizationPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(casesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 92, Short.MAX_VALUE)) + .addContainerGap()) ); + casesPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.Case Details.AccessibleContext.accessibleName")); // NOI18N + jScrollPane1.setViewportView(jPanel1); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -343,13 +398,13 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 488, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 517, Short.MAX_VALUE) ); }// //GEN-END:initComponents private void bnManageTypesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTypesActionPerformed store(); - ManageCorrelationPropertiesDialog dialog = new ManageCorrelationPropertiesDialog(); + ManageCorrelationPropertiesDialog manageCorrelationDialog = new ManageCorrelationPropertiesDialog(); firePropertyChange(OptionsPanelController.PROP_VALID, null, null); }//GEN-LAST:event_bnManageTypesActionPerformed @@ -374,9 +429,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void manageOrganizationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageOrganizationButtonActionPerformed store(); - ManageOrganizationsDialog dialog = new ManageOrganizationsDialog(); + ManageOrganizationsDialog manageOrganizationsDialog = new ManageOrganizationsDialog(); }//GEN-LAST:event_manageOrganizationButtonActionPerformed + private void showCasesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showCasesButtonActionPerformed + store(); + ShowCasesDialog showCasesDialog = new ShowCasesDialog(); + }//GEN-LAST:event_showCasesButtonActionPerformed + @Override @Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."}) public void load() { @@ -553,12 +613,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i organizationPanel.setEnabled(enable && !ingestRunning); organizationTextArea.setEnabled(enable && !ingestRunning); manageOrganizationButton.setEnabled(enable && !ingestRunning); + showCasesButton.setEnabled(enable && !ingestRunning); + casesPanel.setEnabled(enable && !ingestRunning); + casesTextArea.setEnabled(enable && !ingestRunning); return true; } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton bnDbConfigure; private javax.swing.JButton bnManageTypes; + private javax.swing.JPanel casesPanel; + private javax.swing.JScrollPane casesScrollPane; + private javax.swing.JTextArea casesTextArea; private javax.swing.JCheckBox cbUseCentralRepo; private javax.swing.JScrollPane correlationPropertiesScrollPane; private javax.swing.JTextArea correlationPropertiesTextArea; @@ -577,6 +643,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private javax.swing.JTextArea organizationTextArea; private javax.swing.JPanel pnCorrelationProperties; private javax.swing.JPanel pnDatabaseConfiguration; + private javax.swing.JButton showCasesButton; private javax.swing.JTextField tbOops; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesDialog.form new file mode 100644 index 0000000000..f34b3e575c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesDialog.form @@ -0,0 +1,172 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesDialog.java new file mode 100644 index 0000000000..6dc29ea87f --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesDialog.java @@ -0,0 +1,192 @@ +/* + * Central Repository + * + * Copyright 2015-2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.optionspanel; + +import java.util.List; +import java.util.logging.Level; +import javax.swing.JDialog; +import javax.swing.JFrame; +import org.openide.util.NbBundle.Messages; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * Dialog to display table of CorrelationCase information from the CR tab of options. + */ +@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives +final class ShowCasesDialog extends JDialog { + + private static final long serialVersionUID = 1L; + + private final static Logger logger = Logger.getLogger(ShowCasesDialog.class.getName()); + + private final ShowCasesTableModel tableModel; + @Messages({"ShowCasesDialog.title_text=All Cases Details"}) + /** + * Creates new form ShowCases Panel + */ + ShowCasesDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), + Bundle.ShowCasesDialog_title_text(), + true); + tableModel = new ShowCasesTableModel(); + initComponents(); + try { + EamDb dbManager = EamDb.getInstance(); + List eamCases = dbManager.getCases(); + for(CorrelationCase eamCase : eamCases) { + tableModel.addEamCase(eamCase); + } + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Error getting list of cases from database.", ex); // NON-NLS + } + display(); + } + + private void display() { + this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + setVisible(true); + } + + + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + showCasesPanel = new javax.swing.JPanel(); + showCasesScrollPane = new javax.swing.JScrollPane(); + outCasesPane = new javax.swing.JPanel(); + innerCaseScrollPane = new javax.swing.JScrollPane(); + caseDetailsTable = new javax.swing.JTable(); + closeButton = new javax.swing.JButton(); + + setTitle(org.openide.util.NbBundle.getMessage(ShowCasesDialog.class, "ShowCasesDialog.title")); // NOI18N + setMinimumSize(new java.awt.Dimension(545, 415)); + + showCasesPanel.setPreferredSize(new java.awt.Dimension(527, 407)); + + showCasesScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); + showCasesScrollPane.setPreferredSize(new java.awt.Dimension(535, 415)); + + innerCaseScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + caseDetailsTable.setAutoCreateRowSorter(true); + caseDetailsTable.setModel(tableModel); + caseDetailsTable.setToolTipText(org.openide.util.NbBundle.getMessage(ShowCasesDialog.class, "ShowCasesDialog.caseDetailsTable.toolTipText")); // NOI18N + caseDetailsTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); + caseDetailsTable.getTableHeader().setReorderingAllowed(false); + innerCaseScrollPane.setViewportView(caseDetailsTable); + caseDetailsTable.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ShowCasesDialog.class, "ShowCasesDialog.caseDetailsTable.AccessibleContext.accessibleDescription")); // NOI18N + + javax.swing.GroupLayout outCasesPaneLayout = new javax.swing.GroupLayout(outCasesPane); + outCasesPane.setLayout(outCasesPaneLayout); + outCasesPaneLayout.setHorizontalGroup( + outCasesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 1222, Short.MAX_VALUE) + .addGroup(outCasesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(outCasesPaneLayout.createSequentialGroup() + .addComponent(innerCaseScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 1222, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + ); + outCasesPaneLayout.setVerticalGroup( + outCasesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + .addGroup(outCasesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(innerCaseScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)) + ); + + showCasesScrollPane.setViewportView(outCasesPane); + + javax.swing.GroupLayout showCasesPanelLayout = new javax.swing.GroupLayout(showCasesPanel); + showCasesPanel.setLayout(showCasesPanelLayout); + showCasesPanelLayout.setHorizontalGroup( + showCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 527, Short.MAX_VALUE) + .addGroup(showCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(showCasesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)) + ); + showCasesPanelLayout.setVerticalGroup( + showCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 407, Short.MAX_VALUE) + .addGroup(showCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(showCasesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 407, Short.MAX_VALUE)) + ); + + org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ShowCasesDialog.class, "ShowCasesDialog.closeButton.text")); // NOI18N + closeButton.setActionCommand(org.openide.util.NbBundle.getMessage(ShowCasesDialog.class, "ShowCasesDialog.closeButton.actionCommand")); // NOI18N + closeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 4, Short.MAX_VALUE) + .addComponent(showCasesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 4, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(closeButton) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 6, Short.MAX_VALUE) + .addComponent(showCasesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 426, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(closeButton) + .addContainerGap()) + ); + + closeButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ShowCasesDialog.class, "ShowCasesDialog.closeButton.AccessibleContext.accessibleName")); // NOI18N + + pack(); + }// //GEN-END:initComponents + + private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed + dispose(); + }//GEN-LAST:event_closeButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTable caseDetailsTable; + private javax.swing.JButton closeButton; + private javax.swing.JScrollPane innerCaseScrollPane; + private javax.swing.JPanel outCasesPane; + private javax.swing.JPanel showCasesPanel; + private javax.swing.JScrollPane showCasesScrollPane; + // End of variables declaration//GEN-END:variables + + + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesTableModel.java new file mode 100644 index 0000000000..def6cb15b6 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ShowCasesTableModel.java @@ -0,0 +1,187 @@ +/* + * Central Repository + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.optionspanel; + +import java.util.ArrayList; +import java.util.List; +import javax.swing.table.AbstractTableModel; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; + +/** + * Model for cells to display correlation case information + */ +class ShowCasesTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + + @Messages({"ShowCasesTableModel.case=Case Name", + "ShowCasesTableModel.creationDate=Creation Date", + "ShowCasesTableModel.caseNumber=Case Number", + "ShowCasesTableModel.examinerName=Examiner Name", + "ShowCasesTableModel.examinerEmail=Examiner Email", + "ShowCasesTableModel.examinerPhone=Examiner Phone", + "ShowCasesTableModel.notes=Notes", + "ShowCasesTableModel.noData=No Cases"}) + /** + * Enum which lists columns of interest from CorrelationCase. + */ + enum TableColumns { + // Ordering here determines displayed column order in Content Viewer. + // If order is changed, update the CellRenderer to ensure correct row coloring. + CASE_NAME(Bundle.ShowCasesTableModel_case(), 200), + CREATION_DATE(Bundle.ShowCasesTableModel_creationDate(), 150), + CASE_NUMBER(Bundle.ShowCasesTableModel_caseNumber(), 100), + EXAMINER_NAME(Bundle.ShowCasesTableModel_examinerName(), 200), + EXAMINER_EMAIL(Bundle.ShowCasesTableModel_examinerEmail(), 100), + EXAMINER_PHONE(Bundle.ShowCasesTableModel_examinerPhone(), 100), + NOTES(Bundle.ShowCasesTableModel_notes(), 450); + + private final String columnName; + private final int columnWidth; + + TableColumns(String columnName, int columnWidth) { + this.columnName = columnName; + this.columnWidth = columnWidth; + } + + String columnName() { + return columnName; + } + + int columnWidth() { + return columnWidth; + } + }; + + /** + * list of Eam Cases from central repository. + */ + private List eamCases; + + ShowCasesTableModel() { + eamCases = new ArrayList<>(); + } + + @Override + public int getColumnCount() { + return TableColumns.values().length; + } + + /** + * Get the preferred width that has been configured for this column. + * + * A value of 0 means that no preferred width has been defined for this + * column. + * + * @param colIdx Column index + * + * @return preferred column width >= 0 + */ + int getColumnPreferredWidth(int colIdx) { + return TableColumns.values()[colIdx].columnWidth(); + } + + @Override + public int getRowCount() { + return eamCases.size(); + } + + @Override + public String getColumnName(int colIdx) { + return TableColumns.values()[colIdx].columnName(); + } + + @Override + public Object getValueAt(int rowIdx, int colIdx) { + if (eamCases.isEmpty()) { + return Bundle.ShowCasesTableModel_noData(); + } + + return mapValueById(rowIdx, TableColumns.values()[colIdx]); + } + + Object getRow(int rowIdx) { + return eamCases.get(rowIdx); + } + + /** + * Map a rowIdx and colId to the value in that cell. + * + * @param rowIdx Index of row to search + * @param colId ID of column to search + * + * @return value in the cell + */ + private Object mapValueById(int rowIdx, TableColumns colId) { + CorrelationCase eamCase = eamCases.get(rowIdx); + String value = Bundle.ShowCasesTableModel_noData(); + + switch (colId) { + case CASE_NAME: + value = eamCase.getDisplayName(); + break; + case CREATION_DATE: + value = eamCase.getCreationDate(); + break; + case CASE_NUMBER: + value = eamCase.getCaseNumber(); + break; + case EXAMINER_NAME: + value = eamCase.getExaminerName(); + break; + case EXAMINER_EMAIL: + value = eamCase.getExaminerEmail(); + break; + case EXAMINER_PHONE: + value = eamCase.getExaminerPhone(); + break; + case NOTES: + value = eamCase.getNotes(); + break; + default: + break; + } + return value; + } + + @Override + public Class getColumnClass(int colIdx) { + return String.class; + } + + /** + * Add one local central repository case to the table. + * + * @param eamCase central repository case to add to the + * table + */ + void addEamCase(CorrelationCase eamCase) { + eamCases.add(eamCase); + fireTableDataChanged(); + } + + void clearTable() { + eamCases.clear(); + fireTableDataChanged(); + } + + + +}