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