JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / src / jalview / gui / StructureViewer.java
index b3b1962..189d490 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -24,10 +24,12 @@ import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
-import jalview.datamodel.ViewerData;
+import jalview.datamodel.StructureViewerModel;
 import jalview.structure.StructureSelectionManager;
 
 import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * proxy for handling structure viewers.
@@ -64,23 +66,86 @@ public class StructureViewer
     ssm = structureSelectionManager;
   }
 
-  public JalviewStructureDisplayI viewStructures(AlignmentPanel ap,
-          PDBEntry[] pr, SequenceI[][] collateForPDB)
+  /**
+   * View multiple PDB entries, each with associated sequences
+   * 
+   * @param pdbs
+   * @param seqsForPdbs
+   * @param ap
+   * @return
+   */
+  public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs,
+          SequenceI[][] seqsForPdbs, AlignmentPanel ap)
+  {
+    JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqsForPdbs, ap);
+    if (viewer != null)
+    {
+      return viewer;
+    }
+    return viewStructures(getViewerType(), pdbs, seqsForPdbs, ap);
+  }
+
+  /**
+   * A strictly temporary method pending JAL-1761 refactoring. Determines if all
+   * the passed PDB entries are the same (this is the case if selected sequences
+   * to view structure for are chains of the same structure). If so, calls the
+   * single-pdb version of viewStructures and returns the viewer, else returns
+   * null.
+   * 
+   * @param pdbs
+   * @param seqsForPdbs
+   * @param ap
+   * @return
+   */
+  private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs,
+          SequenceI[][] seqsForPdbs, AlignmentPanel ap)
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    if (pdbs == null || pdbs.length == 0)
+    {
+      return null;
+    }
+    int i = 0;
+    String firstFile = pdbs[0].getFile();
+    for (PDBEntry pdb : pdbs)
+    {
+      String pdbFile = pdb.getFile();
+      if (pdbFile == null || !pdbFile.equals(firstFile))
+      {
+        return null;
+      }
+      SequenceI[] pdbseqs = seqsForPdbs[i++];
+      if (pdbseqs != null)
+      {
+        for (SequenceI sq : pdbseqs)
+        {
+          seqs.add(sq);
+        }
+      }
+    }
+    return viewStructures(pdbs[0],
+            seqs.toArray(new SequenceI[seqs.size()]), ap);
+  }
+
+  public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
+          SequenceI[] seqsForPdb, AlignmentPanel ap)
   {
-    return viewStructures(getViewerType(), ap, pr, collateForPDB);
+    return viewStructures(getViewerType(), pdb, seqsForPdb, ap);
   }
 
-  public JalviewStructureDisplayI viewStructures(ViewerType viewerType,
-          AlignmentPanel ap, PDBEntry[] pr, SequenceI[][] collateForPDB)
+  protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
+          PDBEntry[] pdbs, SequenceI[][] seqsForPdbs, AlignmentPanel ap)
   {
+    PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs);
     JalviewStructureDisplayI sview = null;
     if (viewerType.equals(ViewerType.JMOL))
     {
-      sview = new AppJmol(ap, pr, ap.av.collateForPDB(pr));
+      sview = new AppJmol(ap, pdbsForFile, ap.av.collateForPDB(pdbsForFile));
     }
     else if (viewerType.equals(ViewerType.CHIMERA))
     {
-      sview = new ChimeraViewFrame(ap, pr, ap.av.collateForPDB(pr));
+      sview = new ChimeraViewFrame(pdbsForFile,
+              ap.av.collateForPDB(pdbsForFile), ap);
     }
     else
     {
@@ -90,17 +155,47 @@ public class StructureViewer
     return sview;
   }
 
-  public JalviewStructureDisplayI viewStructures(ViewerType viewerType,
-          AlignmentPanel ap, PDBEntry pr, SequenceI[] collateForPDB)
+  /**
+   * Convert the array of PDBEntry into an array with no filename repeated
+   * 
+   * @param pdbs
+   * @return
+   */
+  static PDBEntry[] getUniquePdbFiles(PDBEntry[] pdbs)
+  {
+    if (pdbs == null)
+    {
+      return null;
+    }
+    List<PDBEntry> uniques = new ArrayList<PDBEntry>();
+    List<String> filesSeen = new ArrayList<String>();
+    for (PDBEntry entry : pdbs)
+    {
+      String file = entry.getFile();
+      if (file == null)
+      {
+        uniques.add(entry);
+      }
+      else if (!filesSeen.contains(file))
+      {
+        uniques.add(entry);
+        filesSeen.add(file);
+      }
+    }
+    return uniques.toArray(new PDBEntry[uniques.size()]);
+  }
+
+  protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
+          PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap)
   {
     JalviewStructureDisplayI sview = null;
     if (viewerType.equals(ViewerType.JMOL))
     {
-      sview = new AppJmol(pr, collateForPDB, null, ap);
+      sview = new AppJmol(pdb, seqsForPdb, null, ap);
     }
     else if (viewerType.equals(ViewerType.CHIMERA))
     {
-      sview = new ChimeraViewFrame(pr, collateForPDB, null, ap);
+      sview = new ChimeraViewFrame(pdb, seqsForPdb, null, ap);
     }
     else
     {
@@ -110,12 +205,6 @@ public class StructureViewer
     return sview;
   }
 
-  public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
-          SequenceI[] sequenceIs, Object object, AlignmentPanel ap)
-  {
-    return viewStructures(getViewerType(), ap, pdb, sequenceIs);
-  }
-
   /**
    * Create a new panel controlling a structure viewer.
    * 
@@ -132,8 +221,8 @@ public class StructureViewer
    */
   public JalviewStructureDisplayI createView(ViewerType type,
           String[] pdbf, String[] id, SequenceI[][] sq,
-          AlignmentPanel alignPanel, ViewerData viewerData, String fileloc,
-          Rectangle rect, String vid)
+          AlignmentPanel alignPanel, StructureViewerModel viewerData,
+          String fileloc, Rectangle rect, String vid)
   {
     final boolean useinViewerSuperpos = viewerData.isAlignWithPanel();
     final boolean usetoColourbyseq = viewerData.isColourWithAlignPanel();