From 9d4f6bb146c53cb226bd025a48fcfb121e801c1c Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 10 Jan 2018 12:30:07 -0500 Subject: [PATCH] 3408 clean up comments and names for multi user case explorer changes --- .../autopsy/casemodule/CaseBrowser.form | 2 +- .../autopsy/casemodule/CaseBrowser.java | 96 +++++++++---------- .../casemodule/MultiUserCasesPanel.java | 21 ++-- .../autopsy/casemodule/MultiUserNode.java | 56 +++++------ .../datamodel/DisplayableItemNodeVisitor.java | 6 +- 5 files changed, 81 insertions(+), 100 deletions(-) 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