Merge branch 'develop' into feature/JAL-244_Automatically_adjust_left_margin_to_avoid...
[jalview.git] / src / jalview / gui / StructureChooser.java
index 4e5378e..6fce984 100644 (file)
@@ -28,10 +28,11 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.concurrent.Callable;
+import java.util.Map;
 import java.util.concurrent.Executors;
 
 import javax.swing.JCheckBox;
 import java.util.concurrent.Executors;
 
 import javax.swing.JCheckBox;
@@ -45,11 +46,16 @@ import javax.swing.table.AbstractTableModel;
 
 import com.stevesoft.pat.Regex;
 
 
 import com.stevesoft.pat.Regex;
 
+import jalview.analysis.AlignmentUtils;
+import jalview.api.AlignmentViewPanel;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.bin.Jalview;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JmolParser;
 import jalview.fts.api.FTSData;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JmolParser;
 import jalview.fts.api.FTSData;
@@ -60,6 +66,7 @@ import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
 import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.fts.service.threedbeacons.TDB_FTSData;
 import jalview.fts.core.FTSRestResponse;
 import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.fts.service.threedbeacons.TDB_FTSData;
+import jalview.gui.StructureViewer.ViewerType;
 import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
 import jalview.gui.structurechooser.StructureChooserQuerySource;
 import jalview.gui.structurechooser.ThreeDBStructureChooserQuerySource;
 import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
 import jalview.gui.structurechooser.StructureChooserQuerySource;
 import jalview.gui.structurechooser.ThreeDBStructureChooserQuerySource;
@@ -342,7 +349,7 @@ public class StructureChooser extends GStructureChooser
     };
 
     // fetch db refs if OK pressed
     };
 
     // fetch db refs if OK pressed
-    final Callable discoverCanonicalDBrefs = () -> {
+    final Runnable discoverCanonicalDBrefs = () -> {
       btn_queryTDB.setEnabled(false);
       populateSeqsWithoutSourceDBRef();
 
       btn_queryTDB.setEnabled(false);
       populateSeqsWithoutSourceDBRef();
 
@@ -364,14 +371,12 @@ public class StructureChooser extends GStructureChooser
         // call finished action directly
         afterDbRefFetch.finished();
       }
         // call finished action directly
         afterDbRefFetch.finished();
       }
-      return null;
     };
     };
-    final Callable revertview = () -> {
+    final Runnable revertview = () -> {
       if (lastSelected != null)
       {
         cmb_filterOption.setSelectedItem(lastSelected);
       }
       if (lastSelected != null)
       {
         cmb_filterOption.setSelectedItem(lastSelected);
       }
-      return null;
     };
     int threshold = Cache.getDefault("UNIPROT_AUTOFETCH_THRESHOLD",
             THRESHOLD_WARN_UNIPROT_FETCH_NEEDED);
     };
     int threshold = Cache.getDefault("UNIPROT_AUTOFETCH_THRESHOLD",
             THRESHOLD_WARN_UNIPROT_FETCH_NEEDED);
@@ -736,16 +741,18 @@ public class StructureChooser extends GStructureChooser
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
       String fileName = chooser.getSelectedFile().getPath();
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
       String fileName = chooser.getSelectedFile().getPath();
-      try {
+      try
+      {
         PAEContactMatrix.validateContactMatrixFile(fileName);
       } catch (Exception thr)
       {
         JvOptionPane.showInternalMessageDialog(this, MessageManager
                 .formatMessage("label.couldnt_load_file", new Object[]
         PAEContactMatrix.validateContactMatrixFile(fileName);
       } catch (Exception thr)
       {
         JvOptionPane.showInternalMessageDialog(this, MessageManager
                 .formatMessage("label.couldnt_load_file", new Object[]
-                { fileName})+"<br>"+thr.getLocalizedMessage(),
+                { fileName }) + "<br>" + thr.getLocalizedMessage(),
                 MessageManager.getString("label.error_loading_file"),
                 JvOptionPane.WARNING_MESSAGE);
                 MessageManager.getString("label.error_loading_file"),
                 JvOptionPane.WARNING_MESSAGE);
-        Console.error("Couldn't import "+fileName+" as a PAE matrix",thr);
+        Console.error("Couldn't import " + fileName + " as a PAE matrix",
+                thr);
         return;
       }
       localPdbPaeMatrixFileName = fileName;
         return;
       }
       localPdbPaeMatrixFileName = fileName;
@@ -1203,6 +1210,12 @@ public class StructureChooser extends GStructureChooser
     final int preferredHeight = pnl_filter.getHeight();
     btn_add.setEnabled(false);
     btn_newView.setEnabled(false);
     final int preferredHeight = pnl_filter.getHeight();
     btn_add.setEnabled(false);
     btn_newView.setEnabled(false);
+    btn_cancel.setEnabled(false);
+    actionsPanel.setEnabled(false);
+
+    final String progress = MessageManager
+            .getString("label.working_ellipsis");
+    setProgressBar(progress, progress.hashCode());
     Runnable viewStruc = new Runnable()
     {
       @Override
     Runnable viewStruc = new Runnable()
     {
       @Override
@@ -1293,17 +1306,21 @@ public class StructureChooser extends GStructureChooser
                   .getCmb_assSeq().getSelectedItem();
           SequenceI userSelectedSeq = assSeqOpt.getSequence();
           if (userSelectedSeq != null)
                   .getCmb_assSeq().getSelectedItem();
           SequenceI userSelectedSeq = assSeqOpt.getSequence();
           if (userSelectedSeq != null)
+          {
             selectedSequence = userSelectedSeq;
             selectedSequence = userSelectedSeq;
+          }
           String pdbFilename = selectedPdbFileName;
 
           StructureChooser.openStructureFileForSequence(ssm, sc, ap,
           String pdbFilename = selectedPdbFileName;
 
           StructureChooser.openStructureFileForSequence(ssm, sc, ap,
-                  selectedSequence, true, pdbFilename, tft, paeFilename);
+                  selectedSequence, true, pdbFilename, tft, paeFilename,
+                  true);
         }
         SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
           {
         }
         SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
           {
+            setProgressBar("Complete.", progress.hashCode());
             closeAction(preferredHeight);
             mainFrame.dispose();
           }
             closeAction(preferredHeight);
             mainFrame.dispose();
           }
@@ -1356,6 +1373,15 @@ public class StructureChooser extends GStructureChooser
           StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView,
           final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
           StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView,
           final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
+    return launchStructureViewer(ssm, pdbEntriesToView, alignPanel,
+            sequences, null);
+  }
+
+  private StructureViewer launchStructureViewer(
+          StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView,
+          final AlignmentPanel alignPanel, SequenceI[] sequences,
+          ViewerType viewerType)
+  {
     long progressId = sequences.hashCode();
     setProgressBar(MessageManager
             .getString("status.launching_3d_structure_viewer"), progressId);
     long progressId = sequences.hashCode();
     setProgressBar(MessageManager
             .getString("status.launching_3d_structure_viewer"), progressId);
@@ -1420,7 +1446,8 @@ public class StructureChooser extends GStructureChooser
               MessageManager.getString(
                       "status.fetching_3d_structures_for_selected_entries"),
               progressId);
               MessageManager.getString(
                       "status.fetching_3d_structures_for_selected_entries"),
               progressId);
-      theViewer.viewStructures(pdbEntriesToView, sequences, alignPanel);
+      theViewer.viewStructures(pdbEntriesToView, sequences, alignPanel,
+              viewerType);
     }
     else
     {
     }
     else
     {
@@ -1428,7 +1455,8 @@ public class StructureChooser extends GStructureChooser
               "status.fetching_3d_structures_for",
               pdbEntriesToView[0].getId()), progressId);
       // Can we pass a pre-computeMappinged pdbFile?
               "status.fetching_3d_structures_for",
               pdbEntriesToView[0].getId()), progressId);
       // Can we pass a pre-computeMappinged pdbFile?
-      theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
+      theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel,
+              viewerType);
     }
     setProgressBar(null, progressId);
     // remember the last viewer we used...
     }
     setProgressBar(null, progressId);
     // remember the last viewer we used...
@@ -1669,20 +1697,21 @@ public class StructureChooser extends GStructureChooser
   @Override
   public void setProgressBar(String message, long id)
   {
   @Override
   public void setProgressBar(String message, long id)
   {
-    if (!Platform.isHeadless())
+    if (!Platform.isHeadless() && progressBar != null)
       progressBar.setProgressBar(message, id);
   }
 
   @Override
   public void registerHandler(long id, IProgressIndicatorHandler handler)
   {
       progressBar.setProgressBar(message, id);
   }
 
   @Override
   public void registerHandler(long id, IProgressIndicatorHandler handler)
   {
-    progressBar.registerHandler(id, handler);
+    if (progressBar != null)
+      progressBar.registerHandler(id, handler);
   }
 
   @Override
   public boolean operationInProgress()
   {
   }
 
   @Override
   public boolean operationInProgress()
   {
-    return progressBar.operationInProgress();
+    return progressBar == null ? false : progressBar.operationInProgress();
   }
 
   public JalviewStructureDisplayI getOpenedStructureViewer()
   }
 
   public JalviewStructureDisplayI getOpenedStructureViewer()
@@ -1729,26 +1758,73 @@ public class StructureChooser extends GStructureChooser
   public static void openStructureFileForSequence(
           StructureSelectionManager ssm, StructureChooser sc,
           AlignmentPanel ap, SequenceI seq, boolean prompt,
   public static void openStructureFileForSequence(
           StructureSelectionManager ssm, StructureChooser sc,
           AlignmentPanel ap, SequenceI seq, boolean prompt,
-          String sFilename, TFType tft, String paeFilename)
+          String sFilename, TFType tft, String paeFilename,
+          boolean doXferSettings)
+  {
+    openStructureFileForSequence(ssm, sc, ap, seq, prompt, sFilename, tft,
+            paeFilename, false, true, doXferSettings, null);
+  }
+
+  public static StructureViewer openStructureFileForSequence(
+          StructureSelectionManager ssm, StructureChooser sc,
+          AlignmentPanel ap, SequenceI seq, boolean prompt,
+          String sFilename, TFType tft, String paeFilename,
+          boolean forceHeadless, boolean showRefAnnotations,
+          boolean doXferSettings, ViewerType viewerType)
   {
   {
-    boolean headless = false;
+    StructureViewer sv = null;
+    boolean headless = forceHeadless;
     if (sc == null)
     {
     if (sc == null)
     {
-      headless = true;
+      // headless = true;
+      prompt = false;
       sc = new StructureChooser(new SequenceI[] { seq }, seq, ap, false);
     }
     if (ssm == null)
       sc = new StructureChooser(new SequenceI[] { seq }, seq, ap, false);
     }
     if (ssm == null)
+    {
       ssm = ap.getStructureSelectionManager();
       ssm = ap.getStructureSelectionManager();
+    }
 
     PDBEntry fileEntry = new AssociatePdbFileWithSeq().associatePdbWithSeq(
             sFilename, DataSourceType.FILE, seq, prompt, Desktop.instance,
 
     PDBEntry fileEntry = new AssociatePdbFileWithSeq().associatePdbWithSeq(
             sFilename, DataSourceType.FILE, seq, prompt, Desktop.instance,
-            tft, paeFilename);
+            tft, paeFilename, doXferSettings);
+
+    // if headless, "false" in the sc constructor above will avoid GUI behaviour
+    // in sc.launchStructureViewer()
+    if (!headless && !(viewerType == null))
+    {
+      sv = sc.launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
+              new SequenceI[]
+              { seq }, viewerType);
+    }
 
 
-    StructureViewer sViewer = sc.launchStructureViewer(ssm,
-            new PDBEntry[]
-            { fileEntry }, ap, new SequenceI[] { seq });
+    sc.mainFrame.dispose();
+
+    if (showRefAnnotations)
+      showReferenceAnnotationsForSequence(ap.alignFrame, seq);
+
+    return sv;
+  }
+
+  public static void showReferenceAnnotationsForSequence(AlignFrame af,
+          SequenceI sequence)
+  {
+    AlignViewport av = af.getCurrentView();
+    AlignmentI al = av.getAlignment();
+
+    List<SequenceI> forSequences = new ArrayList<>();
+    forSequences.add(sequence);
+    final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
+    AlignmentUtils.findAddableReferenceAnnotations(forSequences, null,
+            candidates, al);
+    final SequenceGroup selectionGroup = av.getSelectionGroup();
+    AlignmentUtils.addReferenceAnnotations(candidates, al, selectionGroup);
+    for (AlignmentViewPanel ap : af.getAlignPanels())
+    {
+      // required to readjust the height and position of the PAE
+      // annotation
+      ap.adjustAnnotationHeight();
+    }
 
 
-    if (headless)
-      sc.mainFrame.dispose();
   }
 }
   }
 }