Merge branch 'develop' into features/JAL-2295setChimeraAttributes
[jalview.git] / src / jalview / gui / ChimeraViewFrame.java
index 72c5054..ae3ff9e 100644 (file)
@@ -59,9 +59,7 @@ import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Random;
-import java.util.Set;
 import java.util.Vector;
 
 import javax.swing.JCheckBoxMenuItem;
@@ -156,8 +154,8 @@ public class ChimeraViewFrame extends StructureViewerBase
                 alignStructs.setToolTipText(MessageManager
                         .formatMessage(
                                 "label.align_structures_using_linked_alignment_views",
-                                new Object[]
-                                { new Integer(_alignwith.size()).toString() }));
+                                new Object[] { new Integer(_alignwith
+                                        .size()).toString() }));
               }
             });
     handler.itemStateChanged(null);
@@ -183,6 +181,31 @@ public class ChimeraViewFrame extends StructureViewerBase
         // TODO Auto-generated method stub
       }
     });
+    JMenuItem writeFeatures = new JMenuItem(
+            MessageManager.getString("label.create_chimera_attributes"));
+    writeFeatures.setToolTipText(MessageManager
+            .getString("label.create_chimera_attributes_tip"));
+    writeFeatures.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        sendFeaturesToChimera();
+      }
+    });
+    viewerActionMenu.add(writeFeatures);
+  }
+
+  /**
+   * Send a command to Chimera to create residue attributes for Jalview features
+   * <p>
+   * The syntax is: setattr r <attName> <attValue> <atomSpec>
+   * <p>
+   * For example: setattr r jv:chain "Ferredoxin-1, Chloroplastic" #0:94.A
+   */
+  protected void sendFeaturesToChimera()
+  {
+    jmb.sendFeaturesToChimera(getAlignmentPanel());
   }
 
   /**
@@ -196,7 +219,7 @@ public class ChimeraViewFrame extends StructureViewerBase
   public ChimeraViewFrame(PDBEntry pdbentry, SequenceI[] seq,
           String[] chains, final AlignmentPanel ap)
   {
-    super();
+    this();
     String pdbId = pdbentry.getId();
 
     /*
@@ -249,6 +272,7 @@ public class ChimeraViewFrame extends StructureViewerBase
           SequenceI[][] seqs)
   {
     createProgressBar();
+    // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs
     String[][] chains = extractChains(seqs);
     jmb = new JalviewChimeraBindingModel(this,
             ap.getStructureSelectionManager(), pdbentrys, seqs, chains,
@@ -270,6 +294,7 @@ public class ChimeraViewFrame extends StructureViewerBase
 
     this.addInternalFrameListener(new InternalFrameAdapter()
     {
+      @Override
       public void internalFrameClosing(InternalFrameEvent internalFrameEvent)
       {
         closeViewer(false);
@@ -298,9 +323,13 @@ public class ChimeraViewFrame extends StructureViewerBase
         String chain = null;
         if (seq.getDatasetSequence() != null)
         {
-          Vector<PDBEntry> pdbrefs = seq.getDatasetSequence().getAllPDBEntries();
+          Vector<PDBEntry> pdbrefs = seq.getDatasetSequence()
+                  .getAllPDBEntries();
           if (pdbrefs != null && pdbrefs.size() > 0)
           {
+            // FIXME: SequenceI.PDBEntry[0] chain mapping used for
+            // ChimeraViewFrame. Is this even used ???
+
             chain = pdbrefs.get(0).getChainCode();
           }
         }
@@ -323,12 +352,11 @@ public class ChimeraViewFrame extends StructureViewerBase
    * @param newViewId
    */
   public ChimeraViewFrame(String chimeraSessionFile,
-          AlignmentPanel alignPanel,
-          PDBEntry[] pdbArray,
+          AlignmentPanel alignPanel, PDBEntry[] pdbArray,
           SequenceI[][] seqsArray, boolean colourByChimera,
           boolean colourBySequence, String newViewId)
   {
-    super();
+    this();
     setViewId(newViewId);
     this.chimeraSessionFile = chimeraSessionFile;
     openNewChimera(alignPanel, pdbArray, seqsArray);
@@ -357,31 +385,22 @@ public class ChimeraViewFrame extends StructureViewerBase
   public ChimeraViewFrame(PDBEntry[] pe, SequenceI[][] seqs,
           AlignmentPanel ap)
   {
-    super();
+    this();
     openNewChimera(ap, pe, seqs);
   }
 
-  public ChimeraViewFrame(Map<PDBEntry, List<SequenceI>> toView,
-          AlignmentPanel alignPanel)
+  /**
+   * Default constructor
+   */
+  public ChimeraViewFrame()
   {
     super();
 
     /*
-     * Convert the map of sequences per pdb entry into the tied arrays expected
-     * by openNewChimera
-     * 
-     * TODO pass the Map down to openNewChimera and its callees instead
+     * closeViewer will decide whether or not to close this frame
+     * depending on whether user chooses to Cancel or not
      */
-    final Set<PDBEntry> pdbEntries = toView.keySet();
-    PDBEntry[] pdbs = pdbEntries.toArray(new PDBEntry[pdbEntries.size()]);
-    SequenceI[][] seqsForPdbs = new SequenceI[pdbEntries.size()][];
-    for (int i = 0; i < pdbs.length; i++)
-    {
-      final List<SequenceI> seqsForPdb = toView.get(pdbs[i]);
-      seqsForPdbs[i] = seqsForPdb.toArray(new SequenceI[seqsForPdb.size()]);
-    }
-
-    openNewChimera(alignPanel, pdbs, seqsForPdbs);
+    setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
   }
 
   /**
@@ -414,14 +433,13 @@ public class ChimeraViewFrame extends StructureViewerBase
   void initChimera()
   {
     jmb.setFinishedInit(false);
-    jalview.gui.Desktop.addInternalFrame(this, jmb.getViewerTitle("Chimera", true),
-            getBounds().width, getBounds().height);
+    jalview.gui.Desktop.addInternalFrame(this,
+            jmb.getViewerTitle("Chimera", true), getBounds().width,
+            getBounds().height);
 
     if (!jmb.launchChimera())
     {
-      JOptionPane
-              .showMessageDialog(
-                      Desktop.desktop,
+      JOptionPane.showMessageDialog(Desktop.desktop,
               MessageManager.getString("label.chimera_failed"),
               MessageManager.getString("label.error_loading_file"),
               JOptionPane.ERROR_MESSAGE);
@@ -461,6 +479,7 @@ public class ChimeraViewFrame extends StructureViewerBase
             MessageManager.getString("label.all"));
     menuItem.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent evt)
       {
         allChainsSelected = true;
@@ -483,6 +502,7 @@ public class ChimeraViewFrame extends StructureViewerBase
       menuItem = new JCheckBoxMenuItem(chainName, true);
       menuItem.addItemListener(new ItemListener()
       {
+        @Override
         public void itemStateChanged(ItemEvent evt)
         {
           if (!allChainsSelected)
@@ -524,6 +544,7 @@ public class ChimeraViewFrame extends StructureViewerBase
    * @param closeChimera
    *          if true, close any linked Chimera process; if false, prompt first
    */
+  @Override
   public void closeViewer(boolean closeChimera)
   {
     if (jmb != null && jmb.isChimeraRunning())
@@ -531,12 +552,20 @@ public class ChimeraViewFrame extends StructureViewerBase
       if (!closeChimera)
       {
         String prompt = MessageManager.formatMessage(
-                "label.confirm_close_chimera", new Object[]
-                { jmb.getViewerTitle("Chimera", false) });
+                "label.confirm_close_chimera",
+                new Object[] { jmb.getViewerTitle("Chimera", false) });
         prompt = JvSwingUtils.wrapTooltip(true, prompt);
         int confirm = JOptionPane.showConfirmDialog(this, prompt,
                 MessageManager.getString("label.close_viewer"),
-                JOptionPane.YES_NO_OPTION);
+                JOptionPane.YES_NO_CANCEL_OPTION);
+        /*
+         * abort closure if user hits escape or Cancel
+         */
+        if (confirm == JOptionPane.CANCEL_OPTION
+                || confirm == JOptionPane.CLOSED_OPTION)
+        {
+          return;
+        }
         closeChimera = confirm == JOptionPane.YES_OPTION;
       }
       jmb.closeViewer(closeChimera);
@@ -548,12 +577,14 @@ public class ChimeraViewFrame extends StructureViewerBase
     // TODO: check for memory leaks where instance isn't finalised because jmb
     // holds a reference to the window
     jmb = null;
+    dispose();
   }
 
   /**
    * Open any newly added PDB structures in Chimera, having first fetched data
    * from PDB (if not already saved).
    */
+  @Override
   public void run()
   {
     _started = true;
@@ -625,9 +656,8 @@ public class ChimeraViewFrame extends StructureViewerBase
 
       JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.pdb_entries_couldnt_be_retrieved",
-                      new Object[]
-                      { errormsgs.toString() }), MessageManager
-              .getString("label.couldnt_load_file"),
+                      new Object[] { errormsgs.toString() }),
+              MessageManager.getString("label.couldnt_load_file"),
               JOptionPane.ERROR_MESSAGE);
     }
 
@@ -653,7 +683,8 @@ public class ChimeraViewFrame extends StructureViewerBase
           {
             int pos = filePDBpos.get(num).intValue();
             long startTime = startProgressBar("Chimera "
-                    + MessageManager.getString("status.opening_file"));
+                    + MessageManager.getString("status.opening_file_for")
+                    + " " + pe.getId());
             jmb.openFile(pe);
             jmb.addSequence(pos, jmb.getSequence()[pos]);
             File fl = new File(pe.getFile());
@@ -672,9 +703,7 @@ public class ChimeraViewFrame extends StructureViewerBase
             }
             // Explicitly map to the filename used by Chimera ;
             jmb.getSsm().setMapping(jmb.getSequence()[pos],
-                    jmb.getChains()[pos],
-                    pe.getFile(),
-                    protocol);
+                    jmb.getChains()[pos], pe.getFile(), protocol);
           } catch (OutOfMemoryError oomerror)
           {
             new OOMWarning(
@@ -699,10 +728,11 @@ public class ChimeraViewFrame extends StructureViewerBase
         jmb.updateColours(ap);
       }
       // do superposition if asked to
-      if (alignAddedStructures)
+      if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
       {
         new Thread(new Runnable()
         {
+          @Override
           public void run()
           {
             alignStructs_withAllAlignPanels();
@@ -726,6 +756,7 @@ public class ChimeraViewFrame extends StructureViewerBase
    */
   private String fetchPdbFile(PDBEntry processingEntry) throws Exception
   {
+    // FIXME: this is duplicated code with Jmol frame ?
     String filePath = null;
     Pdb pdbclient = new Pdb();
     AlignmentI pdbseq = null;
@@ -737,8 +768,7 @@ public class ChimeraViewFrame extends StructureViewerBase
      * Write 'fetching PDB' progress on AlignFrame as we are not yet visible
      */
     String msg = MessageManager.formatMessage("status.fetching_pdb",
-            new Object[]
-            { pdbid });
+            new Object[] { pdbid });
     getAlignmentPanel().alignFrame.setProgressBar(msg, handle);
     // long hdl = startProgressBar(MessageManager.formatMessage(
     // "status.fetching_pdb", new Object[]
@@ -751,8 +781,7 @@ public class ChimeraViewFrame extends StructureViewerBase
       new OOMWarning("Retrieving PDB id " + pdbid, oomerror);
     } finally
     {
-      msg = pdbid + " "
-              + MessageManager.getString("label.state_completed");
+      msg = pdbid + " " + MessageManager.getString("label.state_completed");
       getAlignmentPanel().alignFrame.setProgressBar(msg, handle);
       // stopProgressBar(msg, hdl);
     }
@@ -1036,10 +1065,10 @@ public class ChimeraViewFrame extends StructureViewerBase
     setChainMenuItems(jmb.getChainNames());
 
     this.setTitle(jmb.getViewerTitle("Chimera", true));
-    if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
-    {
+    // if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
+    // {
       viewerActionMenu.setVisible(true);
-    }
+    // }
     if (!jmb.isLoadingFromArchive())
     {
       seqColour_actionPerformed(null);
@@ -1097,6 +1126,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     }
   }
 
+  @Override
   public void setJalviewColourScheme(ColourSchemeI ucs)
   {
     jmb.setJalviewColourScheme(ucs);