added d martin to authors and fixed faq/discuss message
[jalview.git] / src / jalview / gui / AlignFrame.java
index 72691cc..1320aa0 100755 (executable)
@@ -1,19 +1,19 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
- *
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
+ * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Softwarechang
+ * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 package jalview.gui;
@@ -45,7 +45,7 @@ import jalview.ws.*;
  * @version $Revision$
  */
 public class AlignFrame
-    extends GAlignFrame implements DropTargetListener
+    extends GAlignFrame implements DropTargetListener, IProgressIndicator
 {
   /** DOCUMENT ME!! */
   public static final int DEFAULT_WIDTH = 700;
@@ -68,6 +68,8 @@ public class AlignFrame
    */
   String fileName = null;
 
+  
+
 
   /**
    * Creates a new AlignFrame object.
@@ -513,11 +515,17 @@ public class AlignFrame
     {
       calculateMenu.remove(calculateMenu.getItemCount()-2);
     }
-    setShowProductsEnabled();
   }
 
 
-
+  /**
+   * set up menus for the currently viewport.
+   * This may be called after any operation that affects the data in the current view (selection changed, etc) to update the menus to reflect the new state.
+   */
+  public void setMenusForViewport()
+  {
+    setMenusFromViewport(viewport);
+  }
   /**
    * Need to call this method when tabs are selected for multiple views,
    * or when loading from Jalview2XML.java
@@ -531,6 +539,7 @@ public class AlignFrame
     conservationMenuItem.setSelected(av.getConservationSelected());
     seqLimits.setSelected(av.getShowJVSuffix());
     idRightAlign.setSelected(av.rightAlignIds);
+    centreColumnLabelsMenuItem.setState(av.centreColumnLabels);
     renderGapsMenuItem.setSelected(av.renderGaps);
     wrapMenuItem.setSelected(av.wrapAlignment);
     scaleAbove.setVisible(av.wrapAlignment);
@@ -547,11 +556,16 @@ public class AlignFrame
     hiddenMarkers.setState(av.showHiddenMarkers);
     applyToAllGroups.setState(av.colourAppliesToAllGroups);
 
+    setShowProductsEnabled();
+
     updateEditMenuBar();
   }
 
 
   Hashtable progressBars;
+  /* (non-Javadoc)
+   * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
+   */
   public void setProgressBar(String message, long id)
   {
     if(progressBars == null)
@@ -589,7 +603,8 @@ public class AlignFrame
 
       progressBars.put(new Long(id), progressPanel);
     }
-
+    // update GUI
+    setMenusForViewport();
     validate();
   }
   /**
@@ -2187,6 +2202,12 @@ public class AlignFrame
     alignPanel.paintAlignment(true);
   }
 
+  public void centreColumnLabels_actionPerformed(ActionEvent e)
+  {
+    viewport.centreColumnLabels = centreColumnLabelsMenuItem.getState();
+    alignPanel.paintAlignment(true);
+  }
+
 
 
   /**
@@ -3261,7 +3282,7 @@ public class AlignFrame
    * or just the selected set will be submitted for multiple alignment.
    *
    */
-  private jalview.datamodel.AlignmentView gatherSequencesForAlignment()
+  public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
   {
     // Now, check we have enough sequences
     AlignmentView msa = null;
@@ -3299,12 +3320,14 @@ public class AlignFrame
   }
 
   /**
-   * Decides what is submitted to a secondary structure prediction service,
-   * the currently selected sequence, or the currently selected alignment
+   * Decides what is submitted to a secondary structure prediction service:
+   * the first sequence in the alignment, or in the current selection,
+   * or, if the alignment is 'aligned' (ie padded with gaps), then the
+   * currently selected region or the whole alignment.
    * (where the first sequence in the set is the one that the prediction
    * will be for).
    */
-  AlignmentView gatherSeqOrMsaForSecStrPrediction()
+  public AlignmentView gatherSeqOrMsaForSecStrPrediction()
   {
    AlignmentView seqs = null;
 
@@ -3445,17 +3468,19 @@ public class AlignFrame
   public void BuildWebServiceMenu()
   {
     // TODO: add support for context dependent disabling of services based on alignment and current selection
-    // TODO: refactor to allow list of AbstractName/Handler bindings to be stored or retrieved from elsewhere
     // TODO: add additional serviceHandle parameter to specify abstract handler class independently of AbstractName
     // TODO: add in rediscovery GUI function to restart discoverer
     // TODO: group services by location as well as function and/or introduce object broker mechanism.
     if ( (Discoverer.services != null)
         && (Discoverer.services.size() > 0))
     {
+      // TODO: refactor to allow list of AbstractName/Handler bindings to be stored or retrieved from elsewhere
       Vector msaws = (Vector) Discoverer.services.get("MsaWS");
       Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");
+      Vector seqsrch = (Vector) Discoverer.services.get("SeqSearch");
+      // TODO: move GUI generation code onto service implementation - so a client instance attaches itself to the GUI with method call like jalview.ws.MsaWSClient.bind(servicehandle, Desktop.instance, alignframe)
       Vector wsmenu = new Vector();
-      final AlignFrame af = this;
+      final IProgressIndicator af = this;
       if (msaws != null)
       {
         // Add any Multiple Sequence Alignment Services
@@ -3464,42 +3489,9 @@ public class AlignFrame
         {
           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.
               get(i);
-          final JMenuItem method = new JMenuItem(sh.getName());
-          method.addActionListener(new ActionListener()
-          {
-            public void actionPerformed(ActionEvent e)
-            {
-              AlignmentView msa = gatherSequencesForAlignment();
-              new jalview.ws.MsaWSClient(sh, title, msa,
-                                         false, true,
-                                         viewport.getAlignment().getDataset(),
-                                         af);
-
-            }
-
-          });
-          msawsmenu.add(method);
-          // Deal with services that we know accept partial alignments.
-          if (sh.getName().indexOf("lustal") > -1)
-          {
-            // We know that ClustalWS can accept partial alignments for refinement.
-            final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");
-            methodR.addActionListener(new ActionListener()
-            {
-              public void actionPerformed(ActionEvent e)
-              {
-                AlignmentView msa = gatherSequencesForAlignment();
-                new jalview.ws.MsaWSClient(sh, title, msa,
-                                           true, true,
-                                           viewport.getAlignment().getDataset(),
-                                           af);
-
-              }
-
-            });
-            msawsmenu.add(methodR);
-
-          }
+          jalview.ws.WSClient impl = jalview.ws.Discoverer.getServiceClient(sh);
+          impl.attachWSMenuEntry(msawsmenu, this);
+        
         }
         wsmenu.add(msawsmenu);
       }
@@ -3511,32 +3503,25 @@ public class AlignFrame
         {
           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)
               secstrpr.get(i);
-          final JMenuItem method = new JMenuItem(sh.getName());
-          method.addActionListener(new ActionListener()
-          {
-            public void actionPerformed(ActionEvent e)
-            {
-              AlignmentView msa = gatherSeqOrMsaForSecStrPrediction();
-              if (msa.getSequences().length == 1)
-              {
-                // Single Sequence prediction
-                new jalview.ws.JPredClient(sh, title, false, msa, af, true);
-              }
-              else
-              {
-                if (msa.getSequences().length > 1)
-                {
-                  // Sequence profile based prediction
-                  new jalview.ws.JPredClient(sh,
-                      title, true, msa, af, true);
-                }
-              }
-            }
-          });
-          secstrmenu.add(method);
+          jalview.ws.WSClient impl = jalview.ws.Discoverer.getServiceClient(sh);
+          impl.attachWSMenuEntry(secstrmenu, this);
         }
         wsmenu.add(secstrmenu);
       }
+      if (seqsrch!=null)
+      {
+        // Add any sequence search services
+        final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
+        for (int i = 0, j = seqsrch.size(); i < j; i++)
+        {
+          final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)
+              seqsrch.elementAt(i);
+          jalview.ws.WSClient impl = jalview.ws.Discoverer.getServiceClient(sh);
+          impl.attachWSMenuEntry(seqsrchmenu, this);
+        }
+        // finally, add the whole shebang onto the webservices menu
+        wsmenu.add(seqsrchmenu); 
+      }
       resetWebServiceMenu();
       for (int i = 0, j = wsmenu.size(); i < j; i++)
       {
@@ -3561,15 +3546,22 @@ public class AlignFrame
     webService.removeAll();
     // Temporary hack - DBRef Fetcher always top level ws entry.
     JMenuItem rfetch = new JMenuItem("Fetch DB References");
-    rfetch.setToolTipText("Retrieve and parse uniprot records for the alignment or the currently selected sequences");
+    rfetch.setToolTipText("Retrieve and parse sequence database records for the alignment or the currently selected sequences");
     webService.add(rfetch);
     rfetch.addActionListener(new ActionListener() {
 
       public void actionPerformed(ActionEvent e)
       {
-        new jalview.ws.DBRefFetcher(
-                alignPanel.av.getSequenceSelection(),
-                alignPanel.alignFrame).fetchDBRefs(false);
+        new Thread(new Runnable() {
+
+          public void run()
+          {
+            new jalview.ws.DBRefFetcher(
+                    alignPanel.av.getSequenceSelection(),
+                    alignPanel.alignFrame).fetchDBRefs(false);
+          }
+        }).start();
+        
       }
 
     });
@@ -3637,7 +3629,7 @@ public class AlignFrame
           public void actionPerformed(ActionEvent e)
           {
             // TODO: new thread for this call with vis-delay
-            af.showProductsFor(sel, ds, isRegSel, dna, source);
+            af.showProductsFor(af.viewport.getSequenceSelection(), ds, isRegSel, dna, source);
           }
           
         });
@@ -3938,6 +3930,7 @@ public void drop(DropTargetDropEvent evt)
       {
         
         alignPanel.adjustAnnotationHeight();
+        viewport.updateSequenceIdColours();
         buildSortByAnnotationScoresMenu();
         alignPanel.paintAlignment(true);
       }
@@ -3988,8 +3981,9 @@ public void drop(DropTargetDropEvent evt)
   protected void extractScores_actionPerformed(ActionEvent e)
   {
     ParseProperties pp = new jalview.analysis.ParseProperties(viewport.alignment);
-    if (pp.getScoresFromDescription("col", "score column ", "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)", true)>0)
-    {
+    // TODO: verify regex and introduce GUI dialog for version 2.5
+    //if (pp.getScoresFromDescription("col", "score column ", "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)", true)>0)
+    if (pp.getScoresFromDescription("description column", "score in description column ", "\\W*([-+eE0-9.]+)", true)>0)    {
       buildSortByAnnotationScoresMenu();
     }
   }