mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
3408 clean up and bug fixes for MultiUserCasePanel
This commit is contained in:
parent
978f37620b
commit
b2915ef4f8
@ -23,11 +23,13 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import org.netbeans.swing.etable.ETableColumn;
|
||||
import org.netbeans.swing.etable.ETableColumnModel;
|
||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||
import org.netbeans.swing.outline.Outline;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.openide.nodes.Node;
|
||||
|
||||
/**
|
||||
* A Swing JPanel with a JTabbedPane child component. The tabbed pane contains
|
||||
@ -56,10 +58,10 @@ class CaseBrowser extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Outline outline;
|
||||
private final Outline outline;
|
||||
private ExplorerManager em;
|
||||
private org.openide.explorer.view.OutlineView outlineView;
|
||||
|
||||
private final org.openide.explorer.view.OutlineView outlineView;
|
||||
private int originalPathColumnIndex = 0;
|
||||
/**
|
||||
* Creates new form CaseBrowser
|
||||
*/
|
||||
@ -71,13 +73,28 @@ class CaseBrowser extends javax.swing.JPanel {
|
||||
outlineView.setPropertyColumns(
|
||||
Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
|
||||
Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(),
|
||||
Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath()
|
||||
);
|
||||
Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath());
|
||||
customize();
|
||||
|
||||
}
|
||||
|
||||
private void customize() {
|
||||
TableColumnModel columnModel = outline.getColumnModel();
|
||||
int dateColumnIndex = 0;
|
||||
for (int index = 0; index < columnModel.getColumnCount(); index++) { //get indexes for hidden column and default sorting column
|
||||
if (columnModel.getColumn(index).getHeaderValue().toString().equals(Bundle.CaseNode_column_metadataFilePath())) {
|
||||
originalPathColumnIndex = index;
|
||||
} else if (columnModel.getColumn(index).getHeaderValue().toString().equals(Bundle.CaseNode_column_createdTime())) {
|
||||
dateColumnIndex = index;
|
||||
}
|
||||
}
|
||||
ETableColumn column = (ETableColumn) columnModel.getColumn(originalPathColumnIndex);
|
||||
((ETableColumnModel) columnModel).setColumnHidden(column, true);
|
||||
outline.setRootVisible(false);
|
||||
|
||||
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CaseNode_column_name());
|
||||
outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
outline.setColumnSorted(1, false, 1); //it would be nice if the column index wasn't hardcoded
|
||||
|
||||
outline.setColumnSorted(dateColumnIndex, false, 1); //it would be nice if the column index wasn't hardcoded
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,37 +119,28 @@ class CaseBrowser extends javax.swing.JPanel {
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
public void addListSelectionListener(ListSelectionListener listener) {
|
||||
void setRowSelectionAllowed(boolean allowed) {
|
||||
outline.setRowSelectionAllowed(allowed);
|
||||
}
|
||||
|
||||
void addListSelectionListener(ListSelectionListener listener) {
|
||||
outline.getSelectionModel().addListSelectionListener(listener);
|
||||
}
|
||||
|
||||
String getCasePath() {
|
||||
int[] selectedRows = outline.getSelectedRows();
|
||||
System.out.println("Explored Context: " + em.getExploredContext());
|
||||
System.out.println("EM ROOT NODe: " + em.getRootContext().getDisplayName());
|
||||
if (selectedRows.length == 1) {
|
||||
System.out.println("Selected Row: " + selectedRows[0]);
|
||||
for (int colIndex = 0; colIndex < outline.getColumnCount(); colIndex++) {
|
||||
TableColumn col = outline.getColumnModel().getColumn(colIndex);
|
||||
System.out.println("COL: " + col.getHeaderValue().toString());
|
||||
if (col.getHeaderValue().toString().equals(Bundle.CaseNode_column_metadataFilePath())) {
|
||||
try {
|
||||
return ((NodeProperty)outline.getValueAt(selectedRows[0], colIndex)).getValue().toString();
|
||||
} catch (IllegalAccessException ex) {
|
||||
|
||||
} catch (InvocationTargetException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
try {
|
||||
return ((Node.Property) outline.getModel().getValueAt(outline.convertRowIndexToModel(selectedRows[0]), originalPathColumnIndex)).getValue().toString();
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
System.out.println("THROW");
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
boolean isRowSelected() {
|
||||
System.out.println("SELECTED ROWS: " + outline.getSelectedRows().length);
|
||||
return outline.getSelectedRows().length > 0;
|
||||
return outline.getRowSelectionAllowed() && outline.getSelectedRows().length > 0;
|
||||
}
|
||||
|
||||
private void setColumnWidths() {
|
||||
@ -141,8 +149,8 @@ class CaseBrowser extends javax.swing.JPanel {
|
||||
|
||||
final int rows = Math.min(100, outline.getRowCount());
|
||||
|
||||
for (int column = 0; column < outline.getModel().getColumnCount(); column++) {
|
||||
int columnWidthLimit = 500;
|
||||
for (int column = 0; column < outline.getColumnModel().getColumnCount(); column++) {
|
||||
int columnWidthLimit = 800;
|
||||
int columnWidth = 0;
|
||||
|
||||
// find the maximum width needed to fit the values for the first 100 rows, at most
|
||||
|
@ -19,7 +19,6 @@
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -38,6 +37,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||
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
|
||||
@ -66,18 +66,17 @@ public final class CaseNode extends AbstractNode {
|
||||
|
||||
static class CaseNodeChildren extends ChildFactory<Entry<CaseMetadata, Boolean>> {
|
||||
|
||||
Map<CaseMetadata, Boolean> caseList;
|
||||
private final Map<CaseMetadata, Boolean> caseMap;
|
||||
|
||||
public CaseNodeChildren(Map<CaseMetadata, Boolean> caseList) {
|
||||
this.caseList = caseList;
|
||||
CaseNodeChildren(Map<CaseMetadata, Boolean> caseMap) {
|
||||
this.caseMap = caseMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<Entry<CaseMetadata, Boolean>> list) {
|
||||
if (caseList != null && caseList.size() > 0) {
|
||||
list.addAll(caseList.entrySet());
|
||||
if (caseMap != null && caseMap.size() > 0) {
|
||||
list.addAll(caseMap.entrySet());
|
||||
}
|
||||
System.out.println("NUM OF KEYS: " + list.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -94,18 +93,20 @@ public final class CaseNode extends AbstractNode {
|
||||
*/
|
||||
public static final class CaseNameNode extends DisplayableItemNode {
|
||||
|
||||
CaseMetadata multiUserCase;
|
||||
String caseMetadataFilePath;
|
||||
boolean caseHasAlert;
|
||||
private final String caseName;
|
||||
private final String caseCreatedDate;
|
||||
private final String caseMetadataFilePath;
|
||||
private final boolean caseHasAlert;
|
||||
|
||||
CaseNameNode(Entry<CaseMetadata, Boolean> userCase) {
|
||||
super(Children.LEAF);
|
||||
multiUserCase = userCase.getKey();
|
||||
caseName = userCase.getKey().getCaseDisplayName();
|
||||
caseCreatedDate = userCase.getKey().getCreatedDate();
|
||||
caseHasAlert = userCase.getValue();
|
||||
super.setName(multiUserCase.getCaseDisplayName());
|
||||
setName(multiUserCase.getCaseDisplayName());
|
||||
setDisplayName(multiUserCase.getCaseDisplayName());
|
||||
caseMetadataFilePath = multiUserCase.getFilePath().toString();
|
||||
super.setName(caseName);
|
||||
setName(caseName);
|
||||
setDisplayName(caseName);
|
||||
caseMetadataFilePath = userCase.getKey().getFilePath().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,7 +123,7 @@ public final class CaseNode extends AbstractNode {
|
||||
public String getItemType() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
|
||||
public String getMetadataFilePath() {
|
||||
return caseMetadataFilePath;
|
||||
}
|
||||
@ -136,9 +137,9 @@ public final class CaseNode extends AbstractNode {
|
||||
s.put(ss);
|
||||
}
|
||||
ss.put(new NodeProperty<>(Bundle.CaseNode_column_name(), Bundle.CaseNode_column_name(), Bundle.CaseNode_column_name(),
|
||||
multiUserCase.getCaseDisplayName()));
|
||||
caseName));
|
||||
ss.put(new NodeProperty<>(Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
|
||||
multiUserCase.getCreatedDate()));
|
||||
caseCreatedDate));
|
||||
ss.put(new NodeProperty<>(Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(),
|
||||
(caseHasAlert == true ? "Alert" : "")));
|
||||
ss.put(new NodeProperty<>(Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath(),
|
||||
@ -150,7 +151,7 @@ public final class CaseNode extends AbstractNode {
|
||||
public Action[] getActions(boolean context) {
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.addAll(Arrays.asList(super.getActions(context)));
|
||||
actions.add(new OpenMultiUserCaseAction(multiUserCase.getFilePath()));
|
||||
actions.add(new OpenMultiUserCaseAction(caseMetadataFilePath));
|
||||
return actions.toArray(new Action[actions.size()]);
|
||||
}
|
||||
}
|
||||
@ -162,9 +163,9 @@ public final class CaseNode extends AbstractNode {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Path caseMetadataFilePath;
|
||||
private final String caseMetadataFilePath;
|
||||
|
||||
public OpenMultiUserCaseAction(Path path) {
|
||||
OpenMultiUserCaseAction(String path) {
|
||||
super("Open Case");
|
||||
caseMetadataFilePath = path;
|
||||
}
|
||||
@ -172,32 +173,32 @@ public final class CaseNode extends AbstractNode {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
StartupWindowProvider.getInstance().close();
|
||||
openCaseThread(caseMetadataFilePath);
|
||||
new Thread(
|
||||
() -> {
|
||||
try {
|
||||
Case.openAsCurrentCase(caseMetadataFilePath);
|
||||
} catch (CaseActionException ex) {
|
||||
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||
// LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
//GUI changes done back on the EDT
|
||||
StartupWindowProvider.getInstance().open();
|
||||
});
|
||||
} finally {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
//GUI changes done back on the EDT
|
||||
});
|
||||
}
|
||||
}
|
||||
).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone(); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
}
|
||||
|
||||
private static void openCaseThread(Path caseMetadataFilePath) {
|
||||
|
||||
new Thread(
|
||||
() -> {
|
||||
try {
|
||||
Case.openAsCurrentCase(caseMetadataFilePath.toString());
|
||||
} catch (CaseActionException ex) {
|
||||
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||
// LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
//GUI changes done back on the EDT
|
||||
StartupWindowProvider.getInstance().open();
|
||||
});
|
||||
} finally {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
//GUI changes done back on the EDT
|
||||
});
|
||||
}
|
||||
}
|
||||
).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,13 +45,12 @@ import org.sleuthkit.autopsy.coordinationservice.CaseNodeData;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.datamodel.EmptyNode;
|
||||
|
||||
/**
|
||||
* A panel that allows a user to open cases created by auto ingest.
|
||||
*/
|
||||
@NbBundle.Messages({"MultiUSerCasesPanel.caseListLoading.message=Retrieving list of cases, please wait..."})
|
||||
@NbBundle.Messages({"MultiUserCasesPanel.caseListLoading.message=Please wait..."})
|
||||
final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.Provider {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@ -73,7 +72,7 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
|
||||
caseListPanel = new CaseBrowser();
|
||||
caseListPanel.open();
|
||||
|
||||
caseListPanel.setRowSelectionAllowed(false);
|
||||
caseExplorerScrollPane.add(caseListPanel);
|
||||
caseExplorerScrollPane.setViewportView(caseListPanel);
|
||||
/*
|
||||
@ -92,11 +91,13 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
*/
|
||||
void refresh() {
|
||||
if (tableWorker == null || tableWorker.isDone()) {
|
||||
caseListPanel.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());
|
||||
explorerManager.setRootContext(emptyNode);
|
||||
tableWorker = new LoadCaseListWorker();
|
||||
tableWorker.execute();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -117,7 +118,6 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
*/
|
||||
private void openCase(String caseMetadataFilePath) {
|
||||
if (caseMetadataFilePath != null) {
|
||||
System.out.println("OPENENING CASE: " + caseMetadataFilePath);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
|
||||
StartupWindowProvider.getInstance().close();
|
||||
@ -296,7 +296,7 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
* @throws CoordinationServiceException
|
||||
*/
|
||||
private Map<CaseMetadata, Boolean> getCases() throws CoordinationService.CoordinationServiceException {
|
||||
Map<CaseMetadata, Boolean> cases = new HashMap<>();
|
||||
Map<CaseMetadata, Boolean> casesMap = new HashMap<>();
|
||||
List<String> nodeList = CoordinationService.getInstance().getNodeList(CoordinationService.CategoryNode.CASES);
|
||||
|
||||
for (String node : nodeList) {
|
||||
@ -352,7 +352,7 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
}
|
||||
|
||||
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(autFilePath));
|
||||
cases.put(caseMetadata, hasAlertStatus);
|
||||
casesMap.put(caseMetadata, hasAlertStatus);
|
||||
} catch (CaseMetadata.CaseMetadataException ex) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
|
||||
} catch (InterruptedException | CaseNodeData.InvalidDataException ex) {
|
||||
@ -361,7 +361,7 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
}
|
||||
}
|
||||
}
|
||||
return cases;
|
||||
return casesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -381,18 +381,7 @@ final class MultiUserCasesPanel extends TopComponent implements ExplorerManager.
|
||||
EventQueue.invokeLater(() -> {
|
||||
CaseNode caseListNode = new CaseNode(cases);
|
||||
explorerManager.setRootContext(caseListNode);
|
||||
String displayName = "";
|
||||
Content content = caseListNode.getLookup().lookup(Content.class);
|
||||
if (content != null) {
|
||||
try {
|
||||
displayName = content.getUniquePath();
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while calling Content.getUniquePath() for node: {0}", caseListNode); //NON-NLS
|
||||
}
|
||||
} else if (caseListNode.getLookup().lookup(String.class) != null) {
|
||||
displayName = caseListNode.getLookup().lookup(String.class);
|
||||
}
|
||||
System.out.println("GET CASES DONE");
|
||||
caseListPanel.setRowSelectionAllowed(true);
|
||||
setButtons();
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user