ensure input data can be recovered for tree and PCA even if alignment view was closed
[jalview.git] / src / jalview / gui / Desktop.java
index e690238..2be8770 100755 (executable)
@@ -19,6 +19,7 @@
 package jalview.gui;
 
 import jalview.io.*;
+
 import java.awt.*;
 import java.awt.datatransfer.*;
 import java.awt.dnd.*;
@@ -27,6 +28,8 @@ import java.lang.reflect.Constructor;
 import java.util.*;
 
 import javax.swing.*;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
 
 /**
  * DOCUMENT ME!
@@ -36,15 +39,15 @@ import javax.swing.*;
  */
 public class Desktop
     extends jalview.jbgui.GDesktop implements DropTargetListener,
-    ClipboardOwner
+    ClipboardOwner, IProgressIndicator
 {
   /** DOCUMENT ME!! */
   public static Desktop instance;
 
   //Need to decide if the Memory Usage is to be included in
   //Next release or not.
- // public static MyDesktopPane desktop;
-   public static JDesktopPane desktop;
+  public static MyDesktopPane desktop;
+  // public static JDesktopPane desktop;
 
 
   static int openFrameCount = 0;
@@ -62,6 +65,11 @@ public class Desktop
    */
   public Desktop()
   {
+    /**
+     * A note to implementors. It is ESSENTIAL that any 
+     * activities that might block are spawned off as threads rather 
+     * than waited for during this constructor.
+     */
     instance = this;
     doVamsasClientCheck();
     doGroovyCheck();
@@ -69,8 +77,9 @@ public class Desktop
 
     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
-    desktop = new JDesktopPane();
+    boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",false);
+    desktop = new MyDesktopPane(selmemusage);
+    showMemusage.setSelected(selmemusage);
     desktop.setBackground(Color.white);
     getContentPane().setLayout(new BorderLayout());
     getContentPane().add(desktop, BorderLayout.CENTER);
@@ -118,10 +127,9 @@ public class Desktop
 
 
     this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
+    // Spawn a thread that shows the splashscreen
+    new SplashScreen();     
 
-    /////////Add a splashscreen on startup
-    /////////Add a splashscreen on startup
-    new SplashScreen();
 
 
     discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
@@ -131,8 +139,34 @@ public class Desktop
   {
     if (jalview.bin.Cache.vamsasJarsPresent())
     {
+      setupVamsasDisconnectedGui();
       VamsasMenu.setVisible(true);
-      vamsasLoad.setVisible(true);
+      final Desktop us = this;
+      VamsasMenu.addMenuListener(new MenuListener() {
+        // this listener remembers when the menu was first selected, and
+        // doesn't rebuild the session list until it has been cleared and
+        // reselected again.
+        boolean refresh=true;
+        public void menuCanceled(MenuEvent e)
+        {
+          refresh=true;
+        }
+
+        public void menuDeselected(MenuEvent e)
+        {
+          refresh = true;
+        }
+
+        public void menuSelected(MenuEvent e)
+        {
+          if (refresh)
+          {
+            us.buildVamsasStMenu();
+            refresh=false;
+          }
+        }
+      });
+      vamsasStart.setVisible(true);
     }
   }
 
@@ -404,15 +438,9 @@ public class Desktop
     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
         getProperty(
             "LAST_DIRECTORY"),
-        new String[]
-        {
-        "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
-        "jar"
-    },
-        new String[]
-        {
-        "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
-    }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
+            jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
+            jalview.io.AppletFormatAdapter.READABLE_FNAMES, 
+            jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
 
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle("Open local file");
@@ -641,6 +669,25 @@ public class Desktop
     reorderAssociatedWindows(false, true);
   }
 
+  /* (non-Javadoc)
+   * @see jalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.ActionEvent)
+   */
+  protected void garbageCollect_actionPerformed(ActionEvent e)
+  {
+    // We simply collect the garbage
+    jalview.bin.Cache.log.debug("Collecting garbage...");
+    System.gc();
+    jalview.bin.Cache.log.debug("Finished garbage collection.");
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent)
+   */
+  protected void showMemusage_actionPerformed(ActionEvent e)
+  {
+    desktop.showMemoryUsage(showMemusage.isSelected());
+  }
+
   void reorderAssociatedWindows(boolean minimize, boolean close)
   {
     JInternalFrame[] frames = desktop.getAllFrames();
@@ -717,7 +764,6 @@ public class Desktop
       }
     }
   }
-
   /**
    * DOCUMENT ME!
    *
@@ -782,31 +828,9 @@ public class Desktop
     }
   }
 
-  /*  public void vamsasLoad_actionPerformed(ActionEvent e)
-    {
-      JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
-          getProperty("LAST_DIRECTORY"));
-
-      chooser.setFileView(new JalviewFileView());
-      chooser.setDialogTitle("Load Vamsas file");
-      chooser.setToolTipText("Import");
-
-      int value = chooser.showOpenDialog(this);
-
-      if (value == JalviewFileChooser.APPROVE_OPTION)
-      {
-        jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(null);
-        vs.load(
-            chooser.getSelectedFile().getAbsolutePath()
-            );
-      }
-
-    }*/
-
-
   public void inputSequence_actionPerformed(ActionEvent e)
   {
-    new SequenceFetcher(null);
+    new SequenceFetcher(this);
   }
 
   JPanel progressPanel;
@@ -815,21 +839,45 @@ public class Desktop
   {
     if (fileLoadingCount == 0)
     {
+      addProgressPanel("Loading File: " + fileName + "   ");
+      
+    }
+    fileLoadingCount++;
+  }
+  private JProgressBar addProgressPanel(String string)
+  {
+    if (progressPanel==null)
+    {
       progressPanel = new JPanel(new BorderLayout());
-      JProgressBar progressBar = new JProgressBar();
-      progressBar.setIndeterminate(true);
+      totalProgressCount=0;
+    }
+    JProgressBar progressBar = new JProgressBar();
+    progressBar.setIndeterminate(true);
 
-      progressPanel.add(new JLabel("Loading File: " + fileName + "   "),
-                        BorderLayout.WEST);
+    progressPanel.add(new JLabel(string),
+                      BorderLayout.WEST);
 
-      progressPanel.add(progressBar, BorderLayout.CENTER);
+    progressPanel.add(progressBar, BorderLayout.CENTER);
 
-      instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
+    instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
+    totalProgressCount++;
+    validate();
+    return progressBar;
+  }
+  int totalProgressCount=0;
+  private void removeProgressPanel(JProgressBar progbar)
+  {
+    if (progressPanel!=null)
+    {
+      progressPanel.remove(progbar);
+      if (--totalProgressCount<1)
+      {
+        this.getContentPane().remove(progressPanel);
+        progressPanel = null;
+      }
     }
-    fileLoadingCount++;
     validate();
   }
-
   public void stopLoading()
   {
     fileLoadingCount--;
@@ -844,7 +892,6 @@ public class Desktop
     }
     validate();
   }
-
   public static int getViewCount(String viewId)
   {
     int count = 0;
@@ -936,7 +983,39 @@ public class Desktop
   }
 
   jalview.gui.VamsasApplication v_client = null;
-  public void vamsasLoad_actionPerformed(ActionEvent e)
+  public void vamsasImport_actionPerformed(ActionEvent e)
+  {
+    if (v_client==null)
+    {
+      // Load and try to start a session.
+      JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+          getProperty("LAST_DIRECTORY"));
+
+      chooser.setFileView(new JalviewFileView());
+      chooser.setDialogTitle("Open a saved VAMSAS session");
+      chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
+
+      int value = chooser.showOpenDialog(this);
+
+      if (value == JalviewFileChooser.APPROVE_OPTION)
+      {
+        try {
+          v_client = new jalview.gui.VamsasApplication(this,
+                                                chooser.getSelectedFile());
+        } catch (Exception ex)
+        {
+          jalview.bin.Cache.log.error("New vamsas session from existing session file failed:",ex);
+          return;
+        }
+        setupVamsasConnectedGui();
+        v_client.initial_update(); // TODO: thread ?
+      }
+    }else {
+      jalview.bin.Cache.log.error("Implementation error - load session from a running session is not supported.");
+    }
+  }
+
+  public void vamsasStart_actionPerformed(ActionEvent e)
   {
     if (v_client == null)
     {
@@ -959,28 +1038,154 @@ public class Desktop
                                                 *
                                                 */
       v_client = new VamsasApplication(this);
-      vamsasLoad.setText("Session Update");
-      vamsasStop.setVisible(true);
-      v_client.initial_update();
+      setupVamsasConnectedGui();
+      v_client.initial_update(); // TODO: thread ?
     }
     else
     {
       // store current data in session.
-      v_client.push_update();
+      v_client.push_update(); // TODO: thread
     }
   }
 
+  protected void setupVamsasConnectedGui()
+  {
+    vamsasStart.setText("Session Update");
+    vamsasSave.setVisible(true);
+    vamsasStop.setVisible(true);
+    vamsasImport.setVisible(false); // Document import to existing session is not possible for vamsas-client-1.0.
+  }
+  protected void setupVamsasDisconnectedGui()
+  {
+    vamsasSave.setVisible(false);
+    vamsasStop.setVisible(false);
+    vamsasImport.setVisible(true);
+    vamsasStart.setText("New Vamsas Session");
+  }
+
   public void vamsasStop_actionPerformed(ActionEvent e)
   {
     if (v_client != null)
     {
       v_client.end_session();
       v_client = null;
-      this.vamsasStop.setVisible(false);
-      this.vamsasLoad.setText("Start Vamsas Session...");
+      setupVamsasDisconnectedGui();
+    }
+  }
+  protected void buildVamsasStMenu()
+  {
+    if (v_client == null)
+    {
+      String[] sess = null;
+      try
+      {
+        sess = VamsasApplication.getSessionList();
+      } catch (Exception e)
+      {
+        jalview.bin.Cache.log.warn(
+                "Problem getting current sessions list.", e);
+        sess = null;
+      }
+      if (sess != null)
+      {
+        jalview.bin.Cache.log.debug("Got current sessions list: "
+                + sess.length + " entries.");
+        VamsasStMenu.removeAll();
+        for (int i = 0; i < sess.length; i++)
+        {
+          JMenuItem sessit = new JMenuItem();
+          sessit.setText(sess[i]);
+          sessit.setToolTipText("Connect to session " + sess[i]);
+          final Desktop dsktp = this;
+          final String mysesid = sess[i];
+          sessit.addActionListener(new ActionListener()
+          {
+
+            public void actionPerformed(ActionEvent e)
+            {
+              if (dsktp.v_client == null)
+              {
+                Thread rthr = new Thread(new Runnable() {
+
+                  public void run()
+                  {
+                    dsktp.v_client = new VamsasApplication(dsktp, mysesid);
+                    dsktp.setupVamsasConnectedGui();
+                    dsktp.v_client.initial_update();
+                  }
+                  
+                });
+                rthr.start();
+              }
+            };
+          });
+          VamsasStMenu.add(sessit);
+        }
+        // don't show an empty menu.
+        VamsasStMenu.setVisible(sess.length>0);
+        
+      }
+      else
+      {
+        jalview.bin.Cache.log.debug("No current vamsas sessions.");
+        VamsasStMenu.removeAll();
+        VamsasStMenu.setVisible(false);
+      }
+    } else {
+      // Not interested in the content. Just hide ourselves.
+      VamsasStMenu.setVisible(false);
     }
   }
+  public void vamsasSave_actionPerformed(ActionEvent e)
+  {
+    if (v_client != null)
+    {
+      JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
+            getProperty(
+                "LAST_DIRECTORY"), new String[]
+            {"vdj"}, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
+            new String[]
+            {"Vamsas Document"}, "Vamsas Document");
+
+        chooser.setFileView(new JalviewFileView());
+        chooser.setDialogTitle("Save Vamsas Document Archive");
+
+        int value = chooser.showSaveDialog(this);
 
+        if (value == JalviewFileChooser.APPROVE_OPTION)
+        {
+          java.io.File choice = chooser.getSelectedFile();
+          jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+          String warnmsg=null;
+          String warnttl=null;
+          try {
+            v_client.vclient.storeDocument(choice);
+          }
+          catch (Error ex)
+          {
+            warnttl = "Serious Problem saving Vamsas Document";
+            warnmsg = ex.toString();
+            jalview.bin.Cache.log.error("Error Whilst saving document to "+choice,ex);
+            
+          }
+          catch (Exception ex)
+          {
+            warnttl = "Problem saving Vamsas Document.";
+            warnmsg = ex.toString();
+            jalview.bin.Cache.log.warn("Exception Whilst saving document to "+choice,ex);
+            
+          }
+          if (warnmsg!=null)
+          {
+            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+
+                  warnmsg, warnttl,
+                  JOptionPane.ERROR_MESSAGE);
+          }
+        }
+    }
+  }
+  JProgressBar vamUpdate = null;
   /**
    * hide vamsas user gui bits when a vamsas document event is being handled.
    * @param b true to hide gui, false to reveal gui
@@ -989,9 +1194,18 @@ public class Desktop
   {
     jalview.bin.Cache.log.debug("Setting gui for Vamsas update " +
                                 (b ? "in progress" : "finished"));
-    vamsasLoad.setVisible(!b);
+    
+    if (vamUpdate!=null)
+    {
+      this.removeProgressPanel(vamUpdate);
+    }
+    if (b)
+    {
+      vamUpdate = this.addProgressPanel("Updating vamsas session");
+    }
+    vamsasStart.setVisible(!b);
     vamsasStop.setVisible(!b);
-
+    vamsasSave.setVisible(!b);
   }
 
   public JInternalFrame[] getAllFrames()
@@ -1008,12 +1222,18 @@ public class Desktop
   public void checkForQuestionnaire(String url)
   {
     UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
-    javax.swing.SwingUtilities.invokeLater(jvq);
+    //javax.swing.SwingUtilities.invokeLater(jvq);
+    new Thread(jvq).start();
   }
-
-  /*DISABLED
-   class  MyDesktopPane extends JDesktopPane implements Runnable
+  /**
+   * Proxy class for JDesktopPane which optionally 
+   * displays the current memory usage and highlights 
+   * the desktop area with a red bar if free memory runs low.
+   * @author AMW
+   */
+  public class  MyDesktopPane extends JDesktopPane implements Runnable
   {
+    
     boolean showMemoryUsage = false;
     Runtime runtime;
     java.text.NumberFormat df;
@@ -1034,7 +1254,10 @@ public class Desktop
         worker.start();
       }
     }
-
+    public boolean isShowMemoryUsage()
+    {
+      return showMemoryUsage;
+    }
     public void run()
     {
       df = java.text.NumberFormat.getNumberInstance();
@@ -1081,13 +1304,16 @@ public class Desktop
                      getHeight() - g.getFontMetrics().getHeight());
       }
     }
-  }*/
+
+    
+    
+  }
   protected JMenuItem groovyShell;
   public void doGroovyCheck() {
     if (jalview.bin.Cache.groovyJarsPresent())
     {
       groovyShell = new JMenuItem();
-      groovyShell.setText("Groovy Shell...");
+      groovyShell.setText("Groovy Console...");
       groovyShell.addActionListener(new ActionListener()
       {
           public void actionPerformed(ActionEvent e) {
@@ -1102,7 +1328,7 @@ public class Desktop
    * Accessor method to quickly get all the AlignmentFrames
    * loaded.
    */
-  protected AlignFrame[] getAlignframes() {
+  public static AlignFrame[] getAlignframes() {
     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
 
     if (frames == null)
@@ -1165,4 +1391,27 @@ public class Desktop
               JOptionPane.ERROR_MESSAGE);
     }
   }
+
+  /**
+   *  Progress bars managed by the IProgressIndicator method.
+   */
+  private Hashtable progressBars;
+  /* (non-Javadoc)
+   * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
+   */
+  public void setProgressBar(String message, long id)
+  {
+    if(progressBars == null)
+    {
+      progressBars = new Hashtable();
+    }
+
+    if(progressBars.get( new Long(id) )!=null)
+    {
+      JProgressBar progressPanel = (JProgressBar)progressBars.remove( new Long(id) );
+       removeProgressPanel(progressPanel);
+    } else {
+      progressBars.put(new Long(id), addProgressPanel(message));
+    }
+  }
 }