diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form
index cdb5a13686..edda7a749c 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form
@@ -24,7 +24,7 @@
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java
index 1eaef654eb..4c7980fe32 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java
@@ -39,44 +39,29 @@ import java.util.Map;
import java.util.logging.Level;
import javax.swing.SwingWorker;
import org.openide.explorer.ExplorerManager;
+import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coordinationservice.CaseNodeData;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.EmptyNode;
/**
- * A Swing JPanel with a JTabbedPane child component. The tabbed pane contains
- * result viewers.
+ * A Swing JPanel with a scroll pane child component. The scroll pane contain
+ * the table of cases.
*
- * The "main" DataResultPanel for the desktop application has a table viewer
- * (DataResultViewerTable) and a thumbnail viewer (DataResultViewerThumbnail),
- * plus zero to many additional DataResultViewers, since the DataResultViewer
- * interface is an extension point.
+ * Used to display a list of multi user cases and allow the user to open one of
+ * them.
*
- * The "main" DataResultPanel resides in the "main" results view
- * (DataResultTopComponent) that is normally docked into the upper right hand
- * side of the main window of the desktop application.
- *
- * The result viewers in the "main panel" are used to view the child nodes of a
- * node selected in the tree view (DirectoryTreeTopComponent) that is normally
- * docked into the left hand side of the main window of the desktop application.
- *
- * Nodes selected in the child results viewers of a DataResultPanel are
- * displayed in a content view (implementation of the DataContent interface)
- * supplied the panel. The default content view is (DataContentTopComponent) is
- * normally docked into the lower right hand side of the main window, underneath
- * the results view. A custom content view may be specified instead.
*/
class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider {
private static final long serialVersionUID = 1L;
-
private final Outline outline;
private ExplorerManager em;
private final org.openide.explorer.view.OutlineView outlineView;
private int originalPathColumnIndex = 0;
private static final Logger LOGGER = Logger.getLogger(CaseBrowser.class.getName());
- private LoadCaseListWorker tableWorker;
+ private LoadCaseMapWorker tableWorker;
@Override
public ExplorerManager getExplorerManager() {
@@ -84,7 +69,7 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
}
/**
- * Creates new form CaseBrowser
+ * Creates a new CaseBrowser
*/
CaseBrowser() {
outlineView = new org.openide.explorer.view.OutlineView();
@@ -99,6 +84,9 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
}
+ /**
+ * Configures the the table of cases and its columns.
+ */
private void customize() {
TableColumnModel columnModel = outline.getColumnModel();
int dateColumnIndex = 0;
@@ -116,25 +104,20 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CaseNode_column_name());
outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
outline.setColumnSorted(dateColumnIndex, false, 1); //it would be nice if the column index wasn't hardcoded
- }
-
- /**
- * Initializes this panel. Intended to be called by a parent top component
- * when the top component is opened.
- */
- void open() {
if (null == em) {
em = new ExplorerManager();
}
- jScrollPane1.setViewportView(outlineView);
+ caseTableScrollPane.setViewportView(outlineView);
setColumnWidths();
this.setVisible(true);
+ outline.setRowSelectionAllowed(false);
}
- void setRowSelectionAllowed(boolean allowed) {
- outline.setRowSelectionAllowed(allowed);
- }
-
+ /**
+ * Add a listener to changes in case selections in the table
+ *
+ * @param listener the ListSelectionListener to add
+ */
void addListSelectionListener(ListSelectionListener listener) {
outline.getSelectionModel().addListSelectionListener(listener);
}
@@ -145,12 +128,17 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
try {
return ((Node.Property) outline.getModel().getValueAt(outline.convertRowIndexToModel(selectedRows[0]), originalPathColumnIndex)).getValue().toString();
} catch (IllegalAccessException | InvocationTargetException ex) {
- System.out.println("THROW");
+ //WJS-TODO THROW SOMETHING
}
}
return null;
}
+ /**
+ * Check if a row could be and is selected.
+ *
+ * @return true if a row is selected, false if no row is selected
+ */
boolean isRowSelected() {
return outline.getRowSelectionAllowed() && outline.getSelectedRows().length > 0;
}
@@ -162,8 +150,8 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
final int rows = Math.min(100, outline.getRowCount());
for (int column = 0; column < outline.getColumnModel().getColumnCount(); column++) {
- int columnWidthLimit = 800;
- int columnWidth = 0;
+ int columnWidthLimit = 2000;
+ int columnWidth = 200;
// find the maximum width needed to fit the values for the first 100 rows, at most
for (int row = 0; row < rows; row++) {
@@ -179,18 +167,19 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
}
}
+ @NbBundle.Messages({"CaseBrowser.caseListLoading.message=Please Wait..."})
/**
* Gets the list of cases known to the review mode cases manager and
* refreshes the cases table.
*/
void refresh() {
if (tableWorker == null || tableWorker.isDone()) {
- setRowSelectionAllowed(false);
+ outline.setRowSelectionAllowed(false);
//create a new TableWorker to and execute it in a background thread if one is not currently working
//set the table to display text informing the user that the list is being retreived and disable case selection
- EmptyNode emptyNode = new EmptyNode(Bundle.MultiUserCasesPanel_caseListLoading_message());
+ EmptyNode emptyNode = new EmptyNode(Bundle.CaseBrowser_caseListLoading_message());
em.setRootContext(emptyNode);
- tableWorker = new LoadCaseListWorker();
+ tableWorker = new LoadCaseMapWorker();
tableWorker.execute();
}
@@ -205,22 +194,27 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
// //GEN-BEGIN:initComponents
private void initComponents() {
- jScrollPane1 = new javax.swing.JScrollPane();
+ caseTableScrollPane = new javax.swing.JScrollPane();
setMinimumSize(new java.awt.Dimension(0, 5));
setPreferredSize(new java.awt.Dimension(5, 5));
setLayout(new java.awt.BorderLayout());
- jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
- jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 5));
- jScrollPane1.setOpaque(false);
- jScrollPane1.setPreferredSize(new java.awt.Dimension(5, 5));
- add(jScrollPane1, java.awt.BorderLayout.CENTER);
+ caseTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+ caseTableScrollPane.setMinimumSize(new java.awt.Dimension(0, 5));
+ caseTableScrollPane.setOpaque(false);
+ caseTableScrollPane.setPreferredSize(new java.awt.Dimension(5, 5));
+ add(caseTableScrollPane, java.awt.BorderLayout.CENTER);
}// //GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JScrollPane caseTableScrollPane;
// End of variables declaration//GEN-END:variables
- private class LoadCaseListWorker extends SwingWorker {
+
+ /**
+ * Swingworker to fetch the updated map of cases and their status in a
+ * background thread
+ */
+ private class LoadCaseMapWorker extends SwingWorker {
private static final String ALERT_FILE_NAME = "autoingest.alert";
private Map cases;
@@ -314,11 +308,11 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
@Override
protected void done() {
-
EventQueue.invokeLater(() -> {
- CaseNode caseListNode = new CaseNode(cases);
+ MultiUserNode caseListNode = new MultiUserNode(cases);
em.setRootContext(caseListNode);
- setRowSelectionAllowed(true);
+ setColumnWidths();
+ outline.setRowSelectionAllowed(true);
});
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java
index 5eaa5bed6d..a2a2ec13ad 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java
@@ -30,19 +30,18 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
/**
* A panel that allows a user to open cases created by auto ingest.
*/
-@NbBundle.Messages({"MultiUserCasesPanel.caseListLoading.message=Please Wait..."})
final class MultiUserCasesPanel extends JPanel{
private static final Logger LOGGER = Logger.getLogger(MultiUserCasesPanel.class.getName());
+ private static final long serialVersionUID = 1L;
private final JDialog parentDialog;
- private final CaseBrowser caseListPanel;
+ private final CaseBrowser caseBrowserPanel;
/**
* Constructs a panel that allows a user to open cases created by automated
@@ -52,16 +51,14 @@ final class MultiUserCasesPanel extends JPanel{
this.parentDialog = parentDialog;
initComponents();
- caseListPanel = new CaseBrowser();
- caseListPanel.open();
- caseListPanel.setRowSelectionAllowed(false);
- caseExplorerScrollPane.add(caseListPanel);
- caseExplorerScrollPane.setViewportView(caseListPanel);
+ caseBrowserPanel = new CaseBrowser();
+ caseExplorerScrollPane.add(caseBrowserPanel);
+ caseExplorerScrollPane.setViewportView(caseBrowserPanel);
/*
* Listen for row selection changes and set button state for the current
* selection.
*/
- caseListPanel.addListSelectionListener((ListSelectionEvent e) -> {
+ caseBrowserPanel.addListSelectionListener((ListSelectionEvent e) -> {
setButtons();
});
@@ -72,7 +69,7 @@ final class MultiUserCasesPanel extends JPanel{
* refreshes the cases table.
*/
void refresh() {
- caseListPanel.refresh();
+ caseBrowserPanel.refresh();
}
/**
@@ -80,7 +77,7 @@ final class MultiUserCasesPanel extends JPanel{
* in the cases table.
*/
void setButtons() {
- bnOpen.setEnabled(caseListPanel.isRowSelected());
+ bnOpen.setEnabled(caseBrowserPanel.isRowSelected());
}
/**
@@ -229,7 +226,7 @@ final class MultiUserCasesPanel extends JPanel{
* @param evt -- The event that caused this to be called
*/
private void bnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenActionPerformed
- openCase(caseListPanel.getCasePath());
+ openCase(caseBrowserPanel.getCasePath());
}//GEN-LAST:event_bnOpenActionPerformed
private void bnOpenSingleUserCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenSingleUserCaseActionPerformed
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java
index 87862d4d01..c410afb71b 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2016 Basis Technology Corp.
+ * Copyright 2017-2018 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -40,37 +40,31 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
/**
- * Provides a root node for the results views with a single child node that
- * displays a message as the sole item in its property sheet, useful for
- * displaying explanatory text in the result views when there is a node with no
- * children in the tree view.
+ * A root node containing child nodes of the multi user cases
*/
-public final class CaseNode extends AbstractNode {
+public final class MultiUserNode extends AbstractNode {
@Messages({"CaseNode.column.name=Name",
"CaseNode.column.createdTime=Created Time",
"CaseNode.column.status=Status",
"CaseNode.column.metadataFilePath=Path"})
- private static final Logger LOGGER = Logger.getLogger(CaseNode.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(MultiUserNode.class.getName());
/**
- * Provides a root node for the results views with a single child node that
- * displays a message as the sole item in its property sheet, useful for
- * displaying explanatory text in the result views when there is a node with
- * no children in the tree view.
+ * Provides a root node with children which each represent a case.
*
- * @param displayedMessage The text for the property sheet of the child
- * node.
+ * @param caseMap the map of cases and a boolean indicating if they have an
+ * alert
*/
- CaseNode(Map caseList) {
- super(Children.create(new CaseNodeChildren(caseList), true));
+ MultiUserNode(Map caseMap) {
+ super(Children.create(new MultiUserNodeChildren(caseMap), true));
}
- static class CaseNodeChildren extends ChildFactory> {
+ static class MultiUserNodeChildren extends ChildFactory> {
private final Map caseMap;
- CaseNodeChildren(Map caseMap) {
+ MultiUserNodeChildren(Map caseMap) {
this.caseMap = caseMap;
}
@@ -84,31 +78,30 @@ public final class CaseNode extends AbstractNode {
@Override
protected Node createNodeForKey(Entry key) {
- return new CaseNameNode(key);
+ return new MultiUserCaseNode(key);
}
}
/**
- * The single child node of an EmptyNode, responsible for displaying a
- * message as the sole item in its property sheet.
+ * A node which represents a single multi user case.
*/
- public static final class CaseNameNode extends DisplayableItemNode {
+ public static final class MultiUserCaseNode extends DisplayableItemNode {
private final String caseName;
private final String caseCreatedDate;
private final String caseMetadataFilePath;
private final boolean caseHasAlert;
- CaseNameNode(Entry userCase) {
+ MultiUserCaseNode(Entry multiUserCase) {
super(Children.LEAF);
- caseName = userCase.getKey().getCaseDisplayName();
- caseCreatedDate = userCase.getKey().getCreatedDate();
- caseHasAlert = userCase.getValue();
+ caseName = multiUserCase.getKey().getCaseDisplayName();
+ caseCreatedDate = multiUserCase.getKey().getCreatedDate();
+ caseHasAlert = multiUserCase.getValue();
super.setName(caseName);
setName(caseName);
setDisplayName(caseName);
- caseMetadataFilePath = userCase.getKey().getFilePath().toString();
+ caseMetadataFilePath = multiUserCase.getKey().getFilePath().toString();
}
@Override
@@ -152,14 +145,14 @@ public final class CaseNode extends AbstractNode {
@Override
public Action[] getActions(boolean context) {
List actions = new ArrayList<>();
- // actions.addAll(Arrays.asList(super.getActions(context)));
- actions.add(new OpenMultiUserCaseAction(caseMetadataFilePath));
+ actions.add(new OpenMultiUserCaseAction(caseMetadataFilePath)); //open case context menu option
return actions.toArray(new Action[actions.size()]);
}
}
/**
- * An action that opens the case node which it was generated off of
+ * An action that opens the specified case and hides the multi user case
+ * panel.
*/
private static final class OpenMultiUserCaseAction extends AbstractAction {
@@ -188,10 +181,7 @@ public final class CaseNode extends AbstractNode {
SwingUtilities.invokeLater(() -> {
//GUI changes done back on the EDT
StartupWindowProvider.getInstance().open();
- });
- } finally {
- SwingUtilities.invokeLater(() -> {
- //GUI changes done back on the EDT
+ MultiUserCasesDialog.getInstance().setVisible(true);
});
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java
index d95c8f099e..f6d461e578 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java
@@ -18,7 +18,7 @@
*/
package org.sleuthkit.autopsy.datamodel;
-import org.sleuthkit.autopsy.casemodule.CaseNode;
+import org.sleuthkit.autopsy.casemodule.MultiUserNode;
import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode;
import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode;
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode;
@@ -159,7 +159,7 @@ public interface DisplayableItemNodeVisitor {
T visit(EmptyNode.MessageNode emptyNode);
- T visit(CaseNode.CaseNameNode caseNode);
+ T visit(MultiUserNode.MultiUserCaseNode caseNode);
T visit(InterestingHits.InterestingItemTypeNode aThis);
@@ -245,7 +245,7 @@ public interface DisplayableItemNodeVisitor {
return defaultVisit(ftByMimeTypeEmptyNode);
}
@Override
- public T visit(CaseNode.CaseNameNode caseNameNode) {
+ public T visit(MultiUserNode.MultiUserCaseNode caseNameNode) {
return defaultVisit(caseNameNode);
}
@Override