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;
 
   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;