mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Complete new documentation of core result viewers
This commit is contained in:
parent
b188d76cb8
commit
21bb53b223
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-17 Basis Technology Corp.
|
||||
* Copyright 2012-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -22,76 +22,117 @@ import java.awt.Component;
|
||||
import org.openide.nodes.Node;
|
||||
|
||||
/**
|
||||
* Interface for the different viewers that show a set of nodes in the
|
||||
* DataResult area. AbstractDataResultViewer has default implementations for the
|
||||
* action handlers.
|
||||
* An interface for result viewers. A result viewer uses a Swing component to
|
||||
* provide a view of the application data represented by a given NetBeans node.
|
||||
* Result viewers typically appear in a result view (a DataResultTopComponent)
|
||||
* docked into the upper right hand side of the main application window.
|
||||
*
|
||||
* Typically, a result viewer is a JPanel that displays the child nodes of the
|
||||
* given node using a NetBeans explorer view as a child component. Such a result
|
||||
* viewer should use the explorer manager of the ancestor top component to
|
||||
* connect the lookups of the nodes displayed in the NetBeans explorer view to
|
||||
* the actions global context. It is strongly recommended that this type of
|
||||
* result viewer extends the abstract base class AbstractDataResultViewer, which
|
||||
* will handle some key aspects of working with the ancestor top component's
|
||||
* explorer manager.
|
||||
*
|
||||
* This interface is an extension point, so classes that implement it should
|
||||
* provide an appropriate ServiceProvider annotation.
|
||||
*
|
||||
*/
|
||||
public interface DataResultViewer {
|
||||
|
||||
/**
|
||||
* Set the root node to display in this viewer. When called with null, must
|
||||
* clear all references to previous nodes.
|
||||
*/
|
||||
public void setNode(Node selectedNode);
|
||||
|
||||
/**
|
||||
* Gets the title of this viewer
|
||||
*/
|
||||
public String getTitle();
|
||||
|
||||
/**
|
||||
* Get a new instance of DataResultViewer
|
||||
* Creates a new instance of this result viewer, which allows the
|
||||
* application to use the capability provided by this result viewer in more
|
||||
* than one result view. This is done by using the default instance of this
|
||||
* result viewer as a "factory" for creating other instances.
|
||||
*/
|
||||
public DataResultViewer createInstance();
|
||||
|
||||
/**
|
||||
* Get the Swing component (i.e. JPanel) for this viewer
|
||||
* Indicates whether this result viewer is able to provide a meaningful view
|
||||
* of the application data represented by a given node. Typically, indicates
|
||||
* whether or not this result viewer can use the given node as the root node
|
||||
* of its child explorer view component.
|
||||
*
|
||||
* @param node The node.
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
public boolean isSupported(Node node);
|
||||
|
||||
/**
|
||||
* Sets the node for which this result viewer should provide a view of the
|
||||
* underlying application data. Typically, this means using the given node
|
||||
* as the root node of this result viewer's child explorer view component.
|
||||
*
|
||||
* @param node The node, may be null. If null, the call to this method is
|
||||
* equivalent to a call to resetComponent.
|
||||
*/
|
||||
public void setNode(Node node);
|
||||
|
||||
/**
|
||||
* Requests selection of the given child nodes of the node passed to
|
||||
* setNode. This method should be implemented as a no-op for result viewers
|
||||
* that do not display the child nodes of a given root node using a NetBeans
|
||||
* explorer view set up to use a given explorer manager.
|
||||
*
|
||||
* @param selectedNodes The child nodes to select.
|
||||
*/
|
||||
default public void setSelectedNodes(Node[] selectedNodes) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title of this result viewer.
|
||||
*
|
||||
* @return The title.
|
||||
*/
|
||||
public String getTitle();
|
||||
|
||||
/**
|
||||
* Gets the Swing component for this viewer.
|
||||
*
|
||||
* @return The component.
|
||||
*/
|
||||
public Component getComponent();
|
||||
|
||||
/**
|
||||
* Resets the viewer.
|
||||
* Resets the state of the Swing component for this viewer to its default
|
||||
* state.
|
||||
*/
|
||||
public void resetComponent();
|
||||
default public void resetComponent() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the objects that have been allocated by this viewer, in preparation
|
||||
* for permanently disposing of it.
|
||||
* Frees any resources tha have been allocated by this result viewer, in
|
||||
* preparation for permanently disposing of it.
|
||||
*/
|
||||
public void clearComponent();
|
||||
default public void clearComponent() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand node, if supported by the viewed
|
||||
* Sets the node for which this result viewer should provide a view of the
|
||||
* underlying application data model object, and expands the node.
|
||||
*
|
||||
* @param n Node to expand
|
||||
*/
|
||||
public void expandNode(Node n);
|
||||
|
||||
/**
|
||||
* Select the given node array
|
||||
*/
|
||||
public void setSelectedNodes(Node[] selected);
|
||||
|
||||
/**
|
||||
* Checks whether the currently selected root node is supported by this
|
||||
* viewer
|
||||
* @param node The node.
|
||||
*
|
||||
* @param selectedNode the selected node
|
||||
*
|
||||
* @return True if supported, else false
|
||||
*/
|
||||
public boolean isSupported(Node selectedNode);
|
||||
|
||||
/**
|
||||
* Set a custom content viewer to respond to selection events from this
|
||||
* result viewer. If not set, the default content viewer is used
|
||||
*
|
||||
* @param contentViewer content viewer to respond to selection events from
|
||||
* this viewer
|
||||
*
|
||||
* @deprecated All implementations of this in the standard DataResultViewers are now no-ops.
|
||||
* @deprecated This API is not used by the application.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setContentViewer(DataContent contentViewer);
|
||||
default public void expandNode(Node node) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom content viewer to which nodes selected in this result
|
||||
* viewer should be pushed via DataContent.setNode.
|
||||
*
|
||||
* @param contentViewer The content viewer.
|
||||
*
|
||||
* @deprecated This API is not used by the application.
|
||||
*/
|
||||
@Deprecated
|
||||
default public void setContentViewer(DataContent contentViewer) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,65 +23,49 @@ import java.beans.PropertyVetoException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JPanel;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerManager.Provider;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Provides a JPanel base class that provides a default implementation of the
|
||||
* ExplorerManager.Provider interface and selected methods of
|
||||
* theDataResultViewer interface. The ExplorerManager.Provider interface is
|
||||
* implemented to supply an explorer manager to subclasses and their child
|
||||
* components. The explorer manager is expected to be the explorer manager of a
|
||||
* top component that exposes a lookup maintained by the explorer manager to the
|
||||
* actions global context. This connects the nodes displayed in the result
|
||||
* viewer to the actions global context. The explorer manager may be either
|
||||
* supplied during construction or discovered at runtime.
|
||||
* An abstract base class for an implementation of the result viewer interface
|
||||
* that is a JPanel that displays the child nodes of a given node using a
|
||||
* NetBeans explorer view as a child component. Such a result viewer should use
|
||||
* the explorer manager of an ancestor top component to connect the lookups of
|
||||
* the nodes displayed in the NetBeans explorer view to the actions global
|
||||
* context. This class handles some key aspects of working with the ancestor top
|
||||
* component's explorer manager.
|
||||
*
|
||||
* Instances of this class can be supplied with the top component's explorer
|
||||
* manager during construction, but the typical use case is for the result
|
||||
* viewer to find the ancestor top component's explorer manager at runtime.
|
||||
*
|
||||
* IMPORTANT: If the result viewer is going to find the ancestor top component's
|
||||
* explorer manager at runtime, the first call to the getExplorerManager method
|
||||
* of this class must be made AFTER the component hierarchy is fully
|
||||
* constructed.
|
||||
*
|
||||
*/
|
||||
abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, Provider {
|
||||
public abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, ExplorerManager.Provider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AbstractDataResultViewer.class.getName());
|
||||
private transient ExplorerManager explorerManager;
|
||||
|
||||
/**
|
||||
* Constructs a JPanel base class instance that provides a default
|
||||
* implementation of selected methods of the DataResultViewer and
|
||||
* ExplorerManager.Provider interfaces. The explorer manager of this viewer
|
||||
* will be discovered at runtime.
|
||||
*/
|
||||
AbstractDataResultViewer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JPanel base class instance that provides a default
|
||||
* implementation of selected methods of the DataResultViewer and
|
||||
* ExplorerManager.Provider interfaces.
|
||||
* Constructs an abstract base class for an implementation of the result
|
||||
* viewer interface that is a JPanel that displays the child nodes of the
|
||||
* given node using a NetBeans explorer view as a child component.
|
||||
*
|
||||
* @param explorerManager
|
||||
* @param explorerManager The explorer manager to use in the NetBeans
|
||||
* explorer view child component of this result
|
||||
* viewer, may be null. If null, the explorer manager
|
||||
* will be discovered the first time
|
||||
* getExplorerManager is called.
|
||||
*/
|
||||
AbstractDataResultViewer(ExplorerManager explorerManager) {
|
||||
public AbstractDataResultViewer(ExplorerManager explorerManager) {
|
||||
this.explorerManager = explorerManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearComponent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expandNode(Node n) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetComponent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
if (this.explorerManager == null) {
|
||||
@ -95,13 +79,13 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView
|
||||
try {
|
||||
this.getExplorerManager().setSelectedNodes(selected);
|
||||
} catch (PropertyVetoException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't set selected nodes.", ex); //NON-NLS
|
||||
logger.log(Level.SEVERE, "Couldn't set selected nodes", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setContentViewer(DataContent contentViewer) {
|
||||
public Component getComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 - 2018 Basis Technology Corp.
|
||||
* Copyright 2012-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -67,8 +67,14 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo;
|
||||
|
||||
/**
|
||||
* A tabular results viewer that displays the children of a given root node
|
||||
* A tabular result viewer that displays the children of the given root node
|
||||
* using an OutlineView.
|
||||
*
|
||||
* Instances of this class should use the explorer manager of an ancestor top
|
||||
* component to connect the lookups of the nodes displayed in the OutlineView to
|
||||
* the actions global context. The explorer manager can be supplied during
|
||||
* construction, but the typical use case is for the result viewer to find the
|
||||
* ancestor top component's explorer manager at runtime.
|
||||
*/
|
||||
@ServiceProvider(service = DataResultViewer.class)
|
||||
public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
@ -79,56 +85,52 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
static private final Color TAGGED_ROW_COLOR = new Color(255, 255, 195);
|
||||
private static final Logger logger = Logger.getLogger(DataResultViewerTable.class.getName());
|
||||
private final String title;
|
||||
private Outline outline;
|
||||
private TableListener outlineViewListener;
|
||||
private Node currentRootNode;
|
||||
private final Map<String, ETableColumn> columnMap = new HashMap<>();
|
||||
private final Map<Integer, Property<?>> propertiesMap = new TreeMap<>();
|
||||
private final Map<String, ETableColumn> columnMap;
|
||||
private final Map<Integer, Property<?>> propertiesMap;
|
||||
private final Outline outline;
|
||||
private final TableListener outlineViewListener;
|
||||
private Node rootNode;
|
||||
|
||||
/**
|
||||
* Constructs a tabular results viewer that displays the children of a given
|
||||
* root node using an OutlineView.
|
||||
* Constructs a tabular result viewer that displays the children of the
|
||||
* given root node using an OutlineView. The viewer should have an ancestor
|
||||
* top component to connect the lookups of the nodes displayed in the
|
||||
* OutlineView to the actions global context. The explorer manager will be
|
||||
* discovered at runtime.
|
||||
*/
|
||||
public DataResultViewerTable() {
|
||||
super();
|
||||
this.title = Bundle.DataResultViewerTable_title();
|
||||
initialize();
|
||||
this(null, Bundle.DataResultViewerTable_title());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a tabular results viewer that displays the children of a given
|
||||
* root node using an OutlineView, with a given explorer manager.
|
||||
* Constructs a tabular result viewer that displays the children of a given
|
||||
* root node using an OutlineView. The viewer should have an ancestor top
|
||||
* component to connect the lookups of the nodes displayed in the
|
||||
* OutlineView to the actions global context.
|
||||
*
|
||||
* @param explorerManager The explorer manager.
|
||||
* @param explorerManager The explorer manager of the ancestor top
|
||||
* component.
|
||||
*/
|
||||
public DataResultViewerTable(ExplorerManager explorerManager) {
|
||||
this(explorerManager, Bundle.DataResultViewerTable_title());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a tabular results viewer that displays the children of a given
|
||||
* root node using an OutlineView, with a given explorer manager, and a
|
||||
* custom title.
|
||||
* Constructs a tabular result viewer that displays the children of a given
|
||||
* root node using an OutlineView with a given title. The viewer should have
|
||||
* an ancestor top component to connect the lookups of the nodes displayed
|
||||
* in the OutlineView to the actions global context.
|
||||
*
|
||||
* @param explorerManager The explorer manager.
|
||||
* @param title The custom title.
|
||||
* @param explorerManager The explorer manager of the ancestor top
|
||||
* component.
|
||||
* @param title The title.
|
||||
*/
|
||||
public DataResultViewerTable(ExplorerManager explorerManager, String title) {
|
||||
super(explorerManager);
|
||||
this.title = title;
|
||||
initialize();
|
||||
}
|
||||
this.columnMap = new HashMap<>();
|
||||
this.propertiesMap = new TreeMap<>();
|
||||
|
||||
// @Override
|
||||
// public void addNotify() {
|
||||
// super.addNotify();
|
||||
// initialize();
|
||||
// }
|
||||
|
||||
/*
|
||||
* Initializes this tabular results viewer.
|
||||
*/
|
||||
private void initialize() {
|
||||
/*
|
||||
* Execute the code generated by the GUI builder.
|
||||
*/
|
||||
@ -159,13 +161,13 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of a tabular results viewer that displays the
|
||||
* Creates a new instance of a tabular result viewer that displays the
|
||||
* children of a given root node using an OutlineView. This method exists to
|
||||
* make it possible to use the default service provider instance of this
|
||||
* class in the "main" results view of the application, while using distinct
|
||||
* instances in other places in the UI.
|
||||
*
|
||||
* @return A new instance of a tabular results viewer,
|
||||
* @return A new instance of a tabular result viewer,
|
||||
*/
|
||||
@Override
|
||||
public DataResultViewer createInstance() {
|
||||
@ -173,7 +175,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title of this tabular results viewer.
|
||||
* Gets the title of this tabular result viewer.
|
||||
*/
|
||||
@Override
|
||||
@NbBundle.Messages("DataResultViewerTable.title=Table")
|
||||
@ -195,7 +197,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current root node of this tabular results viewer.
|
||||
* Sets the current root node of this tabular result viewer.
|
||||
*
|
||||
* @param rootNode The node to set as the current root node, possibly null.
|
||||
*/
|
||||
@ -225,8 +227,8 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* case database round trips.
|
||||
*/
|
||||
if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
|
||||
currentRootNode = rootNode;
|
||||
this.getExplorerManager().setRootContext(currentRootNode);
|
||||
this.rootNode = rootNode;
|
||||
this.getExplorerManager().setRootContext(this.rootNode);
|
||||
setupTable();
|
||||
} else {
|
||||
Node emptyNode = new AbstractNode(Children.LEAF);
|
||||
@ -241,7 +243,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the Outline view of this tabular results viewer by creating
|
||||
* Sets up the Outline view of this tabular result viewer by creating
|
||||
* column headers based on the children of the current root node. The
|
||||
* persisted column order, sorting and visibility is used.
|
||||
*/
|
||||
@ -310,10 +312,10 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* it.
|
||||
*/
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (currentRootNode instanceof TableFilterNode) {
|
||||
NodeSelectionInfo selectedChildInfo = ((TableFilterNode) currentRootNode).getChildNodeSelectionInfo();
|
||||
if (rootNode instanceof TableFilterNode) {
|
||||
NodeSelectionInfo selectedChildInfo = ((TableFilterNode) rootNode).getChildNodeSelectionInfo();
|
||||
if (null != selectedChildInfo) {
|
||||
Node[] childNodes = currentRootNode.getChildren().getNodes(true);
|
||||
Node[] childNodes = rootNode.getChildren().getNodes(true);
|
||||
for (int i = 0; i < childNodes.length; ++i) {
|
||||
Node childNode = childNodes[i];
|
||||
if (selectedChildInfo.matches(childNode)) {
|
||||
@ -325,7 +327,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
break;
|
||||
}
|
||||
}
|
||||
((TableFilterNode) currentRootNode).setChildNodeSelectionInfo(null);
|
||||
((TableFilterNode) rootNode).setChildNodeSelectionInfo(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -339,7 +341,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
|
||||
/*
|
||||
* Populates the column map for the child OutlineView of this tabular
|
||||
* results viewer with references to the column objects for use when
|
||||
* result viewer with references to the column objects for use when
|
||||
* loading/storing the visibility info.
|
||||
*/
|
||||
private void populateColumnMap() {
|
||||
@ -361,7 +363,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* viewer.
|
||||
*/
|
||||
private void setColumnWidths() {
|
||||
if (currentRootNode.getChildren().getNodesCount() != 0) {
|
||||
if (rootNode.getChildren().getNodesCount() != 0) {
|
||||
final Graphics graphics = outlineView.getGraphics();
|
||||
if (graphics != null) {
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
@ -419,14 +421,14 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
|
||||
/**
|
||||
* Persists the current column visibility information for the child
|
||||
* OutlineView of this tabular results viewer using a preferences file.
|
||||
* OutlineView of this tabular result viewer using a preferences file.
|
||||
*/
|
||||
private synchronized void storeColumnVisibility() {
|
||||
if (currentRootNode == null || propertiesMap.isEmpty()) {
|
||||
if (rootNode == null || propertiesMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (currentRootNode instanceof TableFilterNode) {
|
||||
TableFilterNode tfn = (TableFilterNode) currentRootNode;
|
||||
if (rootNode instanceof TableFilterNode) {
|
||||
TableFilterNode tfn = (TableFilterNode) rootNode;
|
||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||
final ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
|
||||
for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
|
||||
@ -445,14 +447,14 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
|
||||
/**
|
||||
* Persists the current column ordering for the child OutlineView of this
|
||||
* tabular results viewer using a preferences file.
|
||||
* tabular result viewer using a preferences file.
|
||||
*/
|
||||
private synchronized void storeColumnOrder() {
|
||||
if (currentRootNode == null || propertiesMap.isEmpty()) {
|
||||
if (rootNode == null || propertiesMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (currentRootNode instanceof TableFilterNode) {
|
||||
TableFilterNode tfn = (TableFilterNode) currentRootNode;
|
||||
if (rootNode instanceof TableFilterNode) {
|
||||
TableFilterNode tfn = (TableFilterNode) rootNode;
|
||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||
// Store the current order of the columns into settings
|
||||
for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
|
||||
@ -465,11 +467,11 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* Persists the current column sorting information using a preferences file.
|
||||
*/
|
||||
private synchronized void storeColumnSorting() {
|
||||
if (currentRootNode == null || propertiesMap.isEmpty()) {
|
||||
if (rootNode == null || propertiesMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (currentRootNode instanceof TableFilterNode) {
|
||||
final TableFilterNode tfn = ((TableFilterNode) currentRootNode);
|
||||
if (rootNode instanceof TableFilterNode) {
|
||||
final TableFilterNode tfn = ((TableFilterNode) rootNode);
|
||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||
ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
|
||||
for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
|
||||
@ -497,11 +499,11 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* it cannot set the sort on columns that have not been added to the table.
|
||||
*/
|
||||
private synchronized void loadColumnSorting() {
|
||||
if (currentRootNode == null || propertiesMap.isEmpty()) {
|
||||
if (rootNode == null || propertiesMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (currentRootNode instanceof TableFilterNode) {
|
||||
final TableFilterNode tfn = (TableFilterNode) currentRootNode;
|
||||
if (rootNode instanceof TableFilterNode) {
|
||||
final TableFilterNode tfn = (TableFilterNode) rootNode;
|
||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||
//organize property sorting information, sorted by rank
|
||||
TreeSet<ColumnSortInfo> sortInfos = new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank));
|
||||
@ -523,12 +525,12 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* preferences file.
|
||||
*/
|
||||
private synchronized void loadColumnVisibility() {
|
||||
if (currentRootNode == null || propertiesMap.isEmpty()) {
|
||||
if (rootNode == null || propertiesMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (currentRootNode instanceof TableFilterNode) {
|
||||
if (rootNode instanceof TableFilterNode) {
|
||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||
final TableFilterNode tfn = ((TableFilterNode) currentRootNode);
|
||||
final TableFilterNode tfn = ((TableFilterNode) rootNode);
|
||||
ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
|
||||
for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
|
||||
final String propName = entry.getValue().getName();
|
||||
@ -549,14 +551,14 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
*/
|
||||
private synchronized List<Node.Property<?>> loadColumnOrder() {
|
||||
|
||||
List<Property<?>> props = ResultViewerPersistence.getAllChildProperties(currentRootNode, 100);
|
||||
List<Property<?>> props = ResultViewerPersistence.getAllChildProperties(rootNode, 100);
|
||||
|
||||
// If node is not table filter node, use default order for columns
|
||||
if (!(currentRootNode instanceof TableFilterNode)) {
|
||||
if (!(rootNode instanceof TableFilterNode)) {
|
||||
return props;
|
||||
}
|
||||
|
||||
final TableFilterNode tfn = ((TableFilterNode) currentRootNode);
|
||||
final TableFilterNode tfn = ((TableFilterNode) rootNode);
|
||||
propertiesMap.clear();
|
||||
|
||||
/*
|
||||
@ -593,16 +595,6 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
return new ArrayList<>(propertiesMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands a given child node of the current root node.
|
||||
*
|
||||
* @param node Node to expand
|
||||
*/
|
||||
@Override
|
||||
public void expandNode(Node node) {
|
||||
outlineView.expandNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the resources that have been allocated by this tabular results
|
||||
* viewer, in preparation for permanently disposing of it.
|
||||
@ -782,8 +774,8 @@ public final class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
|
||||
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
|
||||
// only override the color if a node is not selected
|
||||
if (currentRootNode != null && !isSelected) {
|
||||
Node node = currentRootNode.getChildren().getNodeAt(table.convertRowIndexToModel(row));
|
||||
if (rootNode != null && !isSelected) {
|
||||
Node node = rootNode.getChildren().getNodeAt(table.convertRowIndexToModel(row));
|
||||
boolean tagFound = false;
|
||||
if (node != null) {
|
||||
Node.PropertySet[] propSets = node.getPropertySets();
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2017 Basis Technology Corp.
|
||||
* Copyright 2012-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -60,66 +60,67 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A thumbnail viewer for the results view, with paging support.
|
||||
* A thumbnail result viewer, with paging support, that displays the children of
|
||||
* the given root node using an IconView. The paging is intended to reduce
|
||||
* memory footprint by loading no more than two humdred images at a time.
|
||||
*
|
||||
* The paging is intended to reduce memory footprint by load only up to
|
||||
* (currently) 200 images at a time. This works whether or not the underlying
|
||||
* content nodes are being lazy loaded or not.
|
||||
*
|
||||
* TODO (JIRA-2658): Fix DataResultViewer extension point. When this is done,
|
||||
* restore implementation of DataResultViewerTable as a DataResultViewer service
|
||||
* provider.
|
||||
* Instances of this class should use the explorer manager of an ancestor top
|
||||
* component to connect the lookups of the nodes displayed in the IconView to
|
||||
* the actions global context. The explorer manager can be supplied during
|
||||
* construction, but the typical use case is for the result viewer to find the
|
||||
* ancestor top component's explorer manager at runtime.
|
||||
*/
|
||||
@ServiceProvider(service = DataResultViewer.class)
|
||||
public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(DataResultViewerThumbnail.class.getName());
|
||||
private int curPage;
|
||||
private int totalPages;
|
||||
private int curPageImages;
|
||||
private int thumbSize = ImageUtils.ICON_SIZE_MEDIUM;
|
||||
private final PageUpdater pageUpdater = new PageUpdater();
|
||||
private TableFilterNode tfn;
|
||||
private ThumbnailViewChildren tvc;
|
||||
private TableFilterNode rootNode;
|
||||
private ThumbnailViewChildren rootNodeChildren;
|
||||
private NodeSelectionListener selectionListener;
|
||||
private int currentPage;
|
||||
private int totalPages;
|
||||
private int currentPageImages;
|
||||
private int thumbSize = ImageUtils.ICON_SIZE_MEDIUM;
|
||||
|
||||
/**
|
||||
* Constructs a thumbnail viewer for the results view, with paging support,
|
||||
* that is NOT compatible with node multiple selection actions.
|
||||
* Constructs a thumbnail result viewer, with paging support, that displays
|
||||
* the children of the given root node using an IconView. The viewer should
|
||||
* have an ancestor top component to connect the lookups of the nodes
|
||||
* displayed in the IconView to the actions global context. The explorer
|
||||
* manager will be discovered at runtime.
|
||||
*/
|
||||
public DataResultViewerThumbnail() {
|
||||
super();
|
||||
initialize();
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a thumbnail viewer for the results view, with paging support,
|
||||
* that is compatible with node multiple selection actions.
|
||||
* Constructs a thumbnail result viewer, with paging support, that displays
|
||||
* the children of the given root node using an IconView. The viewer should
|
||||
* have an ancestor top component to connect the lookups of the nodes
|
||||
* displayed in the IconView to the actions global context.
|
||||
*
|
||||
* @param explorerManager The shared ExplorerManager for the result viewers.
|
||||
* @param explorerManager The explorer manager of the ancestor top
|
||||
* component.
|
||||
*/
|
||||
public DataResultViewerThumbnail(ExplorerManager explorerManager) {
|
||||
super(explorerManager);
|
||||
initialize();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"DataResultViewerThumbnail.thumbnailSizeComboBox.small=Small Thumbnails",
|
||||
@NbBundle.Messages({
|
||||
"DataResultViewerThumbnail.thumbnailSizeComboBox.small=Small Thumbnails",
|
||||
"DataResultViewerThumbnail.thumbnailSizeComboBox.medium=Medium Thumbnails",
|
||||
"DataResultViewerThumbnail.thumbnailSizeComboBox.large=Large Thumbnails"
|
||||
})
|
||||
private void initialize() {
|
||||
public DataResultViewerThumbnail(ExplorerManager explorerManager) {
|
||||
super(explorerManager);
|
||||
initComponents();
|
||||
iconView.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
// this.getExplorerManager().addPropertyChangeListener(new ExplorerManagerNodeSelectionListener());
|
||||
thumbnailSizeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(
|
||||
new String[]{Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_small(),
|
||||
Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_medium(),
|
||||
Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_large()}));
|
||||
thumbnailSizeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{
|
||||
Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_small(),
|
||||
Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_medium(),
|
||||
Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_large()}));
|
||||
thumbnailSizeComboBox.setSelectedIndex(1);
|
||||
curPage = -1;
|
||||
currentPage = -1;
|
||||
totalPages = 0;
|
||||
curPageImages = 0;
|
||||
currentPageImages = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -315,7 +316,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
|
||||
private void sortButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sortButtonActionPerformed
|
||||
List<Node.Property<?>> childProperties = ResultViewerPersistence.getAllChildProperties(this.getExplorerManager().getRootContext(), 100);
|
||||
SortChooser sortChooser = new SortChooser(childProperties, ResultViewerPersistence.loadSortCriteria(tfn));
|
||||
SortChooser sortChooser = new SortChooser(childProperties, ResultViewerPersistence.loadSortCriteria(rootNode));
|
||||
DialogDescriptor dialogDescriptor = new DialogDescriptor(sortChooser, sortChooser.getDialogTitle());
|
||||
Dialog createDialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
||||
createDialog.setVisible(true);
|
||||
@ -336,8 +337,8 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
Node.Property<?> prop = childProperties.get(i);
|
||||
String propName = prop.getName();
|
||||
SortCriterion criterion = criteriaMap.get(prop);
|
||||
final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(tfn, propName);
|
||||
final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(tfn, propName);
|
||||
final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(rootNode, propName);
|
||||
final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(rootNode, propName);
|
||||
|
||||
if (criterion != null) {
|
||||
preferences.putBoolean(columnSortOrderKey, criterion.getSortOrder() == SortOrder.ASCENDING);
|
||||
@ -347,7 +348,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
preferences.remove(columnSortRankKey);
|
||||
}
|
||||
}
|
||||
setNode(tfn); //this is just to force a refresh
|
||||
setNode(rootNode); //this is just to force a refresh
|
||||
}
|
||||
}//GEN-LAST:event_sortButtonActionPerformed
|
||||
|
||||
@ -383,26 +384,26 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
if (selectionListener == null) {
|
||||
this.getExplorerManager().addPropertyChangeListener(new NodeSelectionListener()); // RJCTODO: remove listener on cleanup
|
||||
}
|
||||
if (tvc != null) {
|
||||
tvc.cancelLoadingThumbnails();
|
||||
if (rootNodeChildren != null) {
|
||||
rootNodeChildren.cancelLoadingThumbnails();
|
||||
}
|
||||
try {
|
||||
if (givenNode != null) {
|
||||
tfn = (TableFilterNode) givenNode;
|
||||
rootNode = (TableFilterNode) givenNode;
|
||||
/*
|
||||
* Wrap the given node in a ThumbnailViewChildren that will
|
||||
* produce ThumbnailPageNodes with ThumbnailViewNode children
|
||||
* from the child nodes of the given node.
|
||||
*/
|
||||
tvc = new ThumbnailViewChildren(givenNode, thumbSize);
|
||||
final Node root = new AbstractNode(tvc);
|
||||
rootNodeChildren = new ThumbnailViewChildren(givenNode, thumbSize);
|
||||
final Node root = new AbstractNode(rootNodeChildren);
|
||||
|
||||
pageUpdater.setRoot(root);
|
||||
root.addNodeListener(pageUpdater);
|
||||
this.getExplorerManager().setRootContext(root);
|
||||
} else {
|
||||
tfn = null;
|
||||
tvc = null;
|
||||
rootNode = null;
|
||||
rootNodeChildren = null;
|
||||
Node emptyNode = new AbstractNode(Children.LEAF);
|
||||
this.getExplorerManager().setRootContext(emptyNode);
|
||||
iconView.setBackground(Color.BLACK);
|
||||
@ -426,8 +427,8 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
public void resetComponent() {
|
||||
super.resetComponent();
|
||||
this.totalPages = 0;
|
||||
this.curPage = -1;
|
||||
curPageImages = 0;
|
||||
this.currentPage = -1;
|
||||
currentPageImages = 0;
|
||||
updateControls();
|
||||
}
|
||||
|
||||
@ -439,15 +440,15 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
}
|
||||
|
||||
private void nextPage() {
|
||||
if (curPage < totalPages) {
|
||||
curPage++;
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
switchPage();
|
||||
}
|
||||
}
|
||||
|
||||
private void previousPage() {
|
||||
if (curPage > 1) {
|
||||
curPage--;
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
switchPage();
|
||||
}
|
||||
}
|
||||
@ -469,7 +470,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
return;
|
||||
}
|
||||
|
||||
curPage = newPage;
|
||||
currentPage = newPage;
|
||||
switchPage();
|
||||
}
|
||||
|
||||
@ -494,9 +495,9 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
progress.switchToIndeterminate();
|
||||
ExplorerManager explorerManager = DataResultViewerThumbnail.this.getExplorerManager();
|
||||
Node root = explorerManager.getRootContext();
|
||||
Node pageNode = root.getChildren().getNodeAt(curPage - 1);
|
||||
Node pageNode = root.getChildren().getNodeAt(currentPage - 1);
|
||||
explorerManager.setExploredContext(pageNode);
|
||||
curPageImages = pageNode.getChildren().getNodesCount();
|
||||
currentPageImages = pageNode.getChildren().getNodesCount();
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -539,20 +540,19 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
sortLabel.setText(DataResultViewerThumbnail_sortLabel_text());
|
||||
|
||||
} else {
|
||||
pageNumLabel.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DataResultViewerThumbnail.pageNumbers.curOfTotal",
|
||||
Integer.toString(curPage), Integer.toString(totalPages)));
|
||||
final int imagesFrom = (curPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE + 1;
|
||||
final int imagesTo = curPageImages + (curPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE;
|
||||
pageNumLabel.setText(NbBundle.getMessage(this.getClass(), "DataResultViewerThumbnail.pageNumbers.curOfTotal",
|
||||
Integer.toString(currentPage), Integer.toString(totalPages)));
|
||||
final int imagesFrom = (currentPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE + 1;
|
||||
final int imagesTo = currentPageImages + (currentPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE;
|
||||
imagesRangeLabel.setText(imagesFrom + "-" + imagesTo);
|
||||
|
||||
pageNextButton.setEnabled(!(curPage == totalPages));
|
||||
pagePrevButton.setEnabled(!(curPage == 1));
|
||||
pageNextButton.setEnabled(!(currentPage == totalPages));
|
||||
pagePrevButton.setEnabled(!(currentPage == 1));
|
||||
goToPageField.setEnabled(totalPages > 1);
|
||||
sortButton.setEnabled(true);
|
||||
thumbnailSizeComboBox.setEnabled(true);
|
||||
if (tfn != null) {
|
||||
String sortString = ResultViewerPersistence.loadSortCriteria(tfn).stream()
|
||||
if (rootNode != null) {
|
||||
String sortString = ResultViewerPersistence.loadSortCriteria(rootNode).stream()
|
||||
.map(SortCriterion::toString)
|
||||
.collect(Collectors.joining(" "));
|
||||
sortString = StringUtils.defaultIfBlank(sortString, "---");
|
||||
@ -583,30 +583,30 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
totalPages = root.getChildren().getNodesCount();
|
||||
|
||||
if (totalPages == 0) {
|
||||
curPage = -1;
|
||||
currentPage = -1;
|
||||
updateControls();
|
||||
return;
|
||||
}
|
||||
|
||||
if (curPage == -1 || curPage > totalPages) {
|
||||
curPage = 1;
|
||||
if (currentPage == -1 || currentPage > totalPages) {
|
||||
currentPage = 1;
|
||||
}
|
||||
|
||||
//force load the curPage node
|
||||
final Node pageNode = root.getChildren().getNodeAt(curPage - 1);
|
||||
final Node pageNode = root.getChildren().getNodeAt(currentPage - 1);
|
||||
|
||||
//em.setSelectedNodes(new Node[]{pageNode});
|
||||
if (pageNode != null) {
|
||||
pageNode.addNodeListener(new NodeListener() {
|
||||
@Override
|
||||
public void childrenAdded(NodeMemberEvent nme) {
|
||||
curPageImages = pageNode.getChildren().getNodesCount();
|
||||
currentPageImages = pageNode.getChildren().getNodesCount();
|
||||
updateControls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void childrenRemoved(NodeMemberEvent nme) {
|
||||
curPageImages = 0;
|
||||
currentPageImages = 0;
|
||||
updateControls();
|
||||
}
|
||||
|
||||
@ -632,7 +632,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
@Override
|
||||
public void childrenRemoved(NodeMemberEvent nme) {
|
||||
totalPages = 0;
|
||||
curPage = -1;
|
||||
currentPage = -1;
|
||||
updateControls();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user