JAL-1847 superpose checkbox in structure chooser
[jalview.git] / src / jalview / gui / StructureChooser.java
index 6e73724..1b69989 100644 (file)
@@ -21,6 +21,8 @@
 
 package jalview.gui;
 
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
@@ -54,6 +56,7 @@ import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
 import javax.swing.JTable;
+import javax.swing.SwingUtilities;
 import javax.swing.table.AbstractTableModel;
 
 /**
@@ -106,6 +109,8 @@ public class StructureChooser extends GStructureChooser
       progressBar = new ProgressBar(this.statusPanel, this.statusBar);
     }
 
+    chk_superpose.setSelected(Cache.getDefault("AUTOSUPERIMPOSE", true));
+
     // ensure a filter option is in force for search
     populateFilterComboBox(true, cachedPDBExists);
     Thread discoverPDBStructuresThread = new Thread(new Runnable()
@@ -123,6 +128,7 @@ public class StructureChooser extends GStructureChooser
         fetchStructuresMetaData();
         // revise filter options if no results were found
         populateFilterComboBox(isStructuresDiscovered(), cachedPDBExists);
+        discoverStructureViews();
         updateProgressIndicator(null, startTime);
         mainFrame.setVisible(true);
         updateCurrentView();
@@ -131,6 +137,47 @@ public class StructureChooser extends GStructureChooser
     discoverPDBStructuresThread.start();
   }
 
+  private void discoverStructureViews()
+  {
+    if (Desktop.instance != null)
+    {
+      targetView.removeAllItems();
+      targetView.addItem(
+              new StructureViewer(ap.getStructureSelectionManager()));
+      if (lastTargetedView != null && !lastTargetedView.isVisible())
+      {
+        lastTargetedView = null;
+      }
+      int linkedViewsAt = 1;
+      for (StructureViewerBase view : Desktop.instance
+              .getStructureViewers(null, null))
+      {
+        StructureViewer viewHandler = (lastTargetedView != null
+                && lastTargetedView.sview == view) ? lastTargetedView
+                        : StructureViewer.reconfigure(view);
+
+        if (view.isLinkedWith(ap))
+        {
+          targetView.insertItemAt(viewHandler,
+                  linkedViewsAt++);
+        }
+        else
+        {
+          targetView.addItem(viewHandler);
+        }
+      }
+      targetView.setVisible(targetView.getItemCount() > 1);
+
+      // finally, restore last targeted view by default.
+      if (lastTargetedView != null)
+      {
+        targetView.setSelectedItem(lastTargetedView);
+      }
+    }
+  }
+
+  private static StructureViewer lastTargetedView = null;
+
   /**
    * Updates the progress indicator with the specified message
    * 
@@ -728,31 +775,43 @@ public class StructureChooser extends GStructureChooser
 
   }
 
-  public void selectStructure(String...pdbids)
+  /**
+   * select structures for viewing by their PDB IDs
+   * 
+   * @param pdbids
+   * @return true if structures were found and marked as selected
+   */
+  public boolean selectStructure(String... pdbids)
   {
+    boolean found = false;
+
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
             .getSelectedItem());
     String currentView = selectedFilterOpt.getView();
     JTable restable = (currentView == VIEWS_FILTER) ? getResultTable()
-            : tbl_local_pdb;
+            : (currentView == VIEWS_LOCAL_PDB) ? tbl_local_pdb : null;
 
-    if (currentView == VIEWS_FILTER)
+    if (restable == null)
     {
-     
-      int pdbIdColIndex = restable.getColumn("PDB Id")
-              .getModelIndex();
-      for (int r = 0; r < restable.getRowCount(); r++)
+      // can't select (enter PDB ID, or load file - need to also select which
+      // sequence to associate with)
+      return false;
+    }
+
+    int pdbIdColIndex = restable.getColumn("PDB Id").getModelIndex();
+    for (int r = 0; r < restable.getRowCount(); r++)
+    {
+      for (int p = 0; p < pdbids.length; p++)
       {
-        for (int p=0;p<pdbids.length;p++)
-        {
-          if (String.valueOf(restable.getValueAt(r, pdbIdColIndex))
-                  .equalsIgnoreCase(pdbids[p]))
+        if (String.valueOf(restable.getValueAt(r, pdbIdColIndex))
+                .equalsIgnoreCase(pdbids[p]))
         {
-            restable.setRowSelectionInterval(r, r);
-        }
+          restable.setRowSelectionInterval(r, r);
+          found = true;
         }
       }
     }
+    return found;
   }
   /**
    * Handles action event for btn_ok
@@ -760,11 +819,22 @@ public class StructureChooser extends GStructureChooser
   @Override
   public void ok_ActionPerformed()
   {
+    showStructures(false);
+  }
+
+  /**
+   * structure viewer opened by this dialog, or null
+   */
+  private StructureViewer sViewer = null;
+
+  public void showStructures(boolean waitUntilFinished)
+  {
+
     final StructureSelectionManager ssm = ap.getStructureSelectionManager();
 
     final int preferredHeight = pnl_filter.getHeight();
 
-    new Thread(new Runnable()
+    Runnable viewStruc = new Runnable()
     {
       @Override
       public void run()
@@ -810,7 +880,8 @@ public class StructureChooser extends GStructureChooser
           }
           SequenceI[] selectedSeqs = selectedSeqsToView
                   .toArray(new SequenceI[selectedSeqsToView.size()]);
-          launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
+          sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
+                  selectedSeqs);
         }
         else if (currentView == VIEWS_LOCAL_PDB)
         {
@@ -833,7 +904,8 @@ public class StructureChooser extends GStructureChooser
           }
           SequenceI[] selectedSeqs = selectedSeqsToView
                   .toArray(new SequenceI[selectedSeqsToView.size()]);
-          launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
+          sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
+                  selectedSeqs);
         }
         else if (currentView == VIEWS_ENTER_ID)
         {
@@ -862,7 +934,7 @@ public class StructureChooser extends GStructureChooser
           }
 
           PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
-          launchStructureViewer(ssm, pdbEntriesToView, ap,
+          sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
                   new SequenceI[]
                   { selectedSequence });
         }
@@ -879,14 +951,40 @@ public class StructureChooser extends GStructureChooser
                           DataSourceType.FILE, selectedSequence, true,
                           Desktop.instance);
 
-          launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
+          sViewer = launchStructureViewer(
+                  ssm, new PDBEntry[]
+                  { fileEntry }, ap,
                   new SequenceI[]
                   { selectedSequence });
         }
-        closeAction(preferredHeight);
-        mainFrame.dispose();
+        SwingUtilities.invokeLater(new Runnable()
+        {
+          @Override
+          public void run()
+          {
+            closeAction(preferredHeight);
+            mainFrame.dispose();
+          }
+        });
+      }
+    };
+    Thread runner = new Thread(viewStruc);
+    runner.start();
+    if (waitUntilFinished)
+    {
+      while (sViewer == null ? runner.isAlive()
+              : (sViewer.sview == null ? true
+                      : !sViewer.sview.hasMapping()))
+      {
+        try
+        {
+          Thread.sleep(300);
+        } catch (InterruptedException ie)
+        {
+
+        }
       }
-    }).start();
+    }
   }
 
   private PDBEntry getFindEntry(String id, Vector<PDBEntry> pdbEntries)
@@ -904,16 +1002,37 @@ public class StructureChooser extends GStructureChooser
     return foundEntry;
   }
 
-  private void launchStructureViewer(StructureSelectionManager ssm,
+  /**
+   * @param ssm
+   * @return targetted structure view (new or existing) configured according to
+   *         superpose checkbox
+   */
+  public StructureViewer getTargetedStructureViewer(
+          StructureSelectionManager ssm)
+  {
+    Object _sv = targetView.getSelectedItem();
+    StructureViewer sv;
+    if (_sv == null)
+    {
+      sv = new StructureViewer(ssm);
+    } else {
+      sv = (StructureViewer) _sv;
+    }
+    sv.setSuperpose(chk_superpose.isSelected());
+    return sv;
+  }
+  private StructureViewer launchStructureViewer(
+          StructureSelectionManager ssm,
           final PDBEntry[] pdbEntriesToView,
           final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
     long progressId = sequences.hashCode();
     setProgressBar(MessageManager
             .getString("status.launching_3d_structure_viewer"), progressId);
-    final StructureViewer sViewer = new StructureViewer(ssm);
-    setProgressBar(null, progressId);
+    final StructureViewer sViewer = getTargetedStructureViewer(ssm);
+    sViewer.setSuperpose(chk_superpose.isSelected());
 
+    setProgressBar(null, progressId);
     if (SiftsSettings.isMapWithSifts())
     {
       List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<>();
@@ -978,6 +1097,9 @@ public class StructureChooser extends GStructureChooser
       sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
     }
     setProgressBar(null, progressId);
+    // remember the last viewer we used...
+    lastTargetedView = sViewer;
+    return sViewer;
   }
 
   /**
@@ -1208,4 +1330,9 @@ public class StructureChooser extends GStructureChooser
   {
     return progressBar.operationInProgress();
   }
+
+  public JalviewStructureDisplayI getOpenedStructureViewer()
+  {
+    return sViewer == null ? null : sViewer.sview;
+  }
 }