Formatting
[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.util.*;
27
28 import javax.swing.*;
29
30 /**
31  * DOCUMENT ME!
32  *
33  * @author $author$
34  * @version $Revision$
35  */
36 public class Desktop
37     extends jalview.jbgui.GDesktop implements DropTargetListener,
38     ClipboardOwner
39 {
40   /** DOCUMENT ME!! */
41   public static Desktop instance;
42   public static JDesktopPane desktop;
43   static int openFrameCount = 0;
44   static final int xOffset = 30;
45   static final int yOffset = 30;
46   public static jalview.ws.Discoverer discoverer;
47
48   public static Object[] jalviewClipboard;
49   public static boolean internalCopy = false;
50
51   static int fileLoadingCount = 0;
52
53   /**
54    * Creates a new Desktop object.
55    */
56   public Desktop()
57   {
58     instance = this;
59     doVamsasClientCheck();
60     Image image = null;
61
62     try
63     {
64       java.net.URL url = getClass().getResource("/images/logo.gif");
65
66       if (url != null)
67       {
68         image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
69
70         MediaTracker mt = new MediaTracker(this);
71         mt.addImage(image, 0);
72         mt.waitForID(0);
73         setIconImage(image);
74       }
75     }
76     catch (Exception ex)
77     {
78     }
79
80     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
81     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
82     desktop = new JDesktopPane();
83     desktop.setBackground(Color.white);
84     getContentPane().setLayout(new BorderLayout());
85     getContentPane().add(desktop, BorderLayout.CENTER);
86     desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
87
88     // This line prevents Windows Look&Feel resizing all new windows to maximum
89     // if previous window was maximised
90     desktop.setDesktopManager(new DefaultDesktopManager());
91
92     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
93     String x = jalview.bin.Cache.getProperty("SCREEN_X");
94     String y = jalview.bin.Cache.getProperty("SCREEN_Y");
95     String width = jalview.bin.Cache.getProperty("SCREEN_WIDTH");
96     String height = jalview.bin.Cache.getProperty("SCREEN_HEIGHT");
97
98     if ( (x != null) && (y != null) && (width != null) && (height != null))
99     {
100       setBounds(Integer.parseInt(x), Integer.parseInt(y),
101                 Integer.parseInt(width), Integer.parseInt(height));
102     }
103     else
104     {
105       setBounds( (int) (screenSize.width - 900) / 2,
106                 (int) (screenSize.height - 650) / 2, 900, 650);
107     }
108
109     this.addWindowListener(new WindowAdapter()
110     {
111       public void windowClosing(WindowEvent evt)
112       {
113         quit();
114       }
115     });
116
117     this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
118
119     /////////Add a splashscreen on startup
120     /////////Add a splashscreen on startup
121     JInternalFrame frame = new JInternalFrame();
122
123     SplashScreen splash = new SplashScreen(frame, image);
124     frame.setContentPane(splash);
125     frame.setLayer(JLayeredPane.PALETTE_LAYER);
126     frame.setLocation( (int) ( (getWidth() - 750) / 2),
127                       (int) ( (getHeight() - 160) / 2));
128
129     addInternalFrame(frame, "", 750, 160, false);
130
131     discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
132   }
133
134   private void doVamsasClientCheck()
135   {
136     if (jalview.bin.Cache.vamsasJarsPresent())
137     {
138       VamsasMenu.setVisible(true);
139       vamsasLoad.setVisible(true);
140     }
141
142   }
143
144   /**
145    * DOCUMENT ME!
146    *
147    * @param frame DOCUMENT ME!
148    * @param title DOCUMENT ME!
149    * @param w DOCUMENT ME!
150    * @param h DOCUMENT ME!
151    */
152   public static synchronized void addInternalFrame(final JInternalFrame frame,
153       String title, int w, int h)
154   {
155     addInternalFrame(frame, title, w, h, true);
156   }
157
158   /**
159    * DOCUMENT ME!
160    *
161    * @param frame DOCUMENT ME!
162    * @param title DOCUMENT ME!
163    * @param w DOCUMENT ME!
164    * @param h DOCUMENT ME!
165    * @param resizable DOCUMENT ME!
166    */
167   public static synchronized void addInternalFrame(final JInternalFrame frame,
168       String title, int w, int h, boolean resizable)
169   {
170
171     frame.setTitle(title);
172     if (frame.getWidth() < 1 || frame.getHeight() < 1)
173     {
174       frame.setSize(w, h);
175     }
176     // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
177     // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
178     // IF JALVIEW IS RUNNING HEADLESS
179     /////////////////////////////////////////////////
180     if (System.getProperty("java.awt.headless") != null
181         && System.getProperty("java.awt.headless").equals("true"))
182     {
183       return;
184     }
185
186     openFrameCount++;
187
188     frame.setVisible(true);
189     frame.setClosable(true);
190     frame.setResizable(resizable);
191     frame.setMaximizable(resizable);
192     frame.setIconifiable(resizable);
193     frame.setFrameIcon(null);
194
195     if (frame.getX() < 1 && frame.getY() < 1)
196     {
197       frame.setLocation(xOffset * openFrameCount,
198                         yOffset * ( (openFrameCount - 1) % 10) + yOffset);
199     }
200
201     final JMenuItem menuItem = new JMenuItem(title);
202     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
203     {
204       public void internalFrameActivated(javax.swing.event.
205                                          InternalFrameEvent evt)
206       {
207         JInternalFrame itf = desktop.getSelectedFrame();
208         if (itf != null)
209         {
210           itf.requestFocus();
211         }
212
213       }
214
215       public void internalFrameClosed(
216           javax.swing.event.InternalFrameEvent evt)
217       {
218         PaintRefresher.RemoveComponent(frame);
219         openFrameCount--;
220         windowMenu.remove(menuItem);
221         JInternalFrame itf = desktop.getSelectedFrame();
222         if (itf != null)
223         {
224           itf.requestFocus();
225         }
226       }
227       ;
228     });
229
230     menuItem.addActionListener(new ActionListener()
231     {
232       public void actionPerformed(ActionEvent e)
233       {
234         try
235         {
236           frame.setSelected(true);
237           frame.setIcon(false);
238         }
239         catch (java.beans.PropertyVetoException ex)
240         {
241
242         }
243       }
244     });
245
246     windowMenu.add(menuItem);
247
248     desktop.add(frame);
249     frame.toFront();
250     try
251     {
252       frame.setSelected(true);
253       frame.requestFocus();
254     }
255     catch (java.beans.PropertyVetoException ve)
256     {}
257   }
258
259   public void lostOwnership(Clipboard clipboard, Transferable contents)
260   {
261     if (!internalCopy)
262     {
263       Desktop.jalviewClipboard = null;
264     }
265
266     internalCopy = false;
267   }
268
269   public void dragEnter(DropTargetDragEvent evt)
270   {}
271
272   public void dragExit(DropTargetEvent evt)
273   {}
274
275   public void dragOver(DropTargetDragEvent evt)
276   {}
277
278   public void dropActionChanged(DropTargetDragEvent evt)
279   {}
280
281   /**
282    * DOCUMENT ME!
283    *
284    * @param evt DOCUMENT ME!
285    */
286   public void drop(DropTargetDropEvent evt)
287   {
288     Transferable t = evt.getTransferable();
289     java.util.List files = null;
290
291     try
292     {
293       DataFlavor uriListFlavor = new DataFlavor(
294           "text/uri-list;class=java.lang.String");
295       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
296       {
297         //Works on Windows and MacOSX
298         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
299         files = (java.util.List) t.getTransferData(DataFlavor.
300             javaFileListFlavor);
301       }
302       else if (t.isDataFlavorSupported(uriListFlavor))
303       {
304         // This is used by Unix drag system
305         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
306         String data = (String) t.getTransferData(uriListFlavor);
307         files = new java.util.ArrayList(1);
308         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
309             data,
310             "\r\n");
311              st.hasMoreTokens(); )
312         {
313           String s = st.nextToken();
314           if (s.startsWith("#"))
315           {
316             // the line is a comment (as per the RFC 2483)
317             continue;
318           }
319
320           java.net.URI uri = new java.net.URI(s);
321           java.io.File file = new java.io.File(uri);
322           files.add(file);
323         }
324       }
325     }
326     catch (Exception e)
327     {}
328
329     if (files != null)
330     {
331       try
332       {
333         for (int i = 0; i < files.size(); i++)
334         {
335           String file = files.get(i).toString();
336           String protocol = FormatAdapter.FILE;
337           String format = null;
338
339           if (file.endsWith(".jar"))
340           {
341             format = "Jalview";
342
343           }
344           else
345           {
346             format = new IdentifyFile().Identify(file,
347                                                  protocol);
348           }
349
350           new FileLoader().LoadFile(file, protocol, format);
351
352         }
353       }
354       catch (Exception ex)
355       {}
356     }
357   }
358
359   /**
360    * DOCUMENT ME!
361    *
362    * @param e DOCUMENT ME!
363    */
364   public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
365   {
366     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
367         getProperty(
368             "LAST_DIRECTORY"),
369         new String[]
370         {
371         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
372         "jar"
373     },
374         new String[]
375         {
376         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
377     }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
378
379     chooser.setFileView(new JalviewFileView());
380     chooser.setDialogTitle("Open local file");
381     chooser.setToolTipText("Open");
382
383     int value = chooser.showOpenDialog(this);
384
385     if (value == JalviewFileChooser.APPROVE_OPTION)
386     {
387       String choice = chooser.getSelectedFile().getPath();
388       jalview.bin.Cache.setProperty("LAST_DIRECTORY",
389                                     chooser.getSelectedFile().getParent());
390
391       String format = null;
392       if (chooser.getSelectedFormat().equals("Jalview"))
393       {
394         format = "Jalview";
395       }
396       else
397       {
398         format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
399       }
400
401       if (viewport != null)
402       {
403         new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE, format);
404       }
405       else
406       {
407         new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
408       }
409     }
410   }
411
412   /**
413    * DOCUMENT ME!
414    *
415    * @param e DOCUMENT ME!
416    */
417   public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
418   {
419     // This construct allows us to have a wider textfield
420     // for viewing
421     JLabel label = new JLabel("Enter URL of Input File");
422     final JComboBox history = new JComboBox();
423
424     JPanel panel = new JPanel(new GridLayout(2, 1));
425     panel.add(label);
426     panel.add(history);
427     history.setPreferredSize(new Dimension(400, 20));
428     history.setEditable(true);
429     history.addItem("http://www.");
430
431     String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
432
433     StringTokenizer st;
434
435     if (historyItems != null)
436     {
437       st = new StringTokenizer(historyItems, "\t");
438
439       while (st.hasMoreTokens())
440       {
441         history.addItem(st.nextElement());
442       }
443     }
444
445     int reply = JOptionPane.showInternalConfirmDialog(desktop,
446         panel, "Input Alignment From URL",
447         JOptionPane.OK_CANCEL_OPTION);
448
449     if (reply != JOptionPane.OK_OPTION)
450     {
451       return;
452     }
453
454     String url = history.getSelectedItem().toString();
455
456     if (url.toLowerCase().endsWith(".jar"))
457     {
458       if (viewport != null)
459       {
460         new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, "Jalview");
461       }
462       else
463       {
464         new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
465       }
466     }
467     else
468     {
469       String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
470
471       if (format.equals("URL NOT FOUND"))
472       {
473         JOptionPane.showInternalMessageDialog(Desktop.desktop,
474                                               "Couldn't locate " + url,
475                                               "URL not found",
476                                               JOptionPane.WARNING_MESSAGE);
477
478         return;
479       }
480
481       if (viewport != null)
482       {
483         new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
484       }
485       else
486       {
487         new FileLoader().LoadFile(url, FormatAdapter.URL, format);
488       }
489     }
490   }
491
492   /**
493    * DOCUMENT ME!
494    *
495    * @param e DOCUMENT ME!
496    */
497   public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
498   {
499     CutAndPasteTransfer cap = new CutAndPasteTransfer();
500     cap.setForInput(viewport);
501     Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
502   }
503
504   /*
505    * Exit the program
506    */
507   public void quit()
508   {
509     jalview.bin.Cache.setProperty("SCREEN_X", getBounds().x + "");
510     jalview.bin.Cache.setProperty("SCREEN_Y", getBounds().y + "");
511     jalview.bin.Cache.setProperty("SCREEN_WIDTH", getWidth() + "");
512     jalview.bin.Cache.setProperty("SCREEN_HEIGHT", getHeight() + "");
513     System.exit(0);
514   }
515
516   /**
517    * DOCUMENT ME!
518    *
519    * @param e DOCUMENT ME!
520    */
521   public void aboutMenuItem_actionPerformed(ActionEvent e)
522   {
523     StringBuffer message = new StringBuffer("JalView version " +
524                                             jalview.bin.Cache.getProperty(
525                                                 "VERSION") +
526                                             "; last updated: " +
527                                             jalview.bin.
528                                             Cache.getDefault("BUILD_DATE",
529         "unknown"));
530
531     if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
532         jalview.bin.Cache.getProperty("VERSION")))
533     {
534       message.append("\n\n!! Jalview version "
535                      + jalview.bin.Cache.getProperty("LATEST_VERSION")
536                      +
537           " is available for download from http://www.jalview.org !!\n");
538
539     }
540
541     message.append("\nAuthors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton." +
542                    "\nCurrent development managed by Andrew Waterhouse; Barton Group, University of Dundee." +
543                    "\nFor all issues relating to Jalview, email help@jalview.org" +
544                    "\n\nIf  you use JalView, please cite:" +
545                    "\n\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"" +
546                    "\nBioinformatics,  2004 20;426-7.");
547
548     JOptionPane.showInternalMessageDialog(Desktop.desktop,
549
550                                           message.toString(), "About Jalview",
551                                           JOptionPane.INFORMATION_MESSAGE);
552   }
553
554   /**
555    * DOCUMENT ME!
556    *
557    * @param e DOCUMENT ME!
558    */
559   public void documentationMenuItem_actionPerformed(ActionEvent e)
560   {
561     try
562     {
563       ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
564       java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
565       javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
566
567       javax.help.HelpBroker hb = hs.createHelpBroker();
568       hb.setCurrentID("home");
569       hb.setDisplayed(true);
570     }
571     catch (Exception ex)
572     {}
573   }
574
575   public void closeAll_actionPerformed(ActionEvent e)
576   {
577     JInternalFrame[] frames = desktop.getAllFrames();
578     for (int i = 0; i < frames.length; i++)
579     {
580       try
581       {
582         frames[i].setClosed(true);
583       }
584       catch (java.beans.PropertyVetoException ex)
585       {}
586     }
587   }
588
589   public void raiseRelated_actionPerformed(ActionEvent e)
590   {
591     reorderAssociatedWindows(false, false);
592   }
593
594   public void minimizeAssociated_actionPerformed(ActionEvent e)
595   {
596     reorderAssociatedWindows(true, false);
597   }
598
599   void closeAssociatedWindows()
600   {
601     reorderAssociatedWindows(false, true);
602   }
603
604   void reorderAssociatedWindows(boolean minimize, boolean close)
605   {
606     JInternalFrame[] frames = desktop.getAllFrames();
607     if (frames == null || frames.length < 1)
608     {
609       return;
610     }
611
612     AlignViewport source = null, target = null;
613     if (frames[0] instanceof AlignFrame)
614     {
615       source = ( (AlignFrame) frames[0]).getCurrentView();
616     }
617     else if (frames[0] instanceof TreePanel)
618     {
619       source = ( (TreePanel) frames[0]).getViewPort();
620     }
621     else if (frames[0] instanceof PCAPanel)
622     {
623       source = ( (PCAPanel) frames[0]).av;
624     }
625     else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
626     {
627       source = ( (PairwiseAlignPanel) frames[0].getContentPane()).av;
628     }
629
630     if (source != null)
631     {
632       for (int i = 0; i < frames.length; i++)
633       {
634         target = null;
635         if (frames[i] == null)
636         {
637           continue;
638         }
639         if (frames[i] instanceof AlignFrame)
640         {
641           target = ( (AlignFrame) frames[i]).getCurrentView();
642         }
643         else if (frames[i] instanceof TreePanel)
644         {
645           target = ( (TreePanel) frames[i]).getViewPort();
646         }
647         else if (frames[i] instanceof PCAPanel)
648         {
649           target = ( (PCAPanel) frames[i]).av;
650         }
651         else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
652         {
653           target = ( (PairwiseAlignPanel) frames[i].getContentPane()).av;
654         }
655
656         if (source == target)
657         {
658           try
659           {
660             if (close)
661             {
662               frames[i].setClosed(true);
663             }
664             else
665             {
666               frames[i].setIcon(minimize);
667               if (!minimize)
668               {
669                 frames[i].toFront();
670               }
671             }
672
673           }
674           catch (java.beans.PropertyVetoException ex)
675           {}
676         }
677       }
678     }
679   }
680
681   /**
682    * DOCUMENT ME!
683    *
684    * @param e DOCUMENT ME!
685    */
686   protected void preferences_actionPerformed(ActionEvent e)
687   {
688     new Preferences();
689   }
690
691   /**
692    * DOCUMENT ME!
693    *
694    * @param e DOCUMENT ME!
695    */
696   public void saveState_actionPerformed(ActionEvent e)
697   {
698     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
699         getProperty(
700             "LAST_DIRECTORY"), new String[]
701         {"jar"},
702         new String[]
703         {"Jalview Project"}, "Jalview Project");
704
705     chooser.setFileView(new JalviewFileView());
706     chooser.setDialogTitle("Save State");
707
708     int value = chooser.showSaveDialog(this);
709
710     if (value == JalviewFileChooser.APPROVE_OPTION)
711     {
712       java.io.File choice = chooser.getSelectedFile();
713       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
714       new Jalview2XML().SaveState(choice);
715     }
716   }
717
718   /**
719    * DOCUMENT ME!
720    *
721    * @param e DOCUMENT ME!
722    */
723   public void loadState_actionPerformed(ActionEvent e)
724   {
725     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
726         getProperty(
727             "LAST_DIRECTORY"), new String[]
728         {"jar"},
729         new String[]
730         {"Jalview Project"}, "Jalview Project");
731     chooser.setFileView(new JalviewFileView());
732     chooser.setDialogTitle("Restore state");
733
734     int value = chooser.showOpenDialog(this);
735
736     if (value == JalviewFileChooser.APPROVE_OPTION)
737     {
738       String choice = chooser.getSelectedFile().getAbsolutePath();
739       jalview.bin.Cache.setProperty("LAST_DIRECTORY",
740                                     chooser.getSelectedFile().getParent());
741       new Jalview2XML().LoadJalviewAlign(choice);
742     }
743   }
744
745   /*  public void vamsasLoad_actionPerformed(ActionEvent e)
746     {
747       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
748           getProperty("LAST_DIRECTORY"));
749
750       chooser.setFileView(new JalviewFileView());
751       chooser.setDialogTitle("Load Vamsas file");
752       chooser.setToolTipText("Import");
753
754       int value = chooser.showOpenDialog(this);
755
756       if (value == JalviewFileChooser.APPROVE_OPTION)
757       {
758         jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(null);
759         vs.load(
760             chooser.getSelectedFile().getAbsolutePath()
761             );
762       }
763
764     }*/
765
766
767   public void inputSequence_actionPerformed(ActionEvent e)
768   {
769     new SequenceFetcher(null);
770   }
771
772   JPanel progressPanel;
773
774   public void startLoading(final String fileName)
775   {
776     if (fileLoadingCount == 0)
777     {
778       progressPanel = new JPanel(new BorderLayout());
779       JProgressBar progressBar = new JProgressBar();
780       progressBar.setIndeterminate(true);
781
782       progressPanel.add(new JLabel("Loading File: " + fileName + "   "),
783                         BorderLayout.WEST);
784
785       progressPanel.add(progressBar, BorderLayout.CENTER);
786
787       instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
788     }
789     fileLoadingCount++;
790     validate();
791   }
792
793   public void stopLoading()
794   {
795     fileLoadingCount--;
796     if (fileLoadingCount < 1)
797     {
798       if (progressPanel != null)
799       {
800         this.getContentPane().remove(progressPanel);
801         progressPanel = null;
802       }
803       fileLoadingCount = 0;
804     }
805     validate();
806   }
807
808   public static int getViewCount(String viewId)
809   {
810     int count = 0;
811     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
812     for (int t = 0; t < frames.length; t++)
813     {
814       if (frames[t] instanceof AlignFrame)
815       {
816         AlignFrame af = (AlignFrame) frames[t];
817         for (int a = 0; a < af.alignPanels.size(); a++)
818         {
819           if (viewId.equals(
820               ( (AlignmentPanel) af.alignPanels.elementAt(a)).av.
821               getSequenceSetId())
822               )
823           {
824             count++;
825           }
826         }
827       }
828     }
829
830     return count;
831   }
832
833   public void explodeViews(AlignFrame af)
834   {
835     int size = af.alignPanels.size();
836     if (size < 2)
837     {
838       return;
839     }
840
841     for (int i = 0; i < size; i++)
842     {
843       AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
844       AlignFrame newaf = new AlignFrame(ap);
845       if (ap.av.explodedPosition != null)
846       {
847         newaf.setBounds(ap.av.explodedPosition);
848       }
849
850       ap.av.gatherViewsHere = false;
851
852       addInternalFrame(newaf, af.getTitle(),
853                        AlignFrame.DEFAULT_WIDTH,
854                        AlignFrame.DEFAULT_HEIGHT);
855     }
856
857     af.alignPanels.clear();
858     af.closeMenuItem_actionPerformed(true);
859
860   }
861
862   public void gatherViews(AlignFrame source)
863   {
864     source.viewport.gatherViewsHere = true;
865     source.viewport.explodedPosition = source.getBounds();
866     JInternalFrame[] frames = desktop.getAllFrames();
867     String viewId = source.viewport.sequenceSetID;
868
869     for (int t = 0; t < frames.length; t++)
870     {
871       if (frames[t] instanceof AlignFrame && frames[t] != source)
872       {
873         AlignFrame af = (AlignFrame) frames[t];
874         boolean gatherThis = false;
875         for (int a = 0; a < af.alignPanels.size(); a++)
876         {
877           AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
878           if (viewId.equals(ap.av.getSequenceSetId()))
879           {
880             gatherThis = true;
881             ap.av.gatherViewsHere = false;
882             ap.av.explodedPosition = af.getBounds();
883             source.addAlignmentPanel(ap, false);
884           }
885         }
886
887         if (gatherThis)
888         {
889           af.alignPanels.clear();
890           af.closeMenuItem_actionPerformed(true);
891         }
892       }
893     }
894
895   }
896
897   jalview.gui.VamsasClient v_client = null;
898   public void vamsasLoad_actionPerformed(ActionEvent e)
899   {
900     if (v_client == null)
901     {
902       // Start a session.
903       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
904           getProperty("LAST_DIRECTORY"));
905
906       chooser.setFileView(new JalviewFileView());
907       chooser.setDialogTitle("Load Vamsas file");
908       chooser.setToolTipText("Import");
909
910       int value = chooser.showOpenDialog(this);
911
912       if (value == JalviewFileChooser.APPROVE_OPTION)
913       {
914         v_client = new jalview.gui.VamsasClient(this,
915                                                 chooser.getSelectedFile());
916         this.vamsasLoad.setText("Session Update");
917         this.vamsasStop.setVisible(true);
918         v_client.initial_update();
919         v_client.startWatcher();
920       }
921     }
922     else
923     {
924       // store current data in session.
925       v_client.push_update();
926     }
927   }
928
929   public void vamsasStop_actionPerformed(ActionEvent e)
930   {
931     if (v_client != null)
932     {
933       v_client.end_session();
934       v_client = null;
935       this.vamsasStop.setVisible(false);
936       this.vamsasLoad.setText("Start Vamsas Session...");
937     }
938   }
939
940   /**
941    * hide vamsas user gui bits when a vamsas document event is being handled.
942    * @param b true to hide gui, false to reveal gui
943    */
944   public void setVamsasUpdate(boolean b)
945   {
946     jalview.bin.Cache.log.debug("Setting gui for Vamsas update " +
947                                 (b ? "in progress" : "finished"));
948     vamsasLoad.setVisible(!b);
949     vamsasStop.setVisible(!b);
950
951   }
952
953   /**
954    * Checks the given url to see if it gives a response indicating that
955    * the user should be informed of a new questionnaire.
956    * @param url
957    */
958   public void checkForQuestionnaire(String url)
959   {
960     UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
961     javax.swing.SwingUtilities.invokeLater(jvq);
962   }
963
964 }