19 package org.sleuthkit.autopsy.communications.relationships;
21 import java.awt.Component;
22 import java.awt.KeyboardFocusManager;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 import javax.swing.JPanel;
26 import static javax.swing.SwingUtilities.isDescendingFrom;
27 import javax.swing.table.TableColumn;
28 import org.netbeans.swing.outline.DefaultOutlineModel;
29 import org.netbeans.swing.outline.Outline;
30 import org.openide.explorer.ExplorerManager;
31 import static org.openide.explorer.ExplorerUtils.createLookup;
32 import org.openide.nodes.AbstractNode;
33 import org.openide.nodes.Children;
34 import org.openide.nodes.Node;
35 import org.openide.nodes.NodeAdapter;
36 import org.openide.nodes.NodeMemberEvent;
37 import org.openide.util.Lookup;
38 import org.openide.util.NbBundle.Messages;
42 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER;
43 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START;
44 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
50 final class CallLogViewer
extends javax.swing.JPanel implements RelationshipsViewer {
52 private static final long serialVersionUID = 1L;
54 private final CallLogsChildNodeFactory nodeFactory;
56 private final CallLogDataViewer callLogDataViewer;
57 private final ModifiableProxyLookup proxyLookup;
58 private PropertyChangeListener focusPropertyListener;
61 "CallLogViewer_title=Call Logs",
62 "CallLogViewer_noCallLogs=<No call logs found for selected account>",
63 "CallLogViewer_recipient_label=To/From",
64 "CallLogViewer_duration_label=Duration(seconds)",
65 "CallLogViewer_device_label=Device"
74 callLogDataViewer =
new CallLogDataViewer();
76 bottomScrollPane.setViewportView(callLogDataViewer);
78 splitPane.setResizeWeight(0.5);
79 splitPane.setDividerLocation(0.5);
81 nodeFactory =
new CallLogsChildNodeFactory(null);
82 proxyLookup =
new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
84 outlineViewPanel.hideOutlineView(Bundle.CallLogViewer_noCallLogs());
88 outlineViewPanel.getOutlineView().setPropertyColumns(
89 TSK_DIRECTION.getLabel(), TSK_DIRECTION.getDisplayName(),
90 TSK_PHONE_NUMBER.getLabel(), Bundle.CallLogViewer_recipient_label(),
91 TSK_DATETIME_START.getLabel(), TSK_DATETIME_START.getDisplayName(),
92 CallLogNode.DURATION_PROP, Bundle.CallLogViewer_duration_label()
95 Outline outline = outlineViewPanel.getOutlineView().getOutline();
96 outline.setRootVisible(
false);
97 ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CallLogViewer_device_label());
99 outlineViewPanel.getExplorerManager().addPropertyChangeListener((PropertyChangeEvent evt) -> {
100 if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
101 final Node[] nodes = outlineViewPanel.getExplorerManager().getSelectedNodes();
102 callLogDataViewer.setNode(nodes != null && nodes.length > 0 ? nodes[0] : null);
106 outlineViewPanel.getExplorerManager().setRootContext(
108 new DataResultFilterNode(
109 new AbstractNode(Children.create(nodeFactory,
true)), outlineViewPanel.getExplorerManager()),
true));
111 outlineViewPanel.getExplorerManager().getRootContext().addNodeListener(
new NodeAdapter() {
113 public void childrenAdded(NodeMemberEvent nme) {
114 updateOutlineViewPanel();
118 public void childrenRemoved(NodeMemberEvent nme) {
119 updateOutlineViewPanel();
123 TableColumn column = outline.getColumnModel().getColumn(2);
124 column.setCellRenderer(
new NodeTableCellRenderer());
133 @SuppressWarnings(
"unchecked")
135 private
void initComponents() {
136 java.awt.GridBagConstraints gridBagConstraints;
138 splitPane =
new javax.swing.JSplitPane();
140 bottomScrollPane =
new javax.swing.JScrollPane();
142 setLayout(
new java.awt.GridBagLayout());
144 splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
145 splitPane.setLeftComponent(outlineViewPanel);
146 splitPane.setRightComponent(bottomScrollPane);
148 gridBagConstraints =
new java.awt.GridBagConstraints();
149 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
150 gridBagConstraints.weightx = 1.0;
151 gridBagConstraints.weighty = 1.0;
152 add(splitPane, gridBagConstraints);
156 public String getDisplayName() {
157 return Bundle.CallLogViewer_title();
161 public JPanel getPanel() {
166 public void setSelectionInfo(SelectionInfo info) {
167 callLogDataViewer.setNode(null);
168 nodeFactory.refresh(info);
173 public Lookup getLookup() {
174 return outlineViewPanel.getLookup();
178 public void addNotify() {
181 if (focusPropertyListener == null) {
184 focusPropertyListener = (
final PropertyChangeEvent focusEvent) -> {
185 if (focusEvent.getPropertyName().equalsIgnoreCase(
"focusOwner")) {
186 handleFocusChange((Component) focusEvent.getNewValue());
193 KeyboardFocusManager.getCurrentKeyboardFocusManager()
194 .addPropertyChangeListener(
"focusOwner", focusPropertyListener);
202 private void handleFocusChange(Component newFocusOwner) {
203 if (newFocusOwner == null) {
206 if (isDescendingFrom(newFocusOwner, callLogDataViewer)) {
208 proxyLookup.setNewLookups(createLookup(callLogDataViewer.getExplorerManager(), getActionMap()));
209 }
else if (isDescendingFrom(newFocusOwner,
this)) {
211 proxyLookup.setNewLookups(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
217 public void removeNotify() {
218 super.removeNotify();
219 if (focusPropertyListener != null) {
220 KeyboardFocusManager.getCurrentKeyboardFocusManager()
221 .removePropertyChangeListener(
"focusOwner", focusPropertyListener);
225 private void updateOutlineViewPanel() {
226 int nodeCount = outlineViewPanel.getExplorerManager().getRootContext().getChildren().getNodesCount();
227 if (nodeCount == 0) {
228 outlineViewPanel.hideOutlineView(Bundle.CallLogViewer_noCallLogs());
230 outlineViewPanel.showOutlineView();
236 private javax.swing.JScrollPane bottomScrollPane;
238 private javax.swing.JSplitPane splitPane;