basic implementation of profile display and todos
[jalview.git] / src / jalview / gui / Desktop.java
index 4cdf84c..1b24694 100755 (executable)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
- * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
+ * Copyright (C) 2009 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
@@ -24,7 +24,15 @@ import java.awt.*;
 import java.awt.datatransfer.*;
 import java.awt.dnd.*;
 import java.awt.event.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.channels.ReadableByteChannel;
 import java.util.*;
 
 import javax.swing.*;
@@ -133,7 +141,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     new SplashScreen();
 
     discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is
-                                              // displayed.
+    // displayed.
   }
 
   private void doVamsasClientCheck()
@@ -219,13 +227,13 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param frame
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param title
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param w
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param h
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public static synchronized void addInternalFrame(
           final JInternalFrame frame, String title, int w, int h)
@@ -237,15 +245,15 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param frame
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param title
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param w
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param h
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    * @param resizable
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public static synchronized void addInternalFrame(
           final JInternalFrame frame, String title, int w, int h,
@@ -373,12 +381,13 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param evt
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void drop(DropTargetDropEvent evt)
   {
     Transferable t = evt.getTransferable();
     java.util.List files = null;
+    java.util.List protocols = null;
 
     try
     {
@@ -397,6 +406,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
         String data = (String) t.getTransferData(uriListFlavor);
         files = new java.util.ArrayList(1);
+        protocols = new java.util.ArrayList(1);
         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
                 data, "\r\n"); st.hasMoreTokens();)
         {
@@ -406,10 +416,19 @@ public class Desktop extends jalview.jbgui.GDesktop implements
             // the line is a comment (as per the RFC 2483)
             continue;
           }
-
           java.net.URI uri = new java.net.URI(s);
-          java.io.File file = new java.io.File(uri);
-          files.add(file);
+          if (uri.getScheme().toLowerCase().startsWith("http"))
+          {
+            protocols.add(FormatAdapter.URL);
+            files.add(uri.toString());
+          }
+          else
+          {
+            // otherwise preserve old behaviour: catch all for file objects
+            java.io.File file = new java.io.File(uri);
+            protocols.add(FormatAdapter.FILE);
+            files.add(file.toString());
+          }
         }
       }
     } catch (Exception e)
@@ -423,7 +442,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         for (int i = 0; i < files.size(); i++)
         {
           String file = files.get(i).toString();
-          String protocol = FormatAdapter.FILE;
+          String protocol = (protocols==null) ? FormatAdapter.FILE : (String) protocols.get(i);
           String format = null;
 
           if (file.endsWith(".jar"))
@@ -449,7 +468,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
   {
@@ -497,7 +516,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
   {
@@ -577,7 +596,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
   {
@@ -602,7 +621,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void aboutMenuItem_actionPerformed(ActionEvent e)
   {
@@ -627,8 +646,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                     + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
                     + "\nIf  you use Jalview, please cite:"
                     + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
-            + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
-            + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
+                    + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
+                    + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
     JOptionPane.showInternalMessageDialog(Desktop.desktop,
 
     message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
@@ -638,7 +657,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void documentationMenuItem_actionPerformed(ActionEvent e)
   {
@@ -669,10 +688,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       }
     }
     System.out.println("ALL CLOSED");
-    if (v_client!=null)
+    if (v_client != null)
     {
       // TODO clear binding to vamsas document objects on close_all
-      
+
     }
   }
 
@@ -694,7 +713,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   /*
    * (non-Javadoc)
    * 
-   * @see jalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.ActionEvent)
+   * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
+   * ActionEvent)
    */
   protected void garbageCollect_actionPerformed(ActionEvent e)
   {
@@ -707,7 +727,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   /*
    * (non-Javadoc)
    * 
-   * @see jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent)
+   * @see
+   * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
+   * )
    */
   protected void showMemusage_actionPerformed(ActionEvent e)
   {
@@ -795,7 +817,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   protected void preferences_actionPerformed(ActionEvent e)
   {
@@ -806,7 +828,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void saveState_actionPerformed(ActionEvent e)
   {
@@ -823,8 +845,12 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
       java.io.File choice = chooser.getSelectedFile();
+      JProgressBar progpanel = addProgressPanel("Saving jalview project "+choice.getName());
       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+      // TODO catch and handle errors for savestate
       new Jalview2XML().SaveState(choice);
+      removeProgressPanel(progpanel);
+
     }
   }
 
@@ -832,7 +858,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * DOCUMENT ME!
    * 
    * @param e
-   *                DOCUMENT ME!
+   *          DOCUMENT ME!
    */
   public void loadState_actionPerformed(ActionEvent e)
   {
@@ -848,9 +874,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
       String choice = chooser.getSelectedFile().getAbsolutePath();
+      setProgressBar("loading jalview project "+chooser.getSelectedFile().getName(),choice.hashCode());
       jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
               .getSelectedFile().getParent());
       new Jalview2XML().LoadJalviewAlign(choice);
+      setProgressBar(null,choice.hashCode());
     }
   }
 
@@ -925,8 +953,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public static int getViewCount(String viewId)
   {
     AlignViewport[] aps = getViewports(viewId);
-    return (aps==null) ? 0 : aps.length;
+    return (aps == null) ? 0 : aps.length;
   }
+
   /**
    * 
    * @param viewId
@@ -935,6 +964,12 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public static AlignmentPanel[] getAlignmentPanels(String viewId)
   {
     int count = 0;
+    if (Desktop.desktop==null)
+    {
+      // no frames created and in headless mode
+      // TODO: verify that frames are recoverable when in headless mode
+      return null;
+    }
     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
     ArrayList aps = new ArrayList();
     for (int t = 0; t < frames.length; t++)
@@ -953,20 +988,23 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         }
       }
     }
-    if (aps.size()==0)
+    if (aps.size() == 0)
     {
       return null;
     }
     AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
-    for (int t=0;t<vap.length;t++)
+    for (int t = 0; t < vap.length; t++)
     {
       vap[t] = (AlignmentPanel) aps.get(t);
     }
     return vap;
   }
+
   /**
    * get all the viewports on an alignment.
-   * @param sequenceSetId unique alignment id
+   * 
+   * @param sequenceSetId
+   *          unique alignment id
    * @return all viewports on the alignment bound to sequenceSetId
    */
   public static AlignViewport[] getViewports(String sequenceSetId)
@@ -975,27 +1013,28 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (desktop != null)
     {
       javax.swing.JInternalFrame[] frames = instance.getAllFrames();
-  
+
       for (int t = 0; t < frames.length; t++)
       {
         if (frames[t] instanceof AlignFrame)
         {
           AlignFrame afr = ((AlignFrame) frames[t]);
-          if (afr.getViewport().getSequenceSetId()
-                  .equals(sequenceSetId))
+          if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
           {
-            if (afr.alignPanels!=null)
+            if (afr.alignPanels != null)
             {
               for (int a = 0; a < afr.alignPanels.size(); a++)
               {
-                if (sequenceSetId
-                        .equals(((AlignmentPanel) afr.alignPanels.elementAt(a)).av
-                                .getSequenceSetId()))
+                if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
+                        .elementAt(a)).av.getSequenceSetId()))
                 {
-                  viewp.addElement(((AlignmentPanel)afr.alignPanels.elementAt(a)).av);
+                  viewp.addElement(((AlignmentPanel) afr.alignPanels
+                          .elementAt(a)).av);
                 }
               }
-            } else {
+            }
+            else
+            {
               viewp.addElement(((AlignFrame) frames[t]).getViewport());
             }
           }
@@ -1094,19 +1133,14 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
       if (value == JalviewFileChooser.APPROVE_OPTION)
       {
-        try
-        {
-          v_client = new jalview.gui.VamsasApplication(this, chooser
-                  .getSelectedFile());
-        } catch (Exception ex)
+        String fle = chooser.getSelectedFile().toString();
+        if (!vamsasImport(chooser.getSelectedFile()))
         {
-          jalview.bin.Cache.log.error(
-                  "New vamsas session from existing session file failed:",
-                  ex);
-          return;
+          JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                  "Couldn't import '" + fle + "' as a new vamsas session.",
+                  "Vamsas Document Import Failed",
+                  JOptionPane.ERROR_MESSAGE);
         }
-        setupVamsasConnectedGui();
-        v_client.initial_update(); // TODO: thread ?
       }
     }
     else
@@ -1116,6 +1150,95 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     }
   }
 
+  /**
+   * import file into a new vamsas session (uses jalview.gui.VamsasApplication) 
+   * @param file 
+   * @return true if import was a success and a session was started.
+   */
+  public boolean vamsasImport(URL url)
+  {
+    // TODO: create progress bar
+    if (v_client != null)
+    {
+      
+      jalview.bin.Cache.log
+      .error("Implementation error - load session from a running session is not supported.");
+      return false;     
+    }
+    
+    try
+      {
+      // copy the URL content to a temporary local file
+      // TODO: be a bit cleverer here with nio (?!)
+      File file = File.createTempFile("vdocfromurl", ".vdj");
+      FileOutputStream fos = new FileOutputStream(file);
+      BufferedInputStream bis = new BufferedInputStream(url.openStream());
+      byte[] buffer = new byte[2048];
+      int ln;
+      while ((ln = bis.read(buffer))>-1)
+      {
+        fos.write(buffer,0,ln);
+      }
+      bis.close();
+      fos.close();
+      v_client = new jalview.gui.VamsasApplication(this, file, url.toExternalForm());
+      } catch (Exception ex)
+      {
+        jalview.bin.Cache.log.error(
+                "Failed to create new vamsas session from contents of URL "+url,ex);
+        return false;
+      }
+      setupVamsasConnectedGui();
+      v_client.initial_update(); // TODO: thread ?
+      return v_client.inSession();
+    }
+
+  /**
+   * import file into a new vamsas session (uses jalview.gui.VamsasApplication) 
+   * @param file 
+   * @return true if import was a success and a session was started.
+   */
+  public boolean vamsasImport(File file)
+  {
+    if (v_client != null)
+    {
+
+      jalview.bin.Cache.log
+              .error("Implementation error - load session from a running session is not supported.");
+      return false;
+    }
+
+    setProgressBar("Importing VAMSAS session from "+file.getName(),file.hashCode());
+    try
+    {
+      v_client = new jalview.gui.VamsasApplication(this, file,null);
+    } catch (Exception ex)
+    {
+      setProgressBar("Importing VAMSAS session from "+file.getName(),file.hashCode());
+      jalview.bin.Cache.log.error(
+              "New vamsas session from existing session file failed:", ex);
+      return false;
+    }
+    setupVamsasConnectedGui();
+    v_client.initial_update(); // TODO: thread ?
+    setProgressBar("Importing VAMSAS session from "+file.getName(),file.hashCode());
+    return v_client.inSession();
+  }
+  public boolean joinVamsasSession(String mysesid) {
+    if (v_client!=null)
+    {
+      throw new Error("Trying to join a vamsas session when another is already connected.");
+    }
+    if (mysesid==null)
+    {
+      throw new Error("Invalid vamsas session id.");
+    }
+    v_client = new VamsasApplication(this, mysesid);
+    setupVamsasConnectedGui();
+    v_client.initial_update();
+    return (v_client.inSession());
+  }
+
   public void vamsasStart_actionPerformed(ActionEvent e)
   {
     if (v_client == null)
@@ -1134,7 +1257,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
        * 
        * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
        * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
-       * 
        */
       v_client = new VamsasApplication(this);
       setupVamsasConnectedGui();
@@ -1153,7 +1275,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     vamsasSave.setVisible(true);
     vamsasStop.setVisible(true);
     vamsasImport.setVisible(false); // Document import to existing session is
-                                    // not possible for vamsas-client-1.0.
+    // not possible for vamsas-client-1.0.
   }
 
   protected void setupVamsasDisconnectedGui()
@@ -1260,6 +1382,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       if (value == JalviewFileChooser.APPROVE_OPTION)
       {
         java.io.File choice = chooser.getSelectedFile();
+        JProgressBar progpanel = addProgressPanel("Saving VAMSAS Document to "+choice.getName());
         jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
         String warnmsg = null;
         String warnttl = null;
@@ -1281,6 +1404,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                   + choice, ex);
 
         }
+        removeProgressPanel(progpanel);
         if (warnmsg != null)
         {
           JOptionPane.showInternalMessageDialog(Desktop.desktop,
@@ -1297,7 +1421,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * hide vamsas user gui bits when a vamsas document event is being handled.
    * 
    * @param b
-   *                true to hide gui, false to reveal gui
+   *          true to hide gui, false to reveal gui
    */
   public void setVamsasUpdate(boolean b)
   {
@@ -1544,7 +1668,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
               .remove(new Long(id));
       if (progressBarHandlers.contains(new Long(id)))
       {
-          progressBarHandlers.remove(new Long(id));
+        progressBarHandlers.remove(new Long(id));
       }
       removeProgressPanel(progressPanel);
     }
@@ -1553,32 +1677,41 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       progressBars.put(new Long(id), addProgressPanel(message));
     }
   }
-  /* (non-Javadoc)
-   * @see jalview.gui.IProgressIndicator#registerHandler(long, jalview.gui.IProgressIndicatorHandler)
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.gui.IProgressIndicator#registerHandler(long,
+   * jalview.gui.IProgressIndicatorHandler)
    */
-  public void registerHandler(final long id, final IProgressIndicatorHandler handler)
+  public void registerHandler(final long id,
+          final IProgressIndicatorHandler handler)
   {
-    if (progressBarHandlers==null || !progressBars.contains(new Long(id)))
+    if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
     {
-      throw new Error("call setProgressBar before registering the progress bar's handler.");
+      throw new Error(
+              "call setProgressBar before registering the progress bar's handler.");
     }
     progressBarHandlers.put(new Long(id), handler);
     final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
     if (handler.canCancel())
     {
       JButton cancel = new JButton("Cancel");
-      final IProgressIndicator us=this;
-      cancel.addActionListener(new ActionListener() {
+      final IProgressIndicator us = this;
+      cancel.addActionListener(new ActionListener()
+      {
 
         public void actionPerformed(ActionEvent e)
         {
           handler.cancelActivity(id);
-          us.setProgressBar("Cancelled "+((JLabel)progressPanel.getComponent(0)).getText(), id);
+          us.setProgressBar("Cancelled "
+                  + ((JLabel) progressPanel.getComponent(0)).getText(), id);
         }
       });
       progressPanel.add(cancel, BorderLayout.EAST);
     }
   }
+
   /**
    * This will return the first AlignFrame viewing AlignViewport av. It will
    * break if there are more than one AlignFrames viewing a particular av. This
@@ -1591,12 +1724,20 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (desktop != null)
     {
       AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
-      for (int panel=0;aps!=null && panel<aps.length;panel++)
-        { if (aps[panel]!=null && aps[panel].av==av) {
+      for (int panel = 0; aps != null && panel < aps.length; panel++)
+      {
+        if (aps[panel] != null && aps[panel].av == av)
+        {
           return aps[panel].alignFrame;
         }
-        }
+      }
     }
     return null;
   }
+
+  public VamsasApplication getVamsasApplication()
+  {
+    return v_client;
+
+  }
 }