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 org.netbeans.swing.outline.DefaultOutlineModel;
 
   28 import org.netbeans.swing.outline.Outline;
 
   29 import org.openide.explorer.ExplorerManager;
 
   30 import static org.openide.explorer.ExplorerUtils.createLookup;
 
   31 import org.openide.nodes.AbstractNode;
 
   32 import org.openide.nodes.Children;
 
   33 import org.openide.nodes.Node;
 
   34 import org.openide.nodes.NodeAdapter;
 
   35 import org.openide.nodes.NodeMemberEvent;
 
   36 import org.openide.util.Lookup;
 
   37 import org.openide.util.NbBundle.Messages;
 
   41 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER;
 
   42 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START;
 
   43 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
 
   49 final class CallLogViewer 
extends javax.swing.JPanel implements RelationshipsViewer {
 
   51     private static final long serialVersionUID = 1L;
 
   53     private final CallLogsChildNodeFactory nodeFactory;
 
   55     private final CallLogDataViewer callLogDataViewer;
 
   56     private final ModifiableProxyLookup proxyLookup;
 
   57     private PropertyChangeListener focusPropertyListener;
 
   60         "CallLogViewer_title=Call Logs",
 
   61         "CallLogViewer_noCallLogs=<No call logs found for selected account>",
 
   62         "CallLogViewer_recipient_label=To/From",
 
   63         "CallLogViewer_duration_label=Duration(seconds)",
 
   64         "CallLogViewer_device_label=Device" 
   73         callLogDataViewer = 
new CallLogDataViewer();
 
   75         bottomScrollPane.setViewportView(callLogDataViewer);
 
   77         splitPane.setResizeWeight(0.5);
 
   78         splitPane.setDividerLocation(0.5);
 
   80         nodeFactory = 
new CallLogsChildNodeFactory(null);
 
   81         proxyLookup = 
new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
 
   83         outlineViewPanel.hideOutlineView(Bundle.CallLogViewer_noCallLogs());
 
   85         outlineViewPanel.getOutlineView().setPropertyColumns(
 
   86                 TSK_DIRECTION.getLabel(), TSK_DIRECTION.getDisplayName(),
 
   87                 TSK_PHONE_NUMBER.getLabel(), Bundle.CallLogViewer_recipient_label(),
 
   88                 TSK_DATETIME_START.getLabel(), TSK_DATETIME_START.getDisplayName(),
 
   89                 CallLogNode.DURATION_PROP, Bundle.CallLogViewer_duration_label()
 
   92         Outline outline = outlineViewPanel.getOutlineView().getOutline();
 
   93         outline.setRootVisible(
false);
 
   94         ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CallLogViewer_device_label());
 
   96         outlineViewPanel.getExplorerManager().addPropertyChangeListener((PropertyChangeEvent evt) -> {
 
   97             if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
 
   98                 final Node[] nodes = outlineViewPanel.getExplorerManager().getSelectedNodes();
 
   99                 callLogDataViewer.setNode(nodes != null && nodes.length > 0 ? nodes[0] : null);
 
  103         outlineViewPanel.getExplorerManager().setRootContext(
 
  105                         new DataResultFilterNode(
 
  106                                 new AbstractNode(Children.create(nodeFactory, 
true)), outlineViewPanel.getExplorerManager()), 
true));
 
  108         outlineViewPanel.getExplorerManager().getRootContext().addNodeListener(
new NodeAdapter() {
 
  110             public void childrenAdded(NodeMemberEvent nme) {
 
  111                 updateOutlineViewPanel();
 
  115             public void childrenRemoved(NodeMemberEvent nme) {
 
  116                 updateOutlineViewPanel();
 
  127     @SuppressWarnings(
"unchecked")
 
  129     private 
void initComponents() {
 
  130         java.awt.GridBagConstraints gridBagConstraints;
 
  132         splitPane = 
new javax.swing.JSplitPane();
 
  134         bottomScrollPane = 
new javax.swing.JScrollPane();
 
  136         setLayout(
new java.awt.GridBagLayout());
 
  138         splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
 
  139         splitPane.setLeftComponent(outlineViewPanel);
 
  140         splitPane.setRightComponent(bottomScrollPane);
 
  142         gridBagConstraints = 
new java.awt.GridBagConstraints();
 
  143         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
 
  144         gridBagConstraints.weightx = 1.0;
 
  145         gridBagConstraints.weighty = 1.0;
 
  146         add(splitPane, gridBagConstraints);
 
  150     public String getDisplayName() {
 
  151         return Bundle.CallLogViewer_title();
 
  155     public JPanel getPanel() {
 
  160     public void setSelectionInfo(SelectionInfo info) {
 
  161         nodeFactory.refresh(info);
 
  165     public Lookup getLookup() {
 
  166         return outlineViewPanel.getLookup();
 
  170     public void addNotify() {
 
  173         if (focusPropertyListener == null) {
 
  176             focusPropertyListener = (
final PropertyChangeEvent focusEvent) -> {
 
  177                 if (focusEvent.getPropertyName().equalsIgnoreCase(
"focusOwner")) {
 
  178                     handleFocusChange((Component) focusEvent.getNewValue());
 
  185         KeyboardFocusManager.getCurrentKeyboardFocusManager()
 
  186                 .addPropertyChangeListener(
"focusOwner", focusPropertyListener); 
 
  194     private void handleFocusChange(Component newFocusOwner) {
 
  195         if (newFocusOwner == null) {
 
  198         if (isDescendingFrom(newFocusOwner, callLogDataViewer)) {
 
  200             proxyLookup.setNewLookups(createLookup(callLogDataViewer.getExplorerManager(), getActionMap()));
 
  201         } 
else if (isDescendingFrom(newFocusOwner, 
this)) {
 
  203             proxyLookup.setNewLookups(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
 
  209     public void removeNotify() {
 
  210         super.removeNotify();
 
  211         if (focusPropertyListener != null) {
 
  212             KeyboardFocusManager.getCurrentKeyboardFocusManager()
 
  213                     .removePropertyChangeListener(
"focusOwner", focusPropertyListener); 
 
  217     private void updateOutlineViewPanel() {
 
  218         int nodeCount = outlineViewPanel.getExplorerManager().getRootContext().getChildren().getNodesCount();
 
  219         if (nodeCount == 0) {
 
  220             outlineViewPanel.hideOutlineView(Bundle.ContactsViewer_noContacts_message());
 
  222             outlineViewPanel.showOutlineView();
 
  228     private javax.swing.JScrollPane bottomScrollPane;
 
  230     private javax.swing.JSplitPane splitPane;