Merge branch 'bug/r2_11_2/JAL-3904_structureviewermenu' into develop
authorJim Procter <j.procter@dundee.ac.uk>
Mon, 18 Oct 2021 14:27:40 +0000 (15:27 +0100)
committerJim Procter <j.procter@dundee.ac.uk>
Mon, 18 Oct 2021 14:27:40 +0000 (15:27 +0100)
src/jalview/api/structures/JalviewStructureDisplayI.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/PymolViewer.java
src/jalview/gui/StructureViewerBase.java
src/jalview/structures/models/AAStructureBindingModel.java
test/jalview/ext/rbvi/chimera/JalviewChimeraView.java

index d8c8371..d0351a8 100644 (file)
@@ -161,4 +161,10 @@ public interface JalviewStructureDisplayI
    */
   void stopProgressBar(String msg, long handle);
 
+  /**
+   * 
+   * @return true if the actions menu is shown for this viewer
+   */
+  boolean hasViewerActionsMenu();
+
 }
index 66420b0..7169fa2 100644 (file)
@@ -342,6 +342,13 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
               "Response from command ('" + cmd + "') was:\n" + lastReply); 
       }
     }
+    else
+    {
+      if (Cache.log.isDebugEnabled())
+      {
+        Cache.log.debug("Command executed: " + cmd);
+      }
+    }
 
     return reply;
   }
@@ -418,19 +425,29 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     {
       return;
     }
-
+    if (!found)
+    {
+      // not a valid residue label command, so clear
+      cmd.setLength(0);
+    }
     /*
-     * unshow the label for the previous residue
+     * prepend with command
+     * to unshow the label for the previous residue
      */
     if (lastHighlightCommand != null)
     {
-      executeCommand(false,  null,  new StructureCommand("~" + lastHighlightCommand));
+      cmd.insert(0, ";");
+      cmd.insert(0,lastHighlightCommand);
+      cmd.insert(0,"~");
+      
     }
-    if (found)
-    {
-      executeCommand(false,  null,  new StructureCommand(command));
+    if (cmd.length()>0) {
+      executeCommand(true,  null,  new StructureCommand(cmd.toString()));
+    }
+    
+    if (found) {
+      this.lastHighlightCommand = command;
     }
-    this.lastHighlightCommand = command;
   }
 
   /**
index e3c65da..364a3b4 100644 (file)
@@ -73,7 +73,10 @@ public class ChimeraViewFrame extends StructureViewerBase
 
   private int myHeight = 150;
 
-  /**
+  private JMenuItem writeFeatures=null;
+
+  private JMenu fetchAttributes=null;
+/**
    * Initialise menu options.
    */
   @Override
@@ -84,7 +87,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     savemenu.setVisible(false); // not yet implemented
     viewMenu.add(fitToWindow);
 
-    JMenuItem writeFeatures = new JMenuItem(
+    writeFeatures = new JMenuItem(
             MessageManager.getString("label.create_viewer_attributes"));
     writeFeatures.setToolTipText(MessageManager
             .getString("label.create_viewer_attributes_tip"));
@@ -98,7 +101,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     });
     viewerActionMenu.add(writeFeatures);
 
-    final JMenu fetchAttributes = new JMenu(
+    fetchAttributes = new JMenu(
             MessageManager.getString("label.fetch_chimera_attributes"));
     fetchAttributes.setToolTipText(
             MessageManager.getString("label.fetch_chimera_attributes_tip"));
@@ -113,7 +116,15 @@ public class ChimeraViewFrame extends StructureViewerBase
     });
     viewerActionMenu.add(fetchAttributes);
   }
-
+  @Override
+  protected void buildActionMenu()
+  {
+    super.buildActionMenu();
+    // add these back in after menu is refreshed
+    viewerActionMenu.add(writeFeatures);
+    viewerActionMenu.add(fetchAttributes);
+    
+  };
   /**
    * Query the structure viewer for its residue attribute names and add them as
    * items off the attributes menu
index c5a4c9a..8dd2fc0 100644 (file)
@@ -348,7 +348,7 @@ public class PymolViewer extends StructureViewerBase
   {
     return "PyMOL";
   }
-
+  JMenuItem writeFeatures = null;
   @Override
   protected void initMenus()
   {
@@ -357,7 +357,7 @@ public class PymolViewer extends StructureViewerBase
     savemenu.setVisible(false); // not yet implemented
     viewMenu.add(fitToWindow);
 
-    JMenuItem writeFeatures = new JMenuItem(
+    writeFeatures = new JMenuItem(
             MessageManager.getString("label.create_viewer_attributes"));
     writeFeatures.setToolTipText(MessageManager
             .getString("label.create_viewer_attributes_tip"));
@@ -371,6 +371,13 @@ public class PymolViewer extends StructureViewerBase
     });
     viewerActionMenu.add(writeFeatures);
   }
+  
+  @Override
+  protected void buildActionMenu()
+  {
+    super.buildActionMenu();
+    viewerActionMenu.add(writeFeatures);
+  }
 
   protected void sendFeaturesToPymol()
   {
index 021e2f6..4f746cb 100644 (file)
@@ -221,6 +221,10 @@ public abstract class StructureViewerBase extends GStructureViewer
       _alignwith.add(ap);
     }
     ;
+    // TODO: refactor to allow concrete classes to register buttons for adding
+    // here
+    // currently have to override to add buttons back in after they are cleared
+    // in this loop
     for (Component c : viewerActionMenu.getMenuComponents())
     {
       if (c != alignStructs)
@@ -1276,5 +1280,11 @@ public abstract class StructureViewerBase extends GStructureViewer
                       + ex.getMessage());
     }
   }
-
+  @Override
+  public boolean hasViewerActionsMenu()
+  {
+    return viewerActionMenu != null && viewerActionMenu.isEnabled()
+            && viewerActionMenu.getItemCount() > 0
+            && viewerActionMenu.isVisible();
+  }
 }
index 748381f..f1f2d30 100644 (file)
@@ -1075,7 +1075,10 @@ public abstract class AAStructureBindingModel
    * executed.
    * <p>
    * If a reply is wanted, the execution is done synchronously (waits),
-   * otherwise it is done in a separate thread (doesn't wait).
+   * otherwise it is done in a separate thread (doesn't wait). WARNING: if you
+   * are sending commands that need to execute before later calls to
+   * executeCommand (e.g. mouseovers, which clean up after previous ones) then
+   * set getReply true to ensure that commands are not executed out of order.
    * 
    * @param getReply
    * @param msg
index d397a6b..e8b5bea 100644 (file)
@@ -39,8 +39,10 @@ import jalview.api.FeatureRenderer;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
@@ -118,6 +120,7 @@ public class JalviewChimeraView
   @Test(groups = { "External" })
   public void testSingleSeqViewChimera()
   {
+
     String inFile = "examples/1gaq.txt";
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
             DataSourceType.FILE);
@@ -139,7 +142,7 @@ public class JalviewChimeraView
     /*
      * Wait for viewer load thread to complete
      */
-    while (!binding.isFinishedInit())
+    do
     {
       try
       {
@@ -147,11 +150,36 @@ public class JalviewChimeraView
       } catch (InterruptedException e)
       {
       }
-    }
+    } while (!binding.isFinishedInit()  ||  !chimeraViewer.isVisible());
 
     assertTrue(binding.isViewerRunning(), "Failed to start Chimera");
 
     assertEquals(chimeraViewer.getBinding().getPdbCount(), 1);
+    assertTrue(chimeraViewer.hasViewerActionsMenu());
+
+    // now add another sequence and bind to view
+    // 
+    AlignmentI al = af.getViewport().getAlignment();
+    PDBEntry xpdb = al.getSequenceAt(0).getPDBEntry("1GAQ");
+    sq = new Sequence("1GAQ", al.getSequenceAt(0).getSequence(25, 95).toString());
+    al.addSequence(sq);
+    structureViewer.viewStructures(new PDBEntry[] { xpdb }, new SequenceI[] { sq }, af.getCurrentView().getAlignPanel());
+
+    /*
+     * Wait for viewer load thread to complete
+     */
+    do 
+    {
+      try {
+        Thread.sleep(1500);
+      } catch (InterruptedException q) {};
+    } while (!binding.isLoadingFinished());
+    
+    // still just one PDB structure shown
+    assertEquals(chimeraViewer.getBinding().getPdbCount(), 1);
+    // and the viewer action menu should still be visible
+    assertTrue(chimeraViewer.hasViewerActionsMenu());
+
     chimeraViewer.closeViewer(true);
     chimeraViewer = null;
     return;