Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / gui / StructureViewerBase.java
index ed42ffa..bd757e8 100644 (file)
@@ -35,6 +35,7 @@ import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.Vector;
 
@@ -89,8 +90,9 @@ public abstract class StructureViewerBase extends GStructureViewer
   }
 
   /**
-   * Singleton list of all (open) instances of structureViewerBase
-   * TODO: JAL-3362 - review and adopt the swingJS-safe singleton pattern so each structure viewer base instance is kept to its own JalviewJS parent
+   * Singleton list of all (open) instances of structureViewerBase TODO:
+   * JAL-3362 - review and adopt the swingJS-safe singleton pattern so each
+   * structure viewer base instance is kept to its own JalviewJS parent
    */
   private static List<JalviewStructureDisplayI> svbs = new ArrayList<>();
 
@@ -141,6 +143,8 @@ public abstract class StructureViewerBase extends GStructureViewer
 
   protected boolean allChainsSelected = false;
 
+  protected boolean allHetatmBeingSelected = false;
+
   protected JMenu viewSelectionMenu;
 
   /**
@@ -605,6 +609,88 @@ public abstract class StructureViewerBase extends GStructureViewer
     }
   }
 
+  void setHetatmMenuItems(Map<String, String> hetatmNames)
+  {
+    hetatmMenu.removeAll();
+    if (hetatmNames == null || hetatmNames.isEmpty())
+    {
+      hetatmMenu.setVisible(false);
+      return;
+    }
+    hetatmMenu.setVisible(true);
+    allHetatmBeingSelected = false;
+    JMenuItem allMenuItem = new JMenuItem(
+            MessageManager.getString("label.all"));
+    JMenuItem noneMenuItem = new JMenuItem(
+            MessageManager.getString("label.none"));
+    allMenuItem.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        {
+          allHetatmBeingSelected = true;
+          // Toggle state of everything - on
+          for (int i = 0; i < hetatmMenu.getItemCount(); i++)
+          {
+            if (hetatmMenu.getItem(i) instanceof JCheckBoxMenuItem)
+            {
+              ((JCheckBoxMenuItem) hetatmMenu.getItem(i)).setSelected(true);
+            }
+          }
+          allHetatmBeingSelected = false;
+          showSelectedHetatms();
+        }
+      }
+    });
+
+    noneMenuItem.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        {
+          allHetatmBeingSelected = true;
+          // Toggle state of everything off
+          for (int i = 0; i < hetatmMenu.getItemCount(); i++)
+          {
+            if (hetatmMenu.getItem(i) instanceof JCheckBoxMenuItem)
+            {
+              ((JCheckBoxMenuItem) hetatmMenu.getItem(i))
+                      .setSelected(false);
+            }
+          }
+          allHetatmBeingSelected = false;
+          showSelectedHetatms();
+        }
+      }
+    });
+    hetatmMenu.add(noneMenuItem);
+    hetatmMenu.add(allMenuItem);
+
+    for (Map.Entry<String, String> chain : hetatmNames.entrySet())
+    {
+      JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(chain.getKey(),
+              false);
+      menuItem.setToolTipText(chain.getValue());
+      menuItem.addItemListener(new ItemListener()
+      {
+        @Override
+        public void itemStateChanged(ItemEvent evt)
+        {
+          if (!allHetatmBeingSelected)
+          {
+            // update viewer only when we were clicked, not programmatically
+            // checked/unchecked
+            showSelectedHetatms();
+          }
+        }
+      });
+
+      hetatmMenu.add(menuItem);
+    }
+  }
+
   /**
    * Action on selecting one of Jalview's registered colour schemes
    */
@@ -1009,6 +1095,7 @@ public abstract class StructureViewerBase extends GStructureViewer
       return;
     }
     setChainMenuItems(binding.getChainNames());
+    setHetatmMenuItems(binding.getHetatmNames());
 
     this.setTitle(binding.getViewerTitle(getViewerName(), true));
 
@@ -1160,6 +1247,26 @@ public abstract class StructureViewerBase extends GStructureViewer
   }
 
   /**
+   * Display selected hetatms in viewer
+   */
+  protected void showSelectedHetatms()
+  {
+    List<String> toshow = new ArrayList<>();
+    for (int i = 0; i < hetatmMenu.getItemCount(); i++)
+    {
+      if (hetatmMenu.getItem(i) instanceof JCheckBoxMenuItem)
+      {
+        JCheckBoxMenuItem item = (JCheckBoxMenuItem) hetatmMenu.getItem(i);
+        if (item.isSelected())
+        {
+          toshow.add(item.getText());
+        }
+      }
+    }
+    getBinding().showHetatms(toshow);
+  }
+
+  /**
    * Tries to fetch a PDB file and save to a temporary local file. Returns the
    * saved file path if successful, or null if not.
    * 
@@ -1362,12 +1469,15 @@ public abstract class StructureViewerBase extends GStructureViewer
     // TODO: check for memory leaks where instance isn't finalised because jmb
     // holds a reference to the window
     // jmb = null;
-    
-    try {
+
+    try
+    {
       svbs.remove(this);
     } catch (Throwable t)
     {
-      Console.info("Unexpected exception when deregistering structure viewer",t);
+      Console.info(
+              "Unexpected exception when deregistering structure viewer",
+              t);
     }
     dispose();
   }