added support for loading a vamsas document into a new vamsas session.
[jalview.git] / src / jalview / gui / Desktop.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import jalview.io.*;
22 import java.awt.*;
23 import java.awt.datatransfer.*;
24 import java.awt.dnd.*;
25 import java.awt.event.*;
26 import java.lang.reflect.Constructor;
27 import java.util.*;
28
29 import javax.swing.*;
30 import javax.swing.event.MenuEvent;
31 import javax.swing.event.MenuListener;
32
33 /**
34  * DOCUMENT ME!
35  *
36  * @author $author$
37  * @version $Revision$
38  */
39 public class Desktop
40     extends jalview.jbgui.GDesktop implements DropTargetListener,
41     ClipboardOwner
42 {
43   /** DOCUMENT ME!! */
44   public static Desktop instance;
45
46   //Need to decide if the Memory Usage is to be included in
47   //Next release or not.
48  // public static MyDesktopPane desktop;
49    public static JDesktopPane desktop;
50
51
52   static int openFrameCount = 0;
53   static final int xOffset = 30;
54   static final int yOffset = 30;
55   public static jalview.ws.Discoverer discoverer;
56
57   public static Object[] jalviewClipboard;
58   public static boolean internalCopy = false;
59
60   static int fileLoadingCount = 0;
61
62   /**
63    * Creates a new Desktop object.
64    */
65   public Desktop()
66   {
67     instance = this;
68     doVamsasClientCheck();
69     doGroovyCheck();
70
71
72     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
73     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
74
75     desktop = new JDesktopPane();
76     desktop.setBackground(Color.white);
77     getContentPane().setLayout(new BorderLayout());
78     getContentPane().add(desktop, BorderLayout.CENTER);
79     desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
80
81     // This line prevents Windows Look&Feel resizing all new windows to maximum
82     // if previous window was maximised
83     desktop.setDesktopManager(new DefaultDesktopManager());
84
85     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
86     String x = jalview.bin.Cache.getProperty("SCREEN_X");
87     String y = jalview.bin.Cache.getProperty("SCREEN_Y");
88     String width = jalview.bin.Cache.getProperty("SCREEN_WIDTH");
89     String height = jalview.bin.Cache.getProperty("SCREEN_HEIGHT");
90
91     if ( (x != null) && (y != null) && (width != null) && (height != null))
92     {
93       setBounds(Integer.parseInt(x), Integer.parseInt(y),
94                 Integer.parseInt(width), Integer.parseInt(height));
95     }
96     else
97     {
98       setBounds( (int) (screenSize.width - 900) / 2,
99                 (int) (screenSize.height - 650) / 2, 900, 650);
100     }
101
102     this.addWindowListener(new WindowAdapter()
103     {
104       public void windowClosing(WindowEvent evt)
105       {
106         quit();
107       }
108     });
109
110     this.addMouseListener(new MouseAdapter()
111         {
112           public void mousePressed(MouseEvent evt)
113           {
114             if(SwingUtilities.isRightMouseButton(evt))
115             {
116               showPasteMenu(evt.getX(), evt.getY());
117             }
118           }
119         });
120
121
122     this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
123
124     /////////Add a splashscreen on startup
125     /////////Add a splashscreen on startup
126     new SplashScreen();
127
128
129     discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
130   }
131
132   private void doVamsasClientCheck()
133   {
134     if (jalview.bin.Cache.vamsasJarsPresent())
135     {
136       setupVamsasDisconnectedGui();
137       VamsasMenu.setVisible(true);
138       final Desktop us = this;
139       VamsasMenu.addMenuListener(new MenuListener() {
140         // this listener remembers when the menu was first selected, and
141         // doesn't rebuild the session list until it has been cleared and
142         // reselected again.
143         boolean refresh=true;
144         public void menuCanceled(MenuEvent e)
145         {
146           refresh=true;
147         }
148
149         public void menuDeselected(MenuEvent e)
150         {
151           refresh = true;
152         }
153
154         public void menuSelected(MenuEvent e)
155         {
156           if (refresh)
157           {
158             us.buildVamsasStMenu();
159             refresh=false;
160           }
161         }
162       });
163       vamsasStart.setVisible(true);
164     }
165   }
166
167   void showPasteMenu(int x, int y)
168   {
169     JPopupMenu popup = new JPopupMenu();
170     JMenuItem item = new JMenuItem("Paste To New Window");
171     item.addActionListener(new ActionListener()
172     {
173       public void actionPerformed(ActionEvent evt)
174       {
175         paste();
176       }
177     });
178
179     popup.add(item);
180     popup.show(this, x, y);
181   }
182
183   public void paste()
184   {
185     try
186     {
187       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
188       Transferable contents = c.getContents(this);
189
190       if (contents != null)
191       {
192         String file = (String) contents
193             .getTransferData(DataFlavor.stringFlavor);
194
195         String format = new IdentifyFile().Identify(file,
196                                                     FormatAdapter.PASTE);
197
198         new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
199
200       }
201     }
202     catch (Exception ex)
203     {
204       System.out.println("Unable to paste alignment from system clipboard:\n"
205                          + ex);
206     }
207   }
208
209   /**
210    * DOCUMENT ME!
211    *
212    * @param frame DOCUMENT ME!
213    * @param title DOCUMENT ME!
214    * @param w DOCUMENT ME!
215    * @param h DOCUMENT ME!
216    */
217   public static synchronized void addInternalFrame(final JInternalFrame frame,
218       String title, int w, int h)
219   {
220     addInternalFrame(frame, title, w, h, true);
221   }
222
223   /**
224    * DOCUMENT ME!
225    *
226    * @param frame DOCUMENT ME!
227    * @param title DOCUMENT ME!
228    * @param w DOCUMENT ME!
229    * @param h DOCUMENT ME!
230    * @param resizable DOCUMENT ME!
231    */
232   public static synchronized void addInternalFrame(final JInternalFrame frame,
233       String title, int w, int h, boolean resizable)
234   {
235
236     frame.setTitle(title);
237     if (frame.getWidth() < 1 || frame.getHeight() < 1)
238     {
239       frame.setSize(w, h);
240     }
241     // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
242     // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
243     // IF JALVIEW IS RUNNING HEADLESS
244     /////////////////////////////////////////////////
245     if (System.getProperty("java.awt.headless") != null
246         && System.getProperty("java.awt.headless").equals("true"))
247     {
248       return;
249     }
250
251     openFrameCount++;
252
253     frame.setVisible(true);
254     frame.setClosable(true);
255     frame.setResizable(resizable);
256     frame.setMaximizable(resizable);
257     frame.setIconifiable(resizable);
258     frame.setFrameIcon(null);
259
260     if (frame.getX() < 1 && frame.getY() < 1)
261     {
262       frame.setLocation(xOffset * openFrameCount,
263                         yOffset * ( (openFrameCount - 1) % 10) + yOffset);
264     }
265
266     final JMenuItem menuItem = new JMenuItem(title);
267     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
268     {
269       public void internalFrameActivated(javax.swing.event.
270                                          InternalFrameEvent evt)
271       {
272         JInternalFrame itf = desktop.getSelectedFrame();
273         if (itf != null)
274         {
275           itf.requestFocus();
276         }
277
278       }
279
280       public void internalFrameClosed(
281           javax.swing.event.InternalFrameEvent evt)
282       {
283         PaintRefresher.RemoveComponent(frame);
284         openFrameCount--;
285         windowMenu.remove(menuItem);
286         JInternalFrame itf = desktop.getSelectedFrame();
287         if (itf != null)
288         {
289           itf.requestFocus();
290         }
291         System.gc();
292       }
293       ;
294     });
295
296     menuItem.addActionListener(new ActionListener()
297     {
298       public void actionPerformed(ActionEvent e)
299       {
300         try
301         {
302           frame.setSelected(true);
303           frame.setIcon(false);
304         }
305         catch (java.beans.PropertyVetoException ex)
306         {
307
308         }
309       }
310     });
311
312     windowMenu.add(menuItem);
313
314     desktop.add(frame);
315     frame.toFront();
316     try
317     {
318       frame.setSelected(true);
319       frame.requestFocus();
320     }
321     catch (java.beans.PropertyVetoException ve)
322     {}
323   }
324
325   public void lostOwnership(Clipboard clipboard, Transferable contents)
326   {
327     if (!internalCopy)
328     {
329       Desktop.jalviewClipboard = null;
330     }
331
332     internalCopy = false;
333   }
334
335   public void dragEnter(DropTargetDragEvent evt)
336   {}
337
338   public void dragExit(DropTargetEvent evt)
339   {}
340
341   public void dragOver(DropTargetDragEvent evt)
342   {}
343
344   public void dropActionChanged(DropTargetDragEvent evt)
345   {}
346
347   /**
348    * DOCUMENT ME!
349    *
350    * @param evt DOCUMENT ME!
351    */
352   public void drop(DropTargetDropEvent evt)
353   {
354     Transferable t = evt.getTransferable();
355     java.util.List files = null;
356
357     try
358     {
359       DataFlavor uriListFlavor = new DataFlavor(
360           "text/uri-list;class=java.lang.String");
361       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
362       {
363         //Works on Windows and MacOSX
364         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
365         files = (java.util.List) t.getTransferData(DataFlavor.
366             javaFileListFlavor);
367       }
368       else if (t.isDataFlavorSupported(uriListFlavor))
369       {
370         // This is used by Unix drag system
371         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
372         String data = (String) t.getTransferData(uriListFlavor);
373         files = new java.util.ArrayList(1);
374         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
375             data,
376             "\r\n");
377              st.hasMoreTokens(); )
378         {
379           String s = st.nextToken();
380           if (s.startsWith("#"))
381           {
382             // the line is a comment (as per the RFC 2483)
383             continue;
384           }
385
386           java.net.URI uri = new java.net.URI(s);
387           java.io.File file = new java.io.File(uri);
388           files.add(file);
389         }
390       }
391     }
392     catch (Exception e)
393     {}
394
395     if (files != null)
396     {
397       try
398       {
399         for (int i = 0; i < files.size(); i++)
400         {
401           String file = files.get(i).toString();
402           String protocol = FormatAdapter.FILE;
403           String format = null;
404
405           if (file.endsWith(".jar"))
406           {
407             format = "Jalview";
408
409           }
410           else
411           {
412             format = new IdentifyFile().Identify(file,
413                                                  protocol);
414           }
415
416           new FileLoader().LoadFile(file, protocol, format);
417
418         }
419       }
420       catch (Exception ex)
421       {}
422     }
423   }
424
425   /**
426    * DOCUMENT ME!
427    *
428    * @param e DOCUMENT ME!
429    */
430   public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
431   {
432     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
433         getProperty(
434             "LAST_DIRECTORY"),
435         new String[]
436         {
437         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
438         "jar"
439     },
440         new String[]
441         {
442         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
443     }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
444
445     chooser.setFileView(new JalviewFileView());
446     chooser.setDialogTitle("Open local file");
447     chooser.setToolTipText("Open");
448
449     int value = chooser.showOpenDialog(this);
450
451     if (value == JalviewFileChooser.APPROVE_OPTION)
452     {
453       String choice = chooser.getSelectedFile().getPath();
454       jalview.bin.Cache.setProperty("LAST_DIRECTORY",
455                                     chooser.getSelectedFile().getParent());
456
457       String format = null;
458       if (chooser.getSelectedFormat().equals("Jalview"))
459       {
460         format = "Jalview";
461       }
462       else
463       {
464         format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
465       }
466
467       if (viewport != null)
468       {
469         new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE, format);
470       }
471       else
472       {
473         new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
474       }
475     }
476   }
477
478   /**
479    * DOCUMENT ME!
480    *
481    * @param e DOCUMENT ME!
482    */
483   public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
484   {
485     // This construct allows us to have a wider textfield
486     // for viewing
487     JLabel label = new JLabel("Enter URL of Input File");
488     final JComboBox history = new JComboBox();
489
490     JPanel panel = new JPanel(new GridLayout(2, 1));
491     panel.add(label);
492     panel.add(history);
493     history.setPreferredSize(new Dimension(400, 20));
494     history.setEditable(true);
495     history.addItem("http://www.");
496
497     String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
498
499     StringTokenizer st;
500
501     if (historyItems != null)
502     {
503       st = new StringTokenizer(historyItems, "\t");
504
505       while (st.hasMoreTokens())
506       {
507         history.addItem(st.nextElement());
508       }
509     }
510
511     int reply = JOptionPane.showInternalConfirmDialog(desktop,
512         panel, "Input Alignment From URL",
513         JOptionPane.OK_CANCEL_OPTION);
514
515     if (reply != JOptionPane.OK_OPTION)
516     {
517       return;
518     }
519
520     String url = history.getSelectedItem().toString();
521
522     if (url.toLowerCase().endsWith(".jar"))
523     {
524       if (viewport != null)
525       {
526         new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, "Jalview");
527       }
528       else
529       {
530         new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
531       }
532     }
533     else
534     {
535       String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
536
537       if (format.equals("URL NOT FOUND"))
538       {
539         JOptionPane.showInternalMessageDialog(Desktop.desktop,
540                                               "Couldn't locate " + url,
541                                               "URL not found",
542                                               JOptionPane.WARNING_MESSAGE);
543
544         return;
545       }
546
547       if (viewport != null)
548       {
549         new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
550       }
551       else
552       {
553         new FileLoader().LoadFile(url, FormatAdapter.URL, format);
554       }
555     }
556   }
557
558   /**
559    * DOCUMENT ME!
560    *
561    * @param e DOCUMENT ME!
562    */
563   public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
564   {
565     CutAndPasteTransfer cap = new CutAndPasteTransfer();
566     cap.setForInput(viewport);
567     Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
568   }
569
570   /*
571    * Exit the program
572    */
573   public void quit()
574   {
575     jalview.bin.Cache.setProperty("SCREEN_X", getBounds().x + "");
576     jalview.bin.Cache.setProperty("SCREEN_Y", getBounds().y + "");
577     jalview.bin.Cache.setProperty("SCREEN_WIDTH", getWidth() + "");
578     jalview.bin.Cache.setProperty("SCREEN_HEIGHT", getHeight() + "");
579     System.exit(0);
580   }
581
582   /**
583    * DOCUMENT ME!
584    *
585    * @param e DOCUMENT ME!
586    */
587   public void aboutMenuItem_actionPerformed(ActionEvent e)
588   {
589     StringBuffer message = new StringBuffer("JalView version " +
590                                             jalview.bin.Cache.getProperty(
591                                                 "VERSION") +
592                                             "; last updated: " +
593                                             jalview.bin.
594                                             Cache.getDefault("BUILD_DATE",
595         "unknown"));
596
597     if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
598         jalview.bin.Cache.getProperty("VERSION")))
599     {
600       message.append("\n\n!! Jalview version "
601                      + jalview.bin.Cache.getProperty("LATEST_VERSION")
602                      +
603           " is available for download from http://www.jalview.org !!\n");
604
605     }
606
607     message.append("\nAuthors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton." +
608                    "\nCurrent development managed by Andrew Waterhouse; Barton Group, University of Dundee." +
609                    "\nFor all issues relating to Jalview, email help@jalview.org" +
610                    "\n\nIf  you use JalView, please cite:" +
611                    "\n\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"" +
612                    "\nBioinformatics,  2004 20;426-7.");
613
614     JOptionPane.showInternalMessageDialog(Desktop.desktop,
615
616                                           message.toString(), "About Jalview",
617                                           JOptionPane.INFORMATION_MESSAGE);
618   }
619
620   /**
621    * DOCUMENT ME!
622    *
623    * @param e DOCUMENT ME!
624    */
625   public void documentationMenuItem_actionPerformed(ActionEvent e)
626   {
627     try
628     {
629       ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
630       java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
631       javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
632
633       javax.help.HelpBroker hb = hs.createHelpBroker();
634       hb.setCurrentID("home");
635       hb.setDisplayed(true);
636     }
637     catch (Exception ex)
638     {}
639   }
640
641   public void closeAll_actionPerformed(ActionEvent e)
642   {
643     JInternalFrame[] frames = desktop.getAllFrames();
644     for (int i = 0; i < frames.length; i++)
645     {
646       try
647       {
648         frames[i].setClosed(true);
649       }
650       catch (java.beans.PropertyVetoException ex)
651       {}
652     }
653     System.out.println("ALL CLOSED");
654
655   }
656
657   public void raiseRelated_actionPerformed(ActionEvent e)
658   {
659     reorderAssociatedWindows(false, false);
660   }
661
662   public void minimizeAssociated_actionPerformed(ActionEvent e)
663   {
664     reorderAssociatedWindows(true, false);
665   }
666
667   void closeAssociatedWindows()
668   {
669     reorderAssociatedWindows(false, true);
670   }
671
672   void reorderAssociatedWindows(boolean minimize, boolean close)
673   {
674     JInternalFrame[] frames = desktop.getAllFrames();
675     if (frames == null || frames.length < 1)
676     {
677       return;
678     }
679
680     AlignViewport source = null, target = null;
681     if (frames[0] instanceof AlignFrame)
682     {
683       source = ( (AlignFrame) frames[0]).getCurrentView();
684     }
685     else if (frames[0] instanceof TreePanel)
686     {
687       source = ( (TreePanel) frames[0]).getViewPort();
688     }
689     else if (frames[0] instanceof PCAPanel)
690     {
691       source = ( (PCAPanel) frames[0]).av;
692     }
693     else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
694     {
695       source = ( (PairwiseAlignPanel) frames[0].getContentPane()).av;
696     }
697
698     if (source != null)
699     {
700       for (int i = 0; i < frames.length; i++)
701       {
702         target = null;
703         if (frames[i] == null)
704         {
705           continue;
706         }
707         if (frames[i] instanceof AlignFrame)
708         {
709           target = ( (AlignFrame) frames[i]).getCurrentView();
710         }
711         else if (frames[i] instanceof TreePanel)
712         {
713           target = ( (TreePanel) frames[i]).getViewPort();
714         }
715         else if (frames[i] instanceof PCAPanel)
716         {
717           target = ( (PCAPanel) frames[i]).av;
718         }
719         else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
720         {
721           target = ( (PairwiseAlignPanel) frames[i].getContentPane()).av;
722         }
723
724         if (source == target)
725         {
726           try
727           {
728             if (close)
729             {
730               frames[i].setClosed(true);
731             }
732             else
733             {
734               frames[i].setIcon(minimize);
735               if (!minimize)
736               {
737                 frames[i].toFront();
738               }
739             }
740
741           }
742           catch (java.beans.PropertyVetoException ex)
743           {}
744         }
745       }
746     }
747   }
748
749   /**
750    * DOCUMENT ME!
751    *
752    * @param e DOCUMENT ME!
753    */
754   protected void preferences_actionPerformed(ActionEvent e)
755   {
756     new Preferences();
757   }
758
759   /**
760    * DOCUMENT ME!
761    *
762    * @param e DOCUMENT ME!
763    */
764   public void saveState_actionPerformed(ActionEvent e)
765   {
766     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
767         getProperty(
768             "LAST_DIRECTORY"), new String[]
769         {"jar"},
770         new String[]
771         {"Jalview Project"}, "Jalview Project");
772
773     chooser.setFileView(new JalviewFileView());
774     chooser.setDialogTitle("Save State");
775
776     int value = chooser.showSaveDialog(this);
777
778     if (value == JalviewFileChooser.APPROVE_OPTION)
779     {
780       java.io.File choice = chooser.getSelectedFile();
781       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
782       new Jalview2XML().SaveState(choice);
783     }
784   }
785
786   /**
787    * DOCUMENT ME!
788    *
789    * @param e DOCUMENT ME!
790    */
791   public void loadState_actionPerformed(ActionEvent e)
792   {
793     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
794         getProperty(
795             "LAST_DIRECTORY"), new String[]
796         {"jar"},
797         new String[]
798         {"Jalview Project"}, "Jalview Project");
799     chooser.setFileView(new JalviewFileView());
800     chooser.setDialogTitle("Restore state");
801
802     int value = chooser.showOpenDialog(this);
803
804     if (value == JalviewFileChooser.APPROVE_OPTION)
805     {
806       String choice = chooser.getSelectedFile().getAbsolutePath();
807       jalview.bin.Cache.setProperty("LAST_DIRECTORY",
808                                     chooser.getSelectedFile().getParent());
809       new Jalview2XML().LoadJalviewAlign(choice);
810     }
811   }
812
813   public void inputSequence_actionPerformed(ActionEvent e)
814   {
815     new SequenceFetcher(null);
816   }
817
818   JPanel progressPanel;
819
820   public void startLoading(final String fileName)
821   {
822     if (fileLoadingCount == 0)
823     {
824       progressPanel = new JPanel(new BorderLayout());
825       JProgressBar progressBar = new JProgressBar();
826       progressBar.setIndeterminate(true);
827
828       progressPanel.add(new JLabel("Loading File: " + fileName + "   "),
829                         BorderLayout.WEST);
830
831       progressPanel.add(progressBar, BorderLayout.CENTER);
832
833       instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
834     }
835     fileLoadingCount++;
836     validate();
837   }
838
839   public void stopLoading()
840   {
841     fileLoadingCount--;
842     if (fileLoadingCount < 1)
843     {
844       if (progressPanel != null)
845       {
846         this.getContentPane().remove(progressPanel);
847         progressPanel = null;
848       }
849       fileLoadingCount = 0;
850     }
851     validate();
852   }
853
854   public static int getViewCount(String viewId)
855   {
856     int count = 0;
857     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
858     for (int t = 0; t < frames.length; t++)
859     {
860       if (frames[t] instanceof AlignFrame)
861       {
862         AlignFrame af = (AlignFrame) frames[t];
863         for (int a = 0; a < af.alignPanels.size(); a++)
864         {
865           if (viewId.equals(
866               ( (AlignmentPanel) af.alignPanels.elementAt(a)).av.
867               getSequenceSetId())
868               )
869           {
870             count++;
871           }
872         }
873       }
874     }
875
876     return count;
877   }
878
879   public void explodeViews(AlignFrame af)
880   {
881     int size = af.alignPanels.size();
882     if (size < 2)
883     {
884       return;
885     }
886
887     for (int i = 0; i < size; i++)
888     {
889       AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
890       AlignFrame newaf = new AlignFrame(ap);
891       if (ap.av.explodedPosition != null &&
892           !ap.av.explodedPosition.equals(af.getBounds()))
893       {
894         newaf.setBounds(ap.av.explodedPosition);
895       }
896
897       ap.av.gatherViewsHere = false;
898
899       addInternalFrame(newaf, af.getTitle(),
900                        AlignFrame.DEFAULT_WIDTH,
901                        AlignFrame.DEFAULT_HEIGHT);
902     }
903
904     af.alignPanels.clear();
905     af.closeMenuItem_actionPerformed(true);
906
907   }
908
909   public void gatherViews(AlignFrame source)
910   {
911     source.viewport.gatherViewsHere = true;
912     source.viewport.explodedPosition = source.getBounds();
913     JInternalFrame[] frames = desktop.getAllFrames();
914     String viewId = source.viewport.sequenceSetID;
915
916     for (int t = 0; t < frames.length; t++)
917     {
918       if (frames[t] instanceof AlignFrame && frames[t] != source)
919       {
920         AlignFrame af = (AlignFrame) frames[t];
921         boolean gatherThis = false;
922         for (int a = 0; a < af.alignPanels.size(); a++)
923         {
924           AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
925           if (viewId.equals(ap.av.getSequenceSetId()))
926           {
927             gatherThis = true;
928             ap.av.gatherViewsHere = false;
929             ap.av.explodedPosition = af.getBounds();
930             source.addAlignmentPanel(ap, false);
931           }
932         }
933
934         if (gatherThis)
935         {
936           af.alignPanels.clear();
937           af.closeMenuItem_actionPerformed(true);
938         }
939       }
940     }
941
942   }
943
944   jalview.gui.VamsasApplication v_client = null;
945   public void vamsasImport_actionPerformed(ActionEvent e)
946   {
947     if (v_client==null)
948     {
949       // Load and try to start a session.
950       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
951           getProperty("LAST_DIRECTORY"));
952
953       chooser.setFileView(new JalviewFileView());
954       chooser.setDialogTitle("Open a saved VAMSAS session");
955       chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
956
957       int value = chooser.showOpenDialog(this);
958
959       if (value == JalviewFileChooser.APPROVE_OPTION)
960       {
961         try {
962           v_client = new jalview.gui.VamsasApplication(this,
963                                                 chooser.getSelectedFile());
964         } catch (Exception ex)
965         {
966           jalview.bin.Cache.log.error("New vamsas session from existing session file failed:",ex);
967           return;
968         }
969         setupVamsasConnectedGui();
970         v_client.initial_update(); // TODO: thread ?
971       }
972     }else {
973       jalview.bin.Cache.log.error("Implementation error - load session from a running session is not supported.");
974     }
975   }
976
977   public void vamsasStart_actionPerformed(ActionEvent e)
978   {
979     if (v_client == null)
980     {
981       // Start a session.
982       // we just start a default session for moment.
983       /*
984       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
985           getProperty("LAST_DIRECTORY"));
986
987       chooser.setFileView(new JalviewFileView());
988       chooser.setDialogTitle("Load Vamsas file");
989       chooser.setToolTipText("Import");
990
991       int value = chooser.showOpenDialog(this);
992
993       if (value == JalviewFileChooser.APPROVE_OPTION)
994       {
995         v_client = new jalview.gui.VamsasApplication(this,
996                                                 chooser.getSelectedFile());
997                                                 *
998                                                 */
999       v_client = new VamsasApplication(this);
1000       setupVamsasConnectedGui();
1001       v_client.initial_update(); // TODO: thread ?
1002     }
1003     else
1004     {
1005       // store current data in session.
1006       v_client.push_update(); // TODO: thread
1007     }
1008   }
1009
1010   protected void setupVamsasConnectedGui()
1011   {
1012     vamsasStart.setText("Session Update");
1013     vamsasSave.setVisible(true);
1014     vamsasStop.setVisible(true);
1015     vamsasImport.setVisible(false); // Document import to existing session is not possible for vamsas-client-1.0.
1016   }
1017   protected void setupVamsasDisconnectedGui()
1018   {
1019     vamsasSave.setVisible(false);
1020     vamsasStop.setVisible(false);
1021     vamsasImport.setVisible(true);
1022     vamsasStart.setText("New Vamsas Session...");
1023   }
1024
1025   public void vamsasStop_actionPerformed(ActionEvent e)
1026   {
1027     if (v_client != null)
1028     {
1029       v_client.end_session();
1030       v_client = null;
1031       setupVamsasDisconnectedGui();
1032     }
1033   }
1034   protected void buildVamsasStMenu()
1035   {
1036     if (v_client == null)
1037     {
1038       String[] sess = null;
1039       try
1040       {
1041         sess = VamsasApplication.getSessionList();
1042       } catch (Exception e)
1043       {
1044         jalview.bin.Cache.log.warn(
1045                 "Problem getting current sessions list.", e);
1046         sess = null;
1047       }
1048       if (sess != null)
1049       {
1050         jalview.bin.Cache.log.debug("Got current sessions list: "
1051                 + sess.length + " entries.");
1052         VamsasStMenu.removeAll();
1053         for (int i = 0; i < sess.length; i++)
1054         {
1055           JMenuItem sessit = new JMenuItem();
1056           sessit.setText(sess[i]);
1057           sessit.setToolTipText("Connect to session " + sess[i]);
1058           final Desktop dsktp = this;
1059           final String mysesid = sess[i];
1060           sessit.addActionListener(new ActionListener()
1061           {
1062
1063             public void actionPerformed(ActionEvent e)
1064             {
1065               if (dsktp.v_client == null)
1066               {
1067                 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1068                 dsktp.setupVamsasConnectedGui();
1069                 dsktp.v_client.initial_update();
1070               }
1071             };
1072           });
1073           VamsasStMenu.add(sessit);
1074         }
1075         VamsasStMenu.setVisible(true);
1076       }
1077       else
1078       {
1079         jalview.bin.Cache.log.debug("No current vamsas sessions.");
1080         VamsasStMenu.removeAll();
1081         VamsasStMenu.setVisible(false);
1082       }
1083     } else {
1084       // Not interested in the content. Just hide ourselves.
1085       VamsasStMenu.setVisible(false);
1086     }
1087   }
1088   public void vamsasSave_actionPerformed(ActionEvent e)
1089   {
1090     if (v_client != null)
1091     {
1092       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1093             getProperty(
1094                 "LAST_DIRECTORY"), new String[]
1095             {"vdj"}, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1096             new String[]
1097             {"Vamsas Document"}, "Vamsas Document");
1098
1099         chooser.setFileView(new JalviewFileView());
1100         chooser.setDialogTitle("Save Vamsas Document Archive");
1101
1102         int value = chooser.showSaveDialog(this);
1103
1104         if (value == JalviewFileChooser.APPROVE_OPTION)
1105         {
1106           java.io.File choice = chooser.getSelectedFile();
1107           jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1108           String warnmsg=null;
1109           String warnttl=null;
1110           try {
1111             v_client.vclient.storeDocument(choice);
1112           }
1113           catch (Error ex)
1114           {
1115             warnttl = "Serious Problem saving Vamsas Document";
1116             warnmsg = ex.toString();
1117             jalview.bin.Cache.log.error("Error Whilst saving document to "+choice,ex);
1118             
1119           }
1120           catch (Exception ex)
1121           {
1122             warnttl = "Problem saving Vamsas Document.";
1123             warnmsg = ex.toString();
1124             jalview.bin.Cache.log.warn("Exception Whilst saving document to "+choice,ex);
1125             
1126           }
1127           if (warnmsg!=null)
1128           {
1129             JOptionPane.showInternalMessageDialog(Desktop.desktop,
1130
1131                   warnmsg, warnttl,
1132                   JOptionPane.ERROR_MESSAGE);
1133           }
1134         }
1135     }
1136   }
1137   /**
1138    * hide vamsas user gui bits when a vamsas document event is being handled.
1139    * @param b true to hide gui, false to reveal gui
1140    */
1141   public void setVamsasUpdate(boolean b)
1142   {
1143     jalview.bin.Cache.log.debug("Setting gui for Vamsas update " +
1144                                 (b ? "in progress" : "finished"));
1145     vamsasStart.setVisible(!b);
1146     vamsasStop.setVisible(!b);
1147     vamsasSave.setVisible(!b);
1148   }
1149
1150   public JInternalFrame[] getAllFrames()
1151   {
1152     return desktop.getAllFrames();
1153   }
1154
1155
1156   /**
1157    * Checks the given url to see if it gives a response indicating that
1158    * the user should be informed of a new questionnaire.
1159    * @param url
1160    */
1161   public void checkForQuestionnaire(String url)
1162   {
1163     UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1164     javax.swing.SwingUtilities.invokeLater(jvq);
1165   }
1166
1167   /*DISABLED
1168    class  MyDesktopPane extends JDesktopPane implements Runnable
1169   {
1170     boolean showMemoryUsage = false;
1171     Runtime runtime;
1172     java.text.NumberFormat df;
1173
1174     float maxMemory, allocatedMemory, freeMemory, totalFreeMemory, percentUsage;
1175
1176     public MyDesktopPane(boolean showMemoryUsage)
1177     {
1178       showMemoryUsage(showMemoryUsage);
1179     }
1180
1181     public void showMemoryUsage(boolean showMemoryUsage)
1182     {
1183       this.showMemoryUsage = showMemoryUsage;
1184       if (showMemoryUsage)
1185       {
1186         Thread worker = new Thread(this);
1187         worker.start();
1188       }
1189     }
1190
1191     public void run()
1192     {
1193       df = java.text.NumberFormat.getNumberInstance();
1194       df.setMaximumFractionDigits(2);
1195       runtime = Runtime.getRuntime();
1196
1197       while (showMemoryUsage)
1198       {
1199         try
1200         {
1201           Thread.sleep(3000);
1202           maxMemory = runtime.maxMemory() / 1048576f;
1203           allocatedMemory = runtime.totalMemory() / 1048576f;
1204           freeMemory = runtime.freeMemory() / 1048576f;
1205           totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
1206
1207           percentUsage = (totalFreeMemory / maxMemory) * 100;
1208
1209         //  if (percentUsage < 20)
1210           {
1211             //   border1 = BorderFactory.createMatteBorder(12, 12, 12, 12, Color.red);
1212             //    instance.set.setBorder(border1);
1213           }
1214           repaint();
1215
1216         }
1217         catch (Exception ex)
1218         {
1219           ex.printStackTrace();
1220         }
1221       }
1222     }
1223
1224     public void paintComponent(Graphics g)
1225     {
1226       if(showMemoryUsage)
1227       {
1228         if (percentUsage < 20)
1229           g.setColor(Color.red);
1230
1231         g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
1232                      + "MB; Max Memory: " + df.format(maxMemory)
1233                      + "MB; " + df.format(percentUsage) + "%", 10,
1234                      getHeight() - g.getFontMetrics().getHeight());
1235       }
1236     }
1237   }*/
1238   protected JMenuItem groovyShell;
1239   public void doGroovyCheck() {
1240     if (jalview.bin.Cache.groovyJarsPresent())
1241     {
1242       groovyShell = new JMenuItem();
1243       groovyShell.setText("Groovy Shell...");
1244       groovyShell.addActionListener(new ActionListener()
1245       {
1246           public void actionPerformed(ActionEvent e) {
1247               groovyShell_actionPerformed(e);
1248           }
1249       });
1250       toolsMenu.add(groovyShell);
1251       groovyShell.setVisible(true);
1252     }
1253   }
1254   /**
1255    * Accessor method to quickly get all the AlignmentFrames
1256    * loaded.
1257    */
1258   protected AlignFrame[] getAlignframes() {
1259     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1260
1261     if (frames == null)
1262     {
1263       return null;
1264       }
1265       Vector avp=new Vector();
1266       try
1267       {
1268           //REVERSE ORDER
1269           for (int i = frames.length - 1; i > -1; i--)
1270           {
1271               if (frames[i] instanceof AlignFrame)
1272               {
1273                   AlignFrame af = (AlignFrame) frames[i];
1274                   avp.addElement(af);
1275               }
1276           }
1277       }
1278       catch (Exception ex)
1279       {
1280           ex.printStackTrace();
1281       }
1282       if (avp.size()==0)
1283       {
1284           return null;
1285       }
1286       AlignFrame afs[] = new AlignFrame[avp.size()];
1287       for (int i=0,j=avp.size(); i<j; i++) {
1288           afs[i] = (AlignFrame) avp.elementAt(i);
1289       }
1290       avp.clear();
1291       return afs;
1292   }
1293
1294   /**
1295     * Add Groovy Support to Jalview
1296     */
1297   public void groovyShell_actionPerformed(ActionEvent e) {
1298     // use reflection to avoid creating compilation dependency.
1299     if (!jalview.bin.Cache.groovyJarsPresent())
1300     {
1301       throw new Error("Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
1302     }
1303     try {
1304     Class gcClass = Desktop.class.getClassLoader().loadClass("groovy.ui.Console");
1305     Constructor gccons = gcClass.getConstructor(null);
1306     java.lang.reflect.Method setvar = gcClass.getMethod("setVariable", new Class[] { String.class, Object.class} );
1307     java.lang.reflect.Method run = gcClass.getMethod("run", null);
1308     Object gc = gccons.newInstance(null);
1309     setvar.invoke(gc, new Object[] { "Jalview", this});
1310     run.invoke(gc, null);
1311     }
1312     catch (Exception ex)
1313     {
1314       jalview.bin.Cache.log.error("Groovy Shell Creation failed.",ex);
1315       JOptionPane.showInternalMessageDialog(Desktop.desktop,
1316
1317               "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.", "Jalview Groovy Support Failed",
1318               JOptionPane.ERROR_MESSAGE);
1319     }
1320   }
1321 }