nullpointer bug fix on consensus thread
[jalview.git] / src / jalview / gui / Desktop.java
index 26b28e7..36fbcf9 100755 (executable)
@@ -23,9 +23,12 @@ import java.awt.*;
 import java.awt.datatransfer.*;
 import java.awt.dnd.*;
 import java.awt.event.*;
+import java.lang.reflect.Constructor;
 import java.util.*;
 
 import javax.swing.*;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
 
 /**
  * DOCUMENT ME!
@@ -39,7 +42,13 @@ public class Desktop
 {
   /** DOCUMENT ME!! */
   public static Desktop instance;
-  public static JDesktopPane desktop;
+
+  //Need to decide if the Memory Usage is to be included in
+  //Next release or not.
+ // public static MyDesktopPane desktop;
+   public static JDesktopPane desktop;
+
+
   static int openFrameCount = 0;
   static final int xOffset = 30;
   static final int yOffset = 30;
@@ -57,28 +66,12 @@ public class Desktop
   {
     instance = this;
     doVamsasClientCheck();
-    Image image = null;
+    doGroovyCheck();
 
-    try
-    {
-      java.net.URL url = getClass().getResource("/images/logo.gif");
-
-      if (url != null)
-      {
-        image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
-
-        MediaTracker mt = new MediaTracker(this);
-        mt.addImage(image, 0);
-        mt.waitForID(0);
-        setIconImage(image);
-      }
-    }
-    catch (Exception ex)
-    {
-    }
 
     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
     desktop = new JDesktopPane();
     desktop.setBackground(Color.white);
     getContentPane().setLayout(new BorderLayout());
@@ -114,19 +107,24 @@ public class Desktop
       }
     });
 
+    this.addMouseListener(new MouseAdapter()
+        {
+          public void mousePressed(MouseEvent evt)
+          {
+            if(SwingUtilities.isRightMouseButton(evt))
+            {
+              showPasteMenu(evt.getX(), evt.getY());
+            }
+          }
+        });
+
+
     this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
 
     /////////Add a splashscreen on startup
     /////////Add a splashscreen on startup
-    JInternalFrame frame = new JInternalFrame();
-
-    SplashScreen splash = new SplashScreen(frame, image);
-    frame.setContentPane(splash);
-    frame.setLayer(JLayeredPane.PALETTE_LAYER);
-    frame.setLocation( (int) ( (getWidth() - 750) / 2),
-                      (int) ( (getHeight() - 160) / 2));
+    new SplashScreen();
 
-    addInternalFrame(frame, "", 750, 160, false);
 
     discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
   }
@@ -135,10 +133,77 @@ 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);
     }
+  }
+
+  void showPasteMenu(int x, int y)
+  {
+    JPopupMenu popup = new JPopupMenu();
+    JMenuItem item = new JMenuItem("Paste To New Window");
+    item.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent evt)
+      {
+        paste();
+      }
+    });
 
+    popup.add(item);
+    popup.show(this, x, y);
+  }
+
+  public void paste()
+  {
+    try
+    {
+      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
+      Transferable contents = c.getContents(this);
+
+      if (contents != null)
+      {
+        String file = (String) contents
+            .getTransferData(DataFlavor.stringFlavor);
+
+        String format = new IdentifyFile().Identify(file,
+                                                    FormatAdapter.PASTE);
+
+        new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
+
+      }
+    }
+    catch (Exception ex)
+    {
+      System.out.println("Unable to paste alignment from system clipboard:\n"
+                         + ex);
+    }
   }
 
   /**
@@ -223,6 +288,7 @@ public class Desktop
         {
           itf.requestFocus();
         }
+        System.gc();
       }
       ;
     });
@@ -366,15 +432,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");
@@ -584,6 +644,8 @@ public class Desktop
       catch (java.beans.PropertyVetoException ex)
       {}
     }
+    System.out.println("ALL CLOSED");
+
   }
 
   public void raiseRelated_actionPerformed(ActionEvent e)
@@ -742,28 +804,6 @@ 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);
@@ -895,12 +935,46 @@ public class Desktop
 
   }
 
-  jalview.gui.VamsasClient v_client = null;
-  public void vamsasLoad_actionPerformed(ActionEvent e)
+  jalview.gui.VamsasApplication v_client = null;
+  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)
     {
       // Start a session.
+      // we just start a default session for moment.
+      /*
       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
           getProperty("LAST_DIRECTORY"));
 
@@ -912,32 +986,148 @@ public class Desktop
 
       if (value == JalviewFileChooser.APPROVE_OPTION)
       {
-        v_client = new jalview.gui.VamsasClient(this,
+        v_client = new jalview.gui.VamsasApplication(this,
                                                 chooser.getSelectedFile());
-        this.vamsasLoad.setText("Session Update");
-        this.vamsasStop.setVisible(true);
-        v_client.initial_update();
-        v_client.startWatcher();
-      }
+                                                *
+                                                */
+      v_client = new VamsasApplication(this);
+      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)
+              {
+                dsktp.v_client = new VamsasApplication(dsktp, mysesid);
+                dsktp.setupVamsasConnectedGui();
+                dsktp.v_client.initial_update();
+              }
+            };
+          });
+          VamsasStMenu.add(sessit);
+        }
+        VamsasStMenu.setVisible(true);
+      }
+      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);
+          }
+        }
+    }
+  }
   /**
    * hide vamsas user gui bits when a vamsas document event is being handled.
    * @param b true to hide gui, false to reveal gui
@@ -946,11 +1136,17 @@ public class Desktop
   {
     jalview.bin.Cache.log.debug("Setting gui for Vamsas update " +
                                 (b ? "in progress" : "finished"));
-    vamsasLoad.setVisible(!b);
+    vamsasStart.setVisible(!b);
     vamsasStop.setVisible(!b);
+    vamsasSave.setVisible(!b);
+  }
 
+  public JInternalFrame[] getAllFrames()
+  {
+    return desktop.getAllFrames();
   }
 
+
   /**
    * Checks the given url to see if it gives a response indicating that
    * the user should be informed of a new questionnaire.
@@ -962,4 +1158,158 @@ public class Desktop
     javax.swing.SwingUtilities.invokeLater(jvq);
   }
 
+  /*DISABLED
+   class  MyDesktopPane extends JDesktopPane implements Runnable
+  {
+    boolean showMemoryUsage = false;
+    Runtime runtime;
+    java.text.NumberFormat df;
+
+    float maxMemory, allocatedMemory, freeMemory, totalFreeMemory, percentUsage;
+
+    public MyDesktopPane(boolean showMemoryUsage)
+    {
+      showMemoryUsage(showMemoryUsage);
+    }
+
+    public void showMemoryUsage(boolean showMemoryUsage)
+    {
+      this.showMemoryUsage = showMemoryUsage;
+      if (showMemoryUsage)
+      {
+        Thread worker = new Thread(this);
+        worker.start();
+      }
+    }
+
+    public void run()
+    {
+      df = java.text.NumberFormat.getNumberInstance();
+      df.setMaximumFractionDigits(2);
+      runtime = Runtime.getRuntime();
+
+      while (showMemoryUsage)
+      {
+        try
+        {
+          Thread.sleep(3000);
+          maxMemory = runtime.maxMemory() / 1048576f;
+          allocatedMemory = runtime.totalMemory() / 1048576f;
+          freeMemory = runtime.freeMemory() / 1048576f;
+          totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
+
+          percentUsage = (totalFreeMemory / maxMemory) * 100;
+
+        //  if (percentUsage < 20)
+          {
+            //   border1 = BorderFactory.createMatteBorder(12, 12, 12, 12, Color.red);
+            //    instance.set.setBorder(border1);
+          }
+          repaint();
+
+        }
+        catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+      }
+    }
+
+    public void paintComponent(Graphics g)
+    {
+      if(showMemoryUsage)
+      {
+        if (percentUsage < 20)
+          g.setColor(Color.red);
+
+        g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
+                     + "MB; Max Memory: " + df.format(maxMemory)
+                     + "MB; " + df.format(percentUsage) + "%", 10,
+                     getHeight() - g.getFontMetrics().getHeight());
+      }
+    }
+  }*/
+  protected JMenuItem groovyShell;
+  public void doGroovyCheck() {
+    if (jalview.bin.Cache.groovyJarsPresent())
+    {
+      groovyShell = new JMenuItem();
+      groovyShell.setText("Groovy Shell...");
+      groovyShell.addActionListener(new ActionListener()
+      {
+          public void actionPerformed(ActionEvent e) {
+              groovyShell_actionPerformed(e);
+          }
+      });
+      toolsMenu.add(groovyShell);
+      groovyShell.setVisible(true);
+    }
+  }
+  /**
+   * Accessor method to quickly get all the AlignmentFrames
+   * loaded.
+   */
+  protected AlignFrame[] getAlignframes() {
+    JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+
+    if (frames == null)
+    {
+      return null;
+      }
+      Vector avp=new Vector();
+      try
+      {
+          //REVERSE ORDER
+          for (int i = frames.length - 1; i > -1; i--)
+          {
+              if (frames[i] instanceof AlignFrame)
+              {
+                  AlignFrame af = (AlignFrame) frames[i];
+                  avp.addElement(af);
+              }
+          }
+      }
+      catch (Exception ex)
+      {
+          ex.printStackTrace();
+      }
+      if (avp.size()==0)
+      {
+          return null;
+      }
+      AlignFrame afs[] = new AlignFrame[avp.size()];
+      for (int i=0,j=avp.size(); i<j; i++) {
+          afs[i] = (AlignFrame) avp.elementAt(i);
+      }
+      avp.clear();
+      return afs;
+  }
+
+  /**
+    * Add Groovy Support to Jalview
+    */
+  public void groovyShell_actionPerformed(ActionEvent e) {
+    // use reflection to avoid creating compilation dependency.
+    if (!jalview.bin.Cache.groovyJarsPresent())
+    {
+      throw new Error("Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
+    }
+    try {
+    Class gcClass = Desktop.class.getClassLoader().loadClass("groovy.ui.Console");
+    Constructor gccons = gcClass.getConstructor(null);
+    java.lang.reflect.Method setvar = gcClass.getMethod("setVariable", new Class[] { String.class, Object.class} );
+    java.lang.reflect.Method run = gcClass.getMethod("run", null);
+    Object gc = gccons.newInstance(null);
+    setvar.invoke(gc, new Object[] { "Jalview", this});
+    run.invoke(gc, null);
+    }
+    catch (Exception ex)
+    {
+      jalview.bin.Cache.log.error("Groovy Shell Creation failed.",ex);
+      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+
+              "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.", "Jalview Groovy Support Failed",
+              JOptionPane.ERROR_MESSAGE);
+    }
+  }
 }