translate cDNA adjusted
[jalview.git] / src / jalview / gui / AlignFrame.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Softwarechang\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import java.beans.*;\r
22 import java.io.*;\r
23 import java.util.*;\r
24 \r
25 import java.awt.*;\r
26 import java.awt.datatransfer.*;\r
27 import java.awt.event.*;\r
28 import java.awt.print.*;\r
29 import javax.swing.*;\r
30 \r
31 import jalview.analysis.*;\r
32 import jalview.datamodel.*;\r
33 import jalview.io.*;\r
34 import jalview.jbgui.*;\r
35 import jalview.schemes.*;\r
36 import jalview.ws.*;\r
37 import java.awt.dnd.*;\r
38 \r
39 \r
40 /**\r
41  * DOCUMENT ME!\r
42  *\r
43  * @author $author$\r
44  * @version $Revision$\r
45  */\r
46 public class AlignFrame\r
47     extends GAlignFrame implements ClipboardOwner, DropTargetListener\r
48 {\r
49   /** DOCUMENT ME!! */\r
50   public static final int NEW_WINDOW_WIDTH = 700;\r
51 \r
52   /** DOCUMENT ME!! */\r
53   public static final int NEW_WINDOW_HEIGHT = 500;\r
54   AlignmentPanel alignPanel;\r
55   AlignViewport viewport;\r
56 \r
57   Vector viewports = new Vector();\r
58   Vector alignPanels = new Vector();\r
59 \r
60   /** DOCUMENT ME!! */\r
61   public String currentFileFormat = null;\r
62   Stack historyList = new Stack();\r
63   Stack redoList = new Stack();\r
64   private int treeCount = 0;\r
65 \r
66 \r
67   /**\r
68    * Creates a new AlignFrame object.\r
69    *\r
70    * @param al DOCUMENT ME!\r
71    */\r
72   public AlignFrame(AlignmentI al)\r
73   {\r
74     viewport = new AlignViewport(al);\r
75     viewports.add(viewport);\r
76 \r
77     this.setDropTarget(new java.awt.dnd.DropTarget(this, this));\r
78 \r
79     if(viewport.vconsensus==null)\r
80     {\r
81       //Out of memory calculating consensus.\r
82       BLOSUM62Colour.setEnabled(false);\r
83       PIDColour.setEnabled(false);\r
84       conservationMenuItem.setEnabled(false);\r
85       modifyConservation.setEnabled(false);\r
86       abovePIDThreshold.setEnabled(false);\r
87       modifyPID.setEnabled(false);\r
88     }\r
89 \r
90     alignPanel = new AlignmentPanel(this, viewport);\r
91     alignPanels.add(alignPanel);\r
92 \r
93     String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT", "No sort");\r
94 \r
95     if(sortby.equals("Id"))\r
96       sortIDMenuItem_actionPerformed(null);\r
97     else if(sortby.equals("Pairwise Identity"))\r
98       sortPairwiseMenuItem_actionPerformed(null);\r
99 \r
100    // remove(tabbedPane);\r
101     getContentPane().add(alignPanel, BorderLayout.CENTER);\r
102 \r
103 \r
104 \r
105   //  tabbedPane.add(al.isNucleotide() ? "DNA":"Protein", alignPanel);\r
106 \r
107     ///Dataset tab\r
108     /////////////////////////\r
109     if(al.getDataset()==null)\r
110     {\r
111       al.setDataset(null);\r
112     }\r
113    // AlignViewport ds = new AlignViewport(al.getDataset(), true);\r
114    // AlignmentPanel dap = new AlignmentPanel(this, ds);\r
115   //  tabbedPane.add("Dataset", dap);\r
116   //  viewports.add(ds);\r
117   //  alignPanels.add(dap);\r
118     /////////////////////////\r
119 \r
120 \r
121     viewport.addPropertyChangeListener(new PropertyChangeListener()\r
122     {\r
123      public void propertyChange(PropertyChangeEvent evt)\r
124      {\r
125        if (evt.getPropertyName().equals("alignment"))\r
126        {\r
127          alignmentChanged();\r
128        }\r
129      }\r
130    });\r
131 \r
132 \r
133   if (Desktop.desktop != null)\r
134   {\r
135     addServiceListeners();\r
136     setGUINucleotide(al.isNucleotide());\r
137   }\r
138   }\r
139 \r
140   /* Set up intrinsic listeners for dynamically generated GUI bits. */\r
141   private void addServiceListeners()\r
142   {\r
143     final java.beans.PropertyChangeListener thisListener;\r
144     // Do this once to get current state\r
145     BuildWebServiceMenu();\r
146     Desktop.discoverer.addPropertyChangeListener(\r
147         thisListener = new java.beans.PropertyChangeListener()\r
148     {\r
149       public void propertyChange(PropertyChangeEvent evt)\r
150       {\r
151         // System.out.println("Discoverer property change.");\r
152         if (evt.getPropertyName().equals("services"))\r
153         {\r
154           // System.out.println("Rebuilding web service menu");\r
155           BuildWebServiceMenu();\r
156         }\r
157       }\r
158     });\r
159     addInternalFrameListener(new javax.swing.event.\r
160                              InternalFrameAdapter()\r
161     {\r
162       public void internalFrameClosed(\r
163           javax.swing.event.InternalFrameEvent evt)\r
164       {\r
165         // System.out.println("deregistering discoverer listener");\r
166         Desktop.discoverer.removePropertyChangeListener(thisListener);\r
167         closeMenuItem_actionPerformed(null);\r
168       }\r
169       ;\r
170     });\r
171 \r
172   }\r
173 \r
174   public void setGUINucleotide(boolean nucleotide)\r
175   {\r
176     showTranslation.setVisible( nucleotide );\r
177     //sequenceFeatures.setVisible(!nucleotide );\r
178     //featureSettings.setVisible( !nucleotide );\r
179     conservationMenuItem.setVisible( !nucleotide );\r
180     modifyConservation.setVisible(   !nucleotide );\r
181 \r
182     //Remember AlignFrame always starts as protein\r
183     if(!nucleotide)\r
184     {\r
185       calculateMenu.remove(calculateMenu.getItemCount()-2);\r
186     }\r
187   }\r
188 \r
189 \r
190   /*\r
191    Added so Castor Mapping file can obtain Jalview Version\r
192   */\r
193   public String getVersion()\r
194   {\r
195     return  jalview.bin.Cache.getProperty("VERSION");\r
196   }\r
197 \r
198 \r
199   public void fetchSequence_actionPerformed(ActionEvent e)\r
200   {\r
201     new SequenceFetcher(this);\r
202   }\r
203   /**\r
204    * DOCUMENT ME!\r
205    *\r
206    * @param e DOCUMENT ME!\r
207    */\r
208   public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
209   {\r
210     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
211         getProperty(\r
212             "LAST_DIRECTORY"),\r
213         new String[]\r
214         {\r
215         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
216         "jar"\r
217     },\r
218         new String[]\r
219         {\r
220         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
221     }, currentFileFormat);\r
222 \r
223     chooser.setAcceptAllFileFilterUsed(false);\r
224     chooser.setFileView(new JalviewFileView());\r
225     chooser.setDialogTitle("Save Alignment to file");\r
226     chooser.setToolTipText("Save");\r
227 \r
228     int value = chooser.showSaveDialog(this);\r
229 \r
230     if (value == JalviewFileChooser.APPROVE_OPTION)\r
231     {\r
232         currentFileFormat = chooser.getSelectedFormat();\r
233 \r
234         if (currentFileFormat == null)\r
235         {\r
236           JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
237                                                 "You must select a file format before saving!",\r
238                                                 "File format not specified",\r
239                                                 JOptionPane.WARNING_MESSAGE);\r
240           value = chooser.showSaveDialog(this);\r
241           return;\r
242         }\r
243 \r
244       jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",\r
245                                     currentFileFormat);\r
246 \r
247       String choice = chooser.getSelectedFile().getPath();\r
248       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
249 \r
250       saveAlignment(choice, currentFileFormat);\r
251     }\r
252   }\r
253 \r
254   public boolean saveAlignment(String file, String format)\r
255   {\r
256     if (format.equalsIgnoreCase("Jalview"))\r
257     {\r
258       String shortName = title;\r
259 \r
260       if (shortName.indexOf(java.io.File.separatorChar) > -1)\r
261       {\r
262         shortName = shortName.substring(shortName.lastIndexOf(\r
263             java.io.File.separatorChar) + 1);\r
264       }\r
265 \r
266       Jalview2XML.SaveAlignment(this, file, shortName);\r
267 \r
268       // USE Jalview2XML to save this file\r
269       return true;\r
270     }\r
271     else\r
272     {\r
273       String output = new FormatAdapter().formatSequences(format,\r
274           viewport.getAlignment().\r
275           getSequences());\r
276       if (output == null)\r
277       {\r
278         return false;\r
279       }\r
280 \r
281       try\r
282       {\r
283         java.io.PrintWriter out = new java.io.PrintWriter(\r
284             new java.io.FileWriter(file));\r
285 \r
286         out.print(output);\r
287         out.close();\r
288         return true;\r
289       }\r
290       catch (Exception ex)\r
291       {\r
292         ex.printStackTrace();\r
293       }\r
294     }\r
295     return false;\r
296   }\r
297 \r
298   /**\r
299    * DOCUMENT ME!\r
300    *\r
301    * @param e DOCUMENT ME!\r
302    */\r
303   protected void outputText_actionPerformed(ActionEvent e)\r
304   {\r
305     CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
306     Desktop.addInternalFrame(cap,\r
307                              "Alignment output - " + e.getActionCommand(), 600,\r
308                              500);\r
309     cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(),\r
310                                               viewport.getAlignment().\r
311                                               getSequences()));\r
312   }\r
313 \r
314   /**\r
315    * DOCUMENT ME!\r
316    *\r
317    * @param e DOCUMENT ME!\r
318    */\r
319   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
320   {\r
321     new HTMLOutput(viewport,\r
322                    alignPanel.seqPanel.seqCanvas.getSequenceRenderer(),\r
323         alignPanel.seqPanel.seqCanvas.getFeatureRenderer());\r
324   }\r
325 \r
326   public void createImageMap(File file, String image)\r
327   {\r
328     alignPanel.makePNGImageMap(file, image);\r
329   }\r
330 \r
331   /**\r
332    * DOCUMENT ME!\r
333    *\r
334    * @param e DOCUMENT ME!\r
335    */\r
336   public void createPNG(File f)\r
337   {\r
338     alignPanel.makePNG(f);\r
339   }\r
340 \r
341   /**\r
342    * DOCUMENT ME!\r
343    *\r
344    * @param e DOCUMENT ME!\r
345    */\r
346   public void createEPS(File f)\r
347   {\r
348     alignPanel.makeEPS(f);\r
349   }\r
350 \r
351   /**\r
352    * DOCUMENT ME!\r
353    *\r
354    * @param e DOCUMENT ME!\r
355    */\r
356   public void printMenuItem_actionPerformed(ActionEvent e)\r
357   {\r
358     //Putting in a thread avoids Swing painting problems\r
359     PrintThread thread = new PrintThread();\r
360     thread.start();\r
361   }\r
362 \r
363   /**\r
364    * DOCUMENT ME!\r
365    *\r
366    * @param e DOCUMENT ME!\r
367    */\r
368   public void closeMenuItem_actionPerformed(ActionEvent e)\r
369   {\r
370     try\r
371     {\r
372       PaintRefresher.components.remove(viewport.alignment);\r
373       this.setClosed(true);\r
374     }\r
375     catch (Exception ex)\r
376     {\r
377     }\r
378   }\r
379 \r
380   /**\r
381    * DOCUMENT ME!\r
382    */\r
383   void updateEditMenuBar()\r
384   {\r
385     if (historyList.size() > 0)\r
386     {\r
387       undoMenuItem.setEnabled(true);\r
388 \r
389       HistoryItem hi = (HistoryItem) historyList.peek();\r
390       undoMenuItem.setText("Undo " + hi.getDescription());\r
391     }\r
392     else\r
393     {\r
394       undoMenuItem.setEnabled(false);\r
395       undoMenuItem.setText("Undo");\r
396     }\r
397 \r
398     if (redoList.size() > 0)\r
399     {\r
400       redoMenuItem.setEnabled(true);\r
401 \r
402       HistoryItem hi = (HistoryItem) redoList.peek();\r
403       redoMenuItem.setText("Redo " + hi.getDescription());\r
404     }\r
405     else\r
406     {\r
407       redoMenuItem.setEnabled(false);\r
408       redoMenuItem.setText("Redo");\r
409     }\r
410   }\r
411 \r
412   /**\r
413    * DOCUMENT ME!\r
414    *\r
415    * @param hi DOCUMENT ME!\r
416    */\r
417   public void addHistoryItem(HistoryItem hi)\r
418   {\r
419     historyList.push(hi);\r
420     updateEditMenuBar();\r
421   }\r
422 \r
423   /**\r
424    * DOCUMENT ME!\r
425    *\r
426    * @param e DOCUMENT ME!\r
427    */\r
428   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
429   {\r
430     HistoryItem hi = (HistoryItem) historyList.pop();\r
431     redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
432                                   HistoryItem.HIDE));\r
433     restoreHistoryItem(hi);\r
434     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
435   }\r
436 \r
437   /**\r
438    * DOCUMENT ME!\r
439    *\r
440    * @param e DOCUMENT ME!\r
441    */\r
442   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
443   {\r
444     HistoryItem hi = (HistoryItem) redoList.pop();\r
445     restoreHistoryItem(hi);\r
446     updateEditMenuBar();\r
447     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
448   }\r
449 \r
450   // used by undo and redo\r
451   void restoreHistoryItem(HistoryItem hi)\r
452   {\r
453     if (hi.getType() == HistoryItem.SORT)\r
454     {\r
455       for (int i = 0; i < hi.getSequences().size(); i++)\r
456       {\r
457         viewport.alignment.getSequences().setElementAt(hi.getSequences()\r
458             .elementAt(i),\r
459             i);\r
460       }\r
461     }\r
462     else\r
463     {\r
464       for (int i = 0; i < hi.getSequences().size(); i++)\r
465       {\r
466         SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
467 \r
468         if (restore.getLength() == 0)\r
469         {\r
470           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
471           viewport.alignment.getSequences().insertElementAt(restore,\r
472               hi.getAlignIndex(i));\r
473         }\r
474         else\r
475         {\r
476           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
477         }\r
478       }\r
479 \r
480       if (hi.getType() == HistoryItem.PASTE)\r
481       {\r
482         for (int i = viewport.alignment.getHeight() - 1;\r
483              i > (hi.getSequences().size() - 1); i--)\r
484         {\r
485           viewport.alignment.deleteSequence(i);\r
486         }\r
487       }\r
488     }\r
489 \r
490     updateEditMenuBar();\r
491 \r
492     viewport.firePropertyChange("alignment", null,\r
493                                 viewport.getAlignment().getSequences());\r
494   }\r
495 \r
496   /**\r
497    * DOCUMENT ME!\r
498    *\r
499    * @param up DOCUMENT ME!\r
500    */\r
501   public void moveSelectedSequences(boolean up)\r
502   {\r
503     SequenceGroup sg = viewport.getSelectionGroup();\r
504 \r
505     if (sg == null)\r
506     {\r
507       return;\r
508     }\r
509 \r
510     if (up)\r
511     {\r
512       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
513       {\r
514         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
515 \r
516         if (!sg.sequences.contains(seq))\r
517         {\r
518           continue;\r
519         }\r
520 \r
521         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
522 \r
523         if (sg.sequences.contains(temp))\r
524         {\r
525           continue;\r
526         }\r
527 \r
528         viewport.alignment.getSequences().setElementAt(temp, i);\r
529         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
530       }\r
531     }\r
532     else\r
533     {\r
534       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
535       {\r
536         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
537 \r
538         if (!sg.sequences.contains(seq))\r
539         {\r
540           continue;\r
541         }\r
542 \r
543         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
544 \r
545         if (sg.sequences.contains(temp))\r
546         {\r
547           continue;\r
548         }\r
549 \r
550         viewport.alignment.getSequences().setElementAt(temp, i);\r
551         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
552       }\r
553     }\r
554 \r
555     alignPanel.repaint();\r
556   }\r
557 \r
558   public void lostOwnership(Clipboard clipboard, Transferable contents)\r
559   {\r
560     Desktop.jalviewClipboard = null;\r
561   }\r
562 \r
563 \r
564   /**\r
565    * DOCUMENT ME!\r
566    *\r
567    * @param e DOCUMENT ME!\r
568    */\r
569   protected void copy_actionPerformed(ActionEvent e)\r
570   {\r
571     if (viewport.getSelectionGroup() == null)\r
572     {\r
573       return;\r
574     }\r
575 \r
576     SequenceGroup sg = viewport.getSelectionGroup();\r
577 \r
578     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
579 \r
580     Hashtable orderedSeqs = new Hashtable();\r
581     SequenceI[] seqs = new SequenceI[sg.getSize()];\r
582 \r
583     for (int i = 0; i < sg.getSize(); i++)\r
584     {\r
585       SequenceI seq = sg.getSequenceAt(i);\r
586       int index = viewport.alignment.findIndex(seq);\r
587       orderedSeqs.put(index + "", seq);\r
588     }\r
589 \r
590     int index = 0, startRes, endRes;\r
591     char ch;\r
592 \r
593     for (int i = 0; i < sg.getSize(); i++)\r
594     {\r
595       SequenceI seq = null;\r
596 \r
597       while (seq == null)\r
598       {\r
599         if (orderedSeqs.containsKey(index + ""))\r
600         {\r
601           seq = (SequenceI) orderedSeqs.get(index + "");\r
602           index++;\r
603 \r
604           break;\r
605         }\r
606         else\r
607         {\r
608           index++;\r
609         }\r
610       }\r
611 \r
612       //FIND START RES\r
613       //Returns residue following index if gap\r
614       startRes = seq.findPosition(sg.getStartRes());\r
615 \r
616       //FIND END RES\r
617       //Need to find the residue preceeding index if gap\r
618       endRes = 0;\r
619 \r
620       for (int j = 0; j < sg.getEndRes() + 1 && j < seq.getLength(); j++)\r
621       {\r
622         ch = seq.getCharAt(j);\r
623         if (!jalview.util.Comparison.isGap( (ch)))\r
624         {\r
625           endRes++;\r
626         }\r
627       }\r
628 \r
629       if (endRes > 0)\r
630       {\r
631         endRes += seq.getStart() - 1;\r
632       }\r
633 \r
634       seqs[i] = new Sequence(seq.getName(),\r
635                              seq.getSequence(sg.getStartRes(), sg.getEndRes() + 1),\r
636                              startRes,\r
637                              endRes);\r
638       seqs[i].setDescription(seq.getDescription());\r
639       seqs[i].setDBRef(seq.getDBRef());\r
640       seqs[i].setSequenceFeatures(seq.getSequenceFeatures());\r
641       seqs[i].setDatasetSequence(seq.getDatasetSequence());\r
642 \r
643     }\r
644 \r
645     FastaFile ff = new FastaFile();\r
646     ff.addJVSuffix( viewport.showJVSuffix );\r
647     c.setContents(new StringSelection( ff.print(seqs)), this);\r
648     Desktop.jalviewClipboard = new Object[]{seqs,  viewport.alignment.getDataset()};\r
649   }\r
650 \r
651   /**\r
652    * DOCUMENT ME!\r
653    *\r
654    * @param e DOCUMENT ME!\r
655    */\r
656   protected void pasteNew_actionPerformed(ActionEvent e)\r
657   {\r
658     paste(true);\r
659   }\r
660 \r
661   /**\r
662    * DOCUMENT ME!\r
663    *\r
664    * @param e DOCUMENT ME!\r
665    */\r
666   protected void pasteThis_actionPerformed(ActionEvent e)\r
667   {\r
668     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
669                                    HistoryItem.PASTE));\r
670     paste(false);\r
671   }\r
672 \r
673   /**\r
674    * DOCUMENT ME!\r
675    *\r
676    * @param newAlignment DOCUMENT ME!\r
677    */\r
678   void paste(boolean newAlignment)\r
679   {\r
680     try\r
681     {\r
682       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
683       Transferable contents = c.getContents(this);\r
684 \r
685       if (contents == null)\r
686       {\r
687         return;\r
688       }\r
689 \r
690       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
691       if(str.length()<1)\r
692         return;\r
693 \r
694       String format = IdentifyFile.Identify(str, "Paste");\r
695       SequenceI[] sequences;\r
696 \r
697      if(Desktop.jalviewClipboard!=null)\r
698      {\r
699        // The clipboard was filled from within Jalview, we must use the sequences\r
700        // And dataset from the copied alignment\r
701        sequences = (SequenceI[])Desktop.jalviewClipboard[0];\r
702      }\r
703      else\r
704      {\r
705        sequences = new FormatAdapter().readFile(str, "Paste", format);\r
706      }\r
707 \r
708       if (newAlignment)\r
709       {\r
710 \r
711         Alignment alignment = new Alignment(sequences);\r
712 \r
713         if(Desktop.jalviewClipboard!=null)\r
714            alignment.setDataset( (Alignment)Desktop.jalviewClipboard[1] );\r
715         else\r
716            alignment.setDataset( null );\r
717 \r
718 \r
719         AlignFrame af = new AlignFrame(alignment);\r
720         String newtitle = new String("Copied sequences");\r
721 \r
722         if (title.startsWith("Copied sequences"))\r
723         {\r
724           newtitle = title;\r
725         }\r
726         else\r
727         {\r
728           newtitle = newtitle.concat("- from " + title);\r
729         }\r
730 \r
731         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
732                                  NEW_WINDOW_HEIGHT);\r
733       }\r
734       else\r
735       {\r
736         //!newAlignment\r
737         for (int i = 0; i < sequences.length; i++)\r
738         {\r
739           Sequence newseq = new Sequence(sequences[i].getName(),\r
740               sequences[i].getSequence(), sequences[i].getStart(),\r
741               sequences[i].getEnd());\r
742           viewport.alignment.addSequence(newseq);\r
743           if(sequences[i].getDatasetSequence()==null)\r
744           {\r
745              ////////////////////////////\r
746             //Datset needs extension;\r
747             /////////////////////////////\r
748             Sequence ds = new Sequence(sequences[i].getName(),\r
749                                        AlignSeq.extractGaps("-. ", sequences[i].getSequence()),\r
750                                        sequences[i].getStart(),\r
751                                        sequences[i].getEnd());\r
752             newseq.setDatasetSequence(ds);\r
753             viewport.alignment.getDataset().addSequence(ds);\r
754           }\r
755           else\r
756           {\r
757             newseq.setDatasetSequence(sequences[i].getDatasetSequence());\r
758             if(sequences[i].getDatasetSequence().getAnnotation()!=null)\r
759             {\r
760               for(int aa=0; aa<sequences[i].getDatasetSequence().getAnnotation().length; aa++)\r
761               {\r
762                 viewport.alignment.addAnnotation(sequences[i].getDatasetSequence().getAnnotation()[aa]);\r
763               }\r
764             }\r
765           }\r
766         }\r
767         viewport.setEndSeq(viewport.alignment.getHeight());\r
768         viewport.alignment.getWidth();\r
769         viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
770       }\r
771     }\r
772     catch (Exception ex)\r
773     {\r
774       ex.printStackTrace();\r
775         System.out.println("Exception whilst pasting: "+ex);\r
776         // could be anything being pasted in here\r
777     }\r
778 \r
779 \r
780   }\r
781 \r
782   /**\r
783    * DOCUMENT ME!\r
784    *\r
785    * @param e DOCUMENT ME!\r
786    */\r
787   protected void cut_actionPerformed(ActionEvent e)\r
788   {\r
789     copy_actionPerformed(null);\r
790     delete_actionPerformed(null);\r
791   }\r
792 \r
793   /**\r
794    * DOCUMENT ME!\r
795    *\r
796    * @param e DOCUMENT ME!\r
797    */\r
798   protected void delete_actionPerformed(ActionEvent e)\r
799   {\r
800 \r
801     if (viewport.getSelectionGroup() == null)\r
802     {\r
803       return;\r
804     }\r
805 \r
806     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
807                                    HistoryItem.HIDE));\r
808 \r
809     SequenceGroup sg = viewport.getSelectionGroup();\r
810     boolean allSequences = false;\r
811     if (sg.sequences.size() == viewport.alignment.getHeight())\r
812     {\r
813       allSequences = true;\r
814     }\r
815 \r
816     for (int i = 0; i < sg.sequences.size(); i++)\r
817     {\r
818       SequenceI seq = sg.getSequenceAt(i);\r
819       int index = viewport.getAlignment().findIndex(seq);\r
820       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
821 \r
822       // If the cut affects all sequences, remove highlighted columns\r
823       if (allSequences)\r
824       {\r
825         viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
826             sg.getEndRes() + 1);\r
827       }\r
828 \r
829       if (seq.getSequence().length() < 1)\r
830       {\r
831         viewport.getAlignment().deleteSequence(seq);\r
832       }\r
833       else\r
834       {\r
835         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
836       }\r
837     }\r
838 \r
839     viewport.setSelectionGroup(null);\r
840     viewport.alignment.deleteGroup(sg);\r
841 \r
842     viewport.firePropertyChange("alignment", null,\r
843                                   viewport.getAlignment().getSequences());\r
844 \r
845 \r
846 \r
847     if (viewport.getAlignment().getHeight() < 1)\r
848     {\r
849       try\r
850       {\r
851         this.setClosed(true);\r
852       }\r
853       catch (Exception ex)\r
854       {\r
855       }\r
856     }\r
857   }\r
858 \r
859   /**\r
860    * DOCUMENT ME!\r
861    *\r
862    * @param e DOCUMENT ME!\r
863    */\r
864   protected void deleteGroups_actionPerformed(ActionEvent e)\r
865   {\r
866     viewport.alignment.deleteAllGroups();\r
867     viewport.setSelectionGroup(null);\r
868     alignPanel.repaint();\r
869   }\r
870 \r
871   /**\r
872    * DOCUMENT ME!\r
873    *\r
874    * @param e DOCUMENT ME!\r
875    */\r
876   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
877   {\r
878     SequenceGroup sg = new SequenceGroup();\r
879 \r
880     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
881          i++)\r
882     {\r
883       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
884     }\r
885 \r
886     sg.setEndRes(viewport.alignment.getWidth() - 1);\r
887     viewport.setSelectionGroup(sg);\r
888     PaintRefresher.Refresh(null, viewport.alignment);\r
889   }\r
890 \r
891   /**\r
892    * DOCUMENT ME!\r
893    *\r
894    * @param e DOCUMENT ME!\r
895    */\r
896   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
897   {\r
898     viewport.setSelectionGroup(null);\r
899     viewport.getColumnSelection().clear();\r
900     viewport.setSelectionGroup(null);\r
901     alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);\r
902     alignPanel.idPanel.idCanvas.searchResults = null;\r
903     alignPanel.annotationPanel.activeRes = null;\r
904     PaintRefresher.Refresh(null, viewport.alignment);\r
905   }\r
906 \r
907   /**\r
908    * DOCUMENT ME!\r
909    *\r
910    * @param e DOCUMENT ME!\r
911    */\r
912   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
913   {\r
914     SequenceGroup sg = viewport.getSelectionGroup();\r
915 \r
916     if (sg == null)\r
917     {\r
918       selectAllSequenceMenuItem_actionPerformed(null);\r
919 \r
920       return;\r
921     }\r
922 \r
923     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
924          i++)\r
925     {\r
926       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
927     }\r
928 \r
929     PaintRefresher.Refresh(null, viewport.alignment);\r
930   }\r
931 \r
932   /**\r
933    * DOCUMENT ME!\r
934    *\r
935    * @param e DOCUMENT ME!\r
936    */\r
937   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
938   {\r
939     ColumnSelection colSel = viewport.getColumnSelection();\r
940 \r
941     if (colSel.size() > 0)\r
942     {\r
943       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
944                                      HistoryItem.HIDE));\r
945 \r
946       int min = colSel.getMin();\r
947       viewport.getAlignment().trimLeft(min);\r
948       colSel.compensateForEdit(0, min);\r
949 \r
950       if (viewport.getSelectionGroup() != null)\r
951       {\r
952         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
953       }\r
954 \r
955       Vector groups = viewport.alignment.getGroups();\r
956 \r
957       for (int i = 0; i < groups.size(); i++)\r
958       {\r
959         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
960 \r
961         if (!sg.adjustForRemoveLeft(min))\r
962         {\r
963           viewport.alignment.deleteGroup(sg);\r
964         }\r
965       }\r
966 \r
967       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
968     }\r
969   }\r
970 \r
971   /**\r
972    * DOCUMENT ME!\r
973    *\r
974    * @param e DOCUMENT ME!\r
975    */\r
976   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
977   {\r
978     ColumnSelection colSel = viewport.getColumnSelection();\r
979 \r
980     if (colSel.size() > 0)\r
981     {\r
982       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
983                                      HistoryItem.HIDE));\r
984 \r
985       int max = colSel.getMax();\r
986       viewport.getAlignment().trimRight(max);\r
987 \r
988       if (viewport.getSelectionGroup() != null)\r
989       {\r
990         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
991       }\r
992 \r
993       Vector groups = viewport.alignment.getGroups();\r
994 \r
995       for (int i = 0; i < groups.size(); i++)\r
996       {\r
997         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
998 \r
999         if (!sg.adjustForRemoveRight(max))\r
1000         {\r
1001           viewport.alignment.deleteGroup(sg);\r
1002         }\r
1003       }\r
1004 \r
1005       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1006     }\r
1007   }\r
1008 \r
1009   /**\r
1010    * DOCUMENT ME!\r
1011    *\r
1012    * @param e DOCUMENT ME!\r
1013    */\r
1014   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
1015   {\r
1016     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
1017                                    viewport.alignment, HistoryItem.HIDE));\r
1018 \r
1019     //This is to maintain viewport position on first residue\r
1020     //of first sequence\r
1021     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
1022     int startRes = seq.findPosition(viewport.startRes);\r
1023 \r
1024     viewport.getAlignment().removeGaps();\r
1025 \r
1026     viewport.setStartRes(seq.findIndex(startRes)-1);\r
1027 \r
1028    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1029   }\r
1030 \r
1031   /**\r
1032    * DOCUMENT ME!\r
1033    *\r
1034    * @param e DOCUMENT ME!\r
1035    */\r
1036   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
1037   {\r
1038     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
1039                                    HistoryItem.HIDE));\r
1040 \r
1041     //This is to maintain viewport position on first residue\r
1042     //of first sequence\r
1043     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
1044     int startRes = seq.findPosition(viewport.startRes);\r
1045 \r
1046 \r
1047     SequenceI current;\r
1048     int jSize;\r
1049 \r
1050     Vector seqs = null;\r
1051 \r
1052     int start = 0;\r
1053     int end = viewport.alignment.getWidth();\r
1054 \r
1055     if (viewport.getSelectionGroup() != null\r
1056         && viewport.getSelectionGroup().sequences != null\r
1057         && viewport.getSelectionGroup().sequences.size() > 0)\r
1058     {\r
1059       seqs = viewport.getSelectionGroup().sequences;\r
1060       start = viewport.getSelectionGroup().getStartRes();\r
1061       end = viewport.getSelectionGroup().getEndRes()+1;\r
1062     }\r
1063     else\r
1064     {\r
1065       seqs = viewport.alignment.getSequences();\r
1066     }\r
1067 \r
1068     for (int i = 0; i < seqs.size(); i++)\r
1069     {\r
1070       current = (SequenceI) seqs.elementAt(i);\r
1071       jSize = current.getLength();\r
1072 \r
1073       // Removing a range is much quicker than removing gaps\r
1074       // one by one for long sequences\r
1075       int j = start;\r
1076       int rangeStart=-1, rangeEnd=-1;\r
1077 \r
1078       do\r
1079       {\r
1080         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
1081         {\r
1082           if(rangeStart==-1)\r
1083            {\r
1084              rangeStart = j;\r
1085              rangeEnd = j+1;\r
1086            }\r
1087            else\r
1088            {\r
1089              rangeEnd++;\r
1090            }\r
1091            j++;\r
1092         }\r
1093         else\r
1094         {\r
1095           if(rangeStart>-1)\r
1096           {\r
1097             current.deleteChars(rangeStart, rangeEnd);\r
1098             j-=rangeEnd-rangeStart;\r
1099             jSize-=rangeEnd-rangeStart;\r
1100             rangeStart = -1;\r
1101             rangeEnd = -1;\r
1102           }\r
1103           else\r
1104             j++;\r
1105         }\r
1106       }\r
1107       while (j < end && j < jSize);\r
1108       if(rangeStart>-1)\r
1109       {\r
1110        current.deleteChars(rangeStart, rangeEnd);\r
1111       }\r
1112     }\r
1113 \r
1114     viewport.setStartRes(seq.findIndex(startRes)-1);\r
1115 \r
1116     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1117   }\r
1118 \r
1119  public void alignmentChanged()\r
1120  {\r
1121    if(viewport.vconsensus!=null)\r
1122    {\r
1123      viewport.updateConsensus();\r
1124      viewport.updateConservation();\r
1125    }\r
1126    resetAllColourSchemes();\r
1127    if(alignPanel.overviewPanel!=null)\r
1128      alignPanel.overviewPanel.updateOverviewImage();\r
1129 \r
1130    viewport.alignment.adjustSequenceAnnotations();\r
1131 \r
1132    alignPanel.repaint();\r
1133  }\r
1134 \r
1135   void resetAllColourSchemes()\r
1136   {\r
1137     ColourSchemeI cs = viewport.globalColourScheme;\r
1138     if(cs!=null)\r
1139     {\r
1140       if (cs instanceof ClustalxColourScheme)\r
1141       {\r
1142         ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
1143             resetClustalX(viewport.alignment.getSequences(),\r
1144                           viewport.alignment.getWidth());\r
1145       }\r
1146 \r
1147       cs.setConsensus(viewport.vconsensus);\r
1148       if (cs.conservationApplied())\r
1149       {\r
1150         Alignment al = (Alignment) viewport.alignment;\r
1151         Conservation c = new Conservation("All",\r
1152                                           ResidueProperties.propHash, 3,\r
1153                                           al.getSequences(), 0,\r
1154                                           al.getWidth() - 1);\r
1155         c.calculate();\r
1156         c.verdict(false, viewport.ConsPercGaps);\r
1157 \r
1158         cs.setConservation(c);\r
1159       }\r
1160     }\r
1161 \r
1162     int s, sSize = viewport.alignment.getGroups().size();\r
1163     for(s=0; s<sSize; s++)\r
1164     {\r
1165       SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
1166       if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
1167       {\r
1168         ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
1169       }\r
1170       sg.recalcConservation();\r
1171     }\r
1172   }\r
1173 \r
1174   /**\r
1175    * DOCUMENT ME!\r
1176    *\r
1177    * @param e DOCUMENT ME!\r
1178    */\r
1179   public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
1180   {\r
1181     addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
1182                                    HistoryItem.HIDE));\r
1183     if (viewport.getAlignment().padGaps())\r
1184       alignmentChanged();\r
1185   }\r
1186 \r
1187   /**\r
1188    * DOCUMENT ME!\r
1189    *\r
1190    * @param e DOCUMENT ME!\r
1191    */\r
1192   public void findMenuItem_actionPerformed(ActionEvent e)\r
1193   {\r
1194     JInternalFrame frame = new JInternalFrame();\r
1195     Finder finder = new Finder(viewport, alignPanel, frame);\r
1196     frame.setContentPane(finder);\r
1197     Desktop.addInternalFrame(frame, "Find", 340, 110);\r
1198     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1199   }\r
1200 \r
1201   /**\r
1202    * DOCUMENT ME!\r
1203    *\r
1204    * @param e DOCUMENT ME!\r
1205    */\r
1206   public void font_actionPerformed(ActionEvent e)\r
1207   {\r
1208     new FontChooser(alignPanel);\r
1209   }\r
1210 \r
1211   public void smoothFont_actionPerformed(ActionEvent e)\r
1212   {\r
1213     viewport.antiAlias = smoothFont.isSelected();\r
1214     alignPanel.annotationPanel.image = null;\r
1215     alignPanel.repaint();\r
1216   }\r
1217 \r
1218 \r
1219   /**\r
1220    * DOCUMENT ME!\r
1221    *\r
1222    * @param e DOCUMENT ME!\r
1223    */\r
1224   protected void seqLimit_actionPerformed(ActionEvent e)\r
1225   {\r
1226     viewport.setShowJVSuffix(seqLimits.isSelected());\r
1227 \r
1228     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
1229     alignPanel.repaint();\r
1230   }\r
1231 \r
1232 \r
1233   /**\r
1234    * DOCUMENT ME!\r
1235    *\r
1236    * @param e DOCUMENT ME!\r
1237    */\r
1238   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
1239   {\r
1240     viewport.setColourText(colourTextMenuItem.isSelected());\r
1241     alignPanel.repaint();\r
1242   }\r
1243 \r
1244   /**\r
1245    * DOCUMENT ME!\r
1246    *\r
1247    * @param e DOCUMENT ME!\r
1248    */\r
1249   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
1250   {\r
1251     viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
1252     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
1253     scaleAbove.setVisible(wrapMenuItem.isSelected());\r
1254     scaleLeft.setVisible(wrapMenuItem.isSelected());\r
1255     scaleRight.setVisible(wrapMenuItem.isSelected());\r
1256     alignPanel.repaint();\r
1257   }\r
1258 \r
1259   /**\r
1260    * DOCUMENT ME!\r
1261    *\r
1262    * @param e DOCUMENT ME!\r
1263    */\r
1264   protected void scaleAbove_actionPerformed(ActionEvent e)\r
1265   {\r
1266     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
1267     alignPanel.repaint();\r
1268   }\r
1269 \r
1270   /**\r
1271    * DOCUMENT ME!\r
1272    *\r
1273    * @param e DOCUMENT ME!\r
1274    */\r
1275   protected void scaleLeft_actionPerformed(ActionEvent e)\r
1276   {\r
1277     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
1278     alignPanel.repaint();\r
1279   }\r
1280 \r
1281   /**\r
1282    * DOCUMENT ME!\r
1283    *\r
1284    * @param e DOCUMENT ME!\r
1285    */\r
1286   protected void scaleRight_actionPerformed(ActionEvent e)\r
1287   {\r
1288     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
1289     alignPanel.repaint();\r
1290   }\r
1291 \r
1292   /**\r
1293    * DOCUMENT ME!\r
1294    *\r
1295    * @param e DOCUMENT ME!\r
1296    */\r
1297   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
1298   {\r
1299     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
1300     alignPanel.repaint();\r
1301   }\r
1302 \r
1303   /**\r
1304    * DOCUMENT ME!\r
1305    *\r
1306    * @param e DOCUMENT ME!\r
1307    */\r
1308   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
1309   {\r
1310     viewport.setShowText(viewTextMenuItem.isSelected());\r
1311     alignPanel.repaint();\r
1312   }\r
1313 \r
1314   /**\r
1315    * DOCUMENT ME!\r
1316    *\r
1317    * @param e DOCUMENT ME!\r
1318    */\r
1319   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
1320   {\r
1321     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
1322     alignPanel.repaint();\r
1323   }\r
1324 \r
1325   public void fetchSeqFeatures_actionPerformed(ActionEvent e)\r
1326   {\r
1327     if (!viewport.alignment.isNucleotide())\r
1328     {\r
1329       new SequenceFeatureFetcher(viewport.\r
1330                                  alignment,\r
1331                                  alignPanel);\r
1332       viewport.showSequenceFeatures(true);\r
1333       showSeqFeatures.setSelected(true);\r
1334     }\r
1335   }\r
1336 \r
1337 \r
1338   public void featureSettings_actionPerformed(ActionEvent e)\r
1339   {\r
1340     new FeatureSettings(viewport, alignPanel);\r
1341   }\r
1342 \r
1343   /**\r
1344    * DOCUMENT ME!\r
1345    *\r
1346    * @param evt DOCUMENT ME!\r
1347    */\r
1348   public void showSeqFeatures_actionPerformed(ActionEvent evt)\r
1349   {\r
1350     viewport.showSequenceFeatures(showSeqFeatures.isSelected());\r
1351     alignPanel.repaint();\r
1352   }\r
1353 \r
1354   /**\r
1355    * DOCUMENT ME!\r
1356    *\r
1357    * @param e DOCUMENT ME!\r
1358    */\r
1359   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
1360   {\r
1361     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
1362     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
1363   }\r
1364 \r
1365   /**\r
1366    * DOCUMENT ME!\r
1367    *\r
1368    * @param e DOCUMENT ME!\r
1369    */\r
1370   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
1371   {\r
1372     if (alignPanel.overviewPanel != null)\r
1373     {\r
1374       return;\r
1375     }\r
1376 \r
1377     JInternalFrame frame = new JInternalFrame();\r
1378     OverviewPanel overview = new OverviewPanel(alignPanel);\r
1379     frame.setContentPane(overview);\r
1380     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
1381                              frame.getWidth(), frame.getHeight());\r
1382     frame.pack();\r
1383     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1384     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1385     {\r
1386       public void internalFrameClosed(\r
1387           javax.swing.event.InternalFrameEvent evt)\r
1388       {\r
1389         alignPanel.setOverviewPanel(null);\r
1390       }\r
1391       ;\r
1392     });\r
1393 \r
1394     alignPanel.setOverviewPanel(overview);\r
1395   }\r
1396 \r
1397   /**\r
1398    * DOCUMENT ME!\r
1399    *\r
1400    * @param e DOCUMENT ME!\r
1401    */\r
1402   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
1403   {\r
1404     changeColour(null);\r
1405   }\r
1406 \r
1407   /**\r
1408    * DOCUMENT ME!\r
1409    *\r
1410    * @param e DOCUMENT ME!\r
1411    */\r
1412   public void clustalColour_actionPerformed(ActionEvent e)\r
1413   {\r
1414     changeColour(new ClustalxColourScheme(\r
1415         viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
1416   }\r
1417 \r
1418   /**\r
1419    * DOCUMENT ME!\r
1420    *\r
1421    * @param e DOCUMENT ME!\r
1422    */\r
1423   public void zappoColour_actionPerformed(ActionEvent e)\r
1424   {\r
1425     changeColour(new ZappoColourScheme());\r
1426   }\r
1427 \r
1428   /**\r
1429    * DOCUMENT ME!\r
1430    *\r
1431    * @param e DOCUMENT ME!\r
1432    */\r
1433   public void taylorColour_actionPerformed(ActionEvent e)\r
1434   {\r
1435     changeColour(new TaylorColourScheme());\r
1436   }\r
1437 \r
1438   /**\r
1439    * DOCUMENT ME!\r
1440    *\r
1441    * @param e DOCUMENT ME!\r
1442    */\r
1443   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
1444   {\r
1445     changeColour(new HydrophobicColourScheme());\r
1446   }\r
1447 \r
1448   /**\r
1449    * DOCUMENT ME!\r
1450    *\r
1451    * @param e DOCUMENT ME!\r
1452    */\r
1453   public void helixColour_actionPerformed(ActionEvent e)\r
1454   {\r
1455     changeColour(new HelixColourScheme());\r
1456   }\r
1457 \r
1458   /**\r
1459    * DOCUMENT ME!\r
1460    *\r
1461    * @param e DOCUMENT ME!\r
1462    */\r
1463   public void strandColour_actionPerformed(ActionEvent e)\r
1464   {\r
1465     changeColour(new StrandColourScheme());\r
1466   }\r
1467 \r
1468   /**\r
1469    * DOCUMENT ME!\r
1470    *\r
1471    * @param e DOCUMENT ME!\r
1472    */\r
1473   public void turnColour_actionPerformed(ActionEvent e)\r
1474   {\r
1475     changeColour(new TurnColourScheme());\r
1476   }\r
1477 \r
1478   /**\r
1479    * DOCUMENT ME!\r
1480    *\r
1481    * @param e DOCUMENT ME!\r
1482    */\r
1483   public void buriedColour_actionPerformed(ActionEvent e)\r
1484   {\r
1485     changeColour(new BuriedColourScheme());\r
1486   }\r
1487 \r
1488   /**\r
1489    * DOCUMENT ME!\r
1490    *\r
1491    * @param e DOCUMENT ME!\r
1492    */\r
1493   public void nucleotideColour_actionPerformed(ActionEvent e)\r
1494   {\r
1495     changeColour(new NucleotideColourScheme());\r
1496   }\r
1497 \r
1498   public void annotationColour_actionPerformed(ActionEvent e)\r
1499   {\r
1500     new AnnotationColourChooser(viewport, alignPanel);\r
1501   }\r
1502 \r
1503 \r
1504   /**\r
1505    * DOCUMENT ME!\r
1506    *\r
1507    * @param e DOCUMENT ME!\r
1508    */\r
1509   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
1510   {\r
1511     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
1512   }\r
1513 \r
1514   /**\r
1515    * DOCUMENT ME!\r
1516    *\r
1517    * @param cs DOCUMENT ME!\r
1518    */\r
1519   void changeColour(ColourSchemeI cs)\r
1520   {\r
1521     int threshold = 0;\r
1522 \r
1523     if(cs!=null)\r
1524     {\r
1525       if (viewport.getAbovePIDThreshold())\r
1526       {\r
1527         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
1528                                                    "Background");\r
1529 \r
1530         cs.setThreshold(threshold,\r
1531                         viewport.getIgnoreGapsConsensus());\r
1532 \r
1533         viewport.setGlobalColourScheme(cs);\r
1534       }\r
1535       else\r
1536       {\r
1537         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1538       }\r
1539 \r
1540       if (viewport.getConservationSelected())\r
1541       {\r
1542 \r
1543         Alignment al = (Alignment) viewport.alignment;\r
1544         Conservation c = new Conservation("All",\r
1545                                           ResidueProperties.propHash, 3,\r
1546                                           al.getSequences(), 0,\r
1547                                           al.getWidth() - 1);\r
1548 \r
1549         c.calculate();\r
1550         c.verdict(false, viewport.ConsPercGaps);\r
1551 \r
1552         cs.setConservation(c);\r
1553 \r
1554         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
1555             "Background"));\r
1556       }\r
1557       else\r
1558       {\r
1559         cs.setConservation(null);\r
1560       }\r
1561 \r
1562       cs.setConsensus(viewport.vconsensus);\r
1563     }\r
1564 \r
1565     viewport.setGlobalColourScheme(cs);\r
1566 \r
1567     if (viewport.getColourAppliesToAllGroups())\r
1568     {\r
1569       Vector groups = viewport.alignment.getGroups();\r
1570 \r
1571       for (int i = 0; i < groups.size(); i++)\r
1572       {\r
1573         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
1574 \r
1575         if (cs == null)\r
1576         {\r
1577           sg.cs = null;\r
1578           continue;\r
1579         }\r
1580 \r
1581         if (cs instanceof ClustalxColourScheme)\r
1582         {\r
1583           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
1584         }\r
1585         else if (cs instanceof UserColourScheme)\r
1586         {\r
1587           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
1588         }\r
1589         else\r
1590         {\r
1591           try\r
1592           {\r
1593             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1594           }\r
1595           catch (Exception ex)\r
1596           {\r
1597           }\r
1598         }\r
1599 \r
1600         if (viewport.getAbovePIDThreshold()\r
1601             || cs instanceof PIDColourScheme\r
1602             || cs instanceof Blosum62ColourScheme)\r
1603         {\r
1604          sg.cs.setThreshold(threshold,\r
1605                 viewport.getIgnoreGapsConsensus());\r
1606 \r
1607           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1608               sg.getWidth()));\r
1609         }\r
1610         else\r
1611           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1612 \r
1613 \r
1614         if (viewport.getConservationSelected())\r
1615         {\r
1616           Conservation c = new Conservation("Group",\r
1617                                             ResidueProperties.propHash, 3,\r
1618                                             sg.sequences, 0,\r
1619                                             viewport.alignment.getWidth() - 1);\r
1620           c.calculate();\r
1621           c.verdict(false, viewport.ConsPercGaps);\r
1622           sg.cs.setConservation(c);\r
1623         }\r
1624         else\r
1625           sg.cs.setConservation(null);\r
1626       }\r
1627     }\r
1628 \r
1629     if (alignPanel.getOverviewPanel() != null)\r
1630     {\r
1631       alignPanel.getOverviewPanel().updateOverviewImage();\r
1632     }\r
1633 \r
1634     alignPanel.repaint();\r
1635   }\r
1636 \r
1637   /**\r
1638    * DOCUMENT ME!\r
1639    *\r
1640    * @param e DOCUMENT ME!\r
1641    */\r
1642   protected void modifyPID_actionPerformed(ActionEvent e)\r
1643   {\r
1644     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
1645     {\r
1646       SliderPanel.setPIDSliderSource(alignPanel,\r
1647                                      viewport.getGlobalColourScheme(),\r
1648                                      "Background");\r
1649       SliderPanel.showPIDSlider();\r
1650     }\r
1651   }\r
1652 \r
1653   /**\r
1654    * DOCUMENT ME!\r
1655    *\r
1656    * @param e DOCUMENT ME!\r
1657    */\r
1658   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1659   {\r
1660     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1661     {\r
1662       SliderPanel.setConservationSlider(alignPanel,\r
1663                                         viewport.globalColourScheme,\r
1664                                         "Background");\r
1665       SliderPanel.showConservationSlider();\r
1666     }\r
1667   }\r
1668 \r
1669   /**\r
1670    * DOCUMENT ME!\r
1671    *\r
1672    * @param e DOCUMENT ME!\r
1673    */\r
1674   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1675   {\r
1676     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1677 \r
1678     viewport.setAbovePIDThreshold(false);\r
1679     abovePIDThreshold.setSelected(false);\r
1680 \r
1681     changeColour(viewport.getGlobalColourScheme());\r
1682 \r
1683     modifyConservation_actionPerformed(null);\r
1684   }\r
1685 \r
1686   /**\r
1687    * DOCUMENT ME!\r
1688    *\r
1689    * @param e DOCUMENT ME!\r
1690    */\r
1691   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1692   {\r
1693     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1694 \r
1695     conservationMenuItem.setSelected(false);\r
1696     viewport.setConservationSelected(false);\r
1697 \r
1698     changeColour(viewport.getGlobalColourScheme());\r
1699 \r
1700     modifyPID_actionPerformed(null);\r
1701   }\r
1702 \r
1703   /**\r
1704    * DOCUMENT ME!\r
1705    *\r
1706    * @param e DOCUMENT ME!\r
1707    */\r
1708   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1709   {\r
1710     if (e.getActionCommand().equals("User Defined..."))\r
1711     {\r
1712       new UserDefinedColours(alignPanel, null);\r
1713     }\r
1714     else\r
1715     {\r
1716       UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
1717           getUserColourSchemes().get(e.getActionCommand());\r
1718 \r
1719       changeColour(udc);\r
1720     }\r
1721   }\r
1722 \r
1723   public void updateUserColourMenu()\r
1724   {\r
1725 \r
1726     Component[] menuItems = colourMenu.getMenuComponents();\r
1727     int i, iSize = menuItems.length;\r
1728     for (i = 0; i < iSize; i++)\r
1729     {\r
1730       if (menuItems[i].getName() != null &&\r
1731           menuItems[i].getName().equals("USER_DEFINED"))\r
1732       {\r
1733         colourMenu.remove(menuItems[i]);\r
1734         iSize--;\r
1735       }\r
1736     }\r
1737     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)\r
1738     {\r
1739       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
1740           getUserColourSchemes().keys();\r
1741 \r
1742       while (userColours.hasMoreElements())\r
1743       {\r
1744         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
1745             nextElement().toString());\r
1746         radioItem.setName("USER_DEFINED");\r
1747         radioItem.addMouseListener(new MouseAdapter()\r
1748             {\r
1749               public void mousePressed(MouseEvent evt)\r
1750               {\r
1751                 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
1752                 {\r
1753                   radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
1754 \r
1755                   int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
1756                       "Remove from default list?",\r
1757                       "Remove user defined colour",\r
1758                       JOptionPane.YES_NO_OPTION);\r
1759                   if(option == JOptionPane.YES_OPTION)\r
1760                   {\r
1761                     jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
1762                     colourMenu.remove(radioItem);\r
1763                   }\r
1764                   else\r
1765                     radioItem.addActionListener(new ActionListener()\r
1766                     {\r
1767                       public void actionPerformed(ActionEvent evt)\r
1768                       {\r
1769                         userDefinedColour_actionPerformed(evt);\r
1770                       }\r
1771                     });\r
1772                 }\r
1773               }\r
1774             });\r
1775         radioItem.addActionListener(new ActionListener()\r
1776         {\r
1777           public void actionPerformed(ActionEvent evt)\r
1778           {\r
1779             userDefinedColour_actionPerformed(evt);\r
1780           }\r
1781         });\r
1782 \r
1783         colourMenu.insert(radioItem, 15);\r
1784         colours.add(radioItem);\r
1785       }\r
1786     }\r
1787   }\r
1788 \r
1789   /**\r
1790    * DOCUMENT ME!\r
1791    *\r
1792    * @param e DOCUMENT ME!\r
1793    */\r
1794   public void PIDColour_actionPerformed(ActionEvent e)\r
1795   {\r
1796     changeColour(new PIDColourScheme());\r
1797   }\r
1798 \r
1799   /**\r
1800    * DOCUMENT ME!\r
1801    *\r
1802    * @param e DOCUMENT ME!\r
1803    */\r
1804   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1805   {\r
1806     changeColour(new Blosum62ColourScheme());\r
1807   }\r
1808 \r
1809   /**\r
1810    * DOCUMENT ME!\r
1811    *\r
1812    * @param e DOCUMENT ME!\r
1813    */\r
1814   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1815   {\r
1816     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1817                                    HistoryItem.SORT));\r
1818     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1819                               viewport.getAlignment().getSequenceAt(0));\r
1820     alignPanel.repaint();\r
1821   }\r
1822 \r
1823   /**\r
1824    * DOCUMENT ME!\r
1825    *\r
1826    * @param e DOCUMENT ME!\r
1827    */\r
1828   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1829   {\r
1830     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1831                                    HistoryItem.SORT));\r
1832     AlignmentSorter.sortByID(viewport.getAlignment());\r
1833     alignPanel.repaint();\r
1834   }\r
1835 \r
1836   /**\r
1837    * DOCUMENT ME!\r
1838    *\r
1839    * @param e DOCUMENT ME!\r
1840    */\r
1841   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1842   {\r
1843     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1844                                    HistoryItem.SORT));\r
1845 \r
1846     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1847     alignPanel.repaint();\r
1848   }\r
1849 \r
1850   /**\r
1851    * DOCUMENT ME!\r
1852    *\r
1853    * @param e DOCUMENT ME!\r
1854    */\r
1855   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1856   {\r
1857     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1858     JInternalFrame frame = new JInternalFrame();\r
1859     frame.setContentPane(sp);\r
1860     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1861                              100, false);\r
1862   }\r
1863 \r
1864   /**\r
1865    * DOCUMENT ME!\r
1866    *\r
1867    * @param e DOCUMENT ME!\r
1868    */\r
1869   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1870   {\r
1871     if ( (viewport.getSelectionGroup() == null) ||\r
1872         (viewport.getSelectionGroup().getSize() < 2))\r
1873     {\r
1874       JOptionPane.showInternalMessageDialog(this,\r
1875                                             "You must select at least 2 sequences.",\r
1876                                             "Invalid Selection",\r
1877                                             JOptionPane.WARNING_MESSAGE);\r
1878     }\r
1879     else\r
1880     {\r
1881       JInternalFrame frame = new JInternalFrame();\r
1882       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1883       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1884     }\r
1885   }\r
1886 \r
1887   /**\r
1888    * DOCUMENT ME!\r
1889    *\r
1890    * @param e DOCUMENT ME!\r
1891    */\r
1892   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1893   {\r
1894     if ( ( (viewport.getSelectionGroup() != null) &&\r
1895           (viewport.getSelectionGroup().getSize() < 4) &&\r
1896           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1897         (viewport.getAlignment().getHeight() < 4))\r
1898     {\r
1899       JOptionPane.showInternalMessageDialog(this,\r
1900                                             "Principal component analysis must take\n" +\r
1901                                             "at least 4 input sequences.",\r
1902                                             "Sequence selection insufficient",\r
1903                                             JOptionPane.WARNING_MESSAGE);\r
1904 \r
1905       return;\r
1906     }\r
1907 \r
1908      new PCAPanel(viewport);\r
1909   }\r
1910 \r
1911   /**\r
1912    * DOCUMENT ME!\r
1913    *\r
1914    * @param e DOCUMENT ME!\r
1915    */\r
1916   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1917   {\r
1918     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1919   }\r
1920 \r
1921   /**\r
1922    * DOCUMENT ME!\r
1923    *\r
1924    * @param e DOCUMENT ME!\r
1925    */\r
1926   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1927   {\r
1928     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1929   }\r
1930 \r
1931   /**\r
1932    * DOCUMENT ME!\r
1933    *\r
1934    * @param e DOCUMENT ME!\r
1935    */\r
1936   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1937   {\r
1938     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1939   }\r
1940 \r
1941   /**\r
1942    * DOCUMENT ME!\r
1943    *\r
1944    * @param e DOCUMENT ME!\r
1945    */\r
1946   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1947   {\r
1948     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1949   }\r
1950 \r
1951   /**\r
1952    * DOCUMENT ME!\r
1953    *\r
1954    * @param type DOCUMENT ME!\r
1955    * @param pwType DOCUMENT ME!\r
1956    * @param title DOCUMENT ME!\r
1957    */\r
1958   void NewTreePanel(String type, String pwType, String title)\r
1959   {\r
1960     final TreePanel tp;\r
1961 \r
1962     if ( (viewport.getSelectionGroup() != null) &&\r
1963         (viewport.getSelectionGroup().getSize() > 3))\r
1964     {\r
1965       int s = 0;\r
1966       SequenceGroup sg = viewport.getSelectionGroup();\r
1967 \r
1968       /* Decide if the selection is a column region */\r
1969       while (s < sg.sequences.size())\r
1970       {\r
1971         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1972             sg.getEndRes())\r
1973         {\r
1974           JOptionPane.showMessageDialog(Desktop.desktop,\r
1975                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1976                                         "Try using the Pad function in the edit menu,\n" +\r
1977                                         "or one of the multiple sequence alignment web services.",\r
1978                                         "Sequences in selection are not aligned",\r
1979                                         JOptionPane.WARNING_MESSAGE);\r
1980 \r
1981           return;\r
1982         }\r
1983       }\r
1984 \r
1985       title = title + " on region";\r
1986       tp = new TreePanel(viewport,\r
1987                          viewport.getSelectionGroup().sequences, type, pwType,\r
1988                          sg.getStartRes(), sg.getEndRes());\r
1989     }\r
1990     else\r
1991     {\r
1992       //are the sequences aligned?\r
1993       if (!viewport.alignment.isAligned())\r
1994       {\r
1995         JOptionPane.showMessageDialog(Desktop.desktop,\r
1996                                       "The sequences must be aligned before creating a tree.\n" +\r
1997                                       "Try using the Pad function in the edit menu,\n" +\r
1998                                       "or one of the multiple sequence alignment web services.",\r
1999                                       "Sequences not aligned",\r
2000                                       JOptionPane.WARNING_MESSAGE);\r
2001 \r
2002         return;\r
2003       }\r
2004 \r
2005       tp = new TreePanel(viewport,\r
2006                          viewport.getAlignment().getSequences(), type, pwType,\r
2007                          0,\r
2008                          viewport.alignment.getWidth());\r
2009     }\r
2010 \r
2011     addTreeMenuItem(tp, title);\r
2012     viewport.setCurrentTree(tp.getTree());\r
2013 \r
2014     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
2015   }\r
2016 \r
2017   /**\r
2018    * DOCUMENT ME!\r
2019    *\r
2020    * @param title DOCUMENT ME!\r
2021    * @param order DOCUMENT ME!\r
2022    */\r
2023   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
2024   {\r
2025     final JMenuItem item = new JMenuItem("by " + title);\r
2026     sort.add(item);\r
2027     item.addActionListener(new java.awt.event.ActionListener()\r
2028     {\r
2029       public void actionPerformed(ActionEvent e)\r
2030       {\r
2031         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
2032                                        HistoryItem.SORT));\r
2033 \r
2034         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
2035         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
2036         alignPanel.repaint();\r
2037       }\r
2038     });\r
2039   }\r
2040 \r
2041   /**\r
2042    * Maintain the Order by->Displayed Tree menu.\r
2043    * Creates a new menu item for a TreePanel with an appropriate\r
2044    * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added\r
2045    * to remove the menu item when the treePanel is closed, and adjust\r
2046    * the tree leaf to sequence mapping when the alignment is modified.\r
2047    * @param treePanel Displayed tree window.\r
2048    * @param title SortBy menu item title.\r
2049    */\r
2050   void addTreeMenuItem(final TreePanel treePanel, String title)\r
2051   {\r
2052     final JMenuItem item = new JMenuItem(title);\r
2053 \r
2054     treeCount++;\r
2055 \r
2056     if (treeCount == 1)\r
2057     {\r
2058       sort.add(sortByTreeMenu);\r
2059     }\r
2060 \r
2061     sortByTreeMenu.add(item);\r
2062     item.addActionListener(new java.awt.event.ActionListener()\r
2063     {\r
2064       public void actionPerformed(ActionEvent e)\r
2065       {\r
2066         addHistoryItem(new HistoryItem("Tree Sort",\r
2067                                        viewport.alignment, HistoryItem.SORT));\r
2068         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
2069                                    treePanel.getTree());\r
2070         alignPanel.repaint();\r
2071       }\r
2072     });\r
2073 \r
2074     treePanel.addInternalFrameListener(new javax.swing.event.\r
2075                                        InternalFrameAdapter()\r
2076     {\r
2077       public void internalFrameClosed(\r
2078           javax.swing.event.InternalFrameEvent evt)\r
2079       {\r
2080         treeCount--;\r
2081         sortByTreeMenu.remove(item);\r
2082 \r
2083         if (treeCount == 0)\r
2084         {\r
2085           sort.remove(sortByTreeMenu);\r
2086         }\r
2087       }\r
2088       ;\r
2089     });\r
2090   }\r
2091 \r
2092   /**\r
2093    * Work out whether the whole set of sequences\r
2094    * or just the selected set will be submitted for multiple alignment.\r
2095    *\r
2096    */\r
2097   private SequenceI[] gatherSequencesForAlignment()\r
2098   {\r
2099     // Now, check we have enough sequences\r
2100     SequenceI[] msa = null;\r
2101 \r
2102     if ( (viewport.getSelectionGroup() != null) &&\r
2103         (viewport.getSelectionGroup().getSize() > 1))\r
2104     {\r
2105       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2106       SequenceGroup seqs = viewport.getSelectionGroup();\r
2107       int sz;\r
2108       msa = new SequenceI[sz = seqs.getSize()];\r
2109 \r
2110       for (int i = 0; i < sz; i++)\r
2111       {\r
2112         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2113       }\r
2114     }\r
2115     else\r
2116     {\r
2117       Vector seqs = viewport.getAlignment().getSequences();\r
2118 \r
2119       if (seqs.size() > 1)\r
2120       {\r
2121         msa = new SequenceI[seqs.size()];\r
2122 \r
2123         for (int i = 0; i < seqs.size(); i++)\r
2124         {\r
2125           msa[i] = (SequenceI) seqs.elementAt(i);\r
2126         }\r
2127       }\r
2128     }\r
2129     return msa;\r
2130   }\r
2131 \r
2132   /**\r
2133    * Decides what is submitted to a secondary structure prediction service,\r
2134    * the currently selected sequence, or the currently selected alignment\r
2135    * (where the first sequence in the set is the one that the prediction\r
2136    * will be for).\r
2137    */\r
2138   SequenceI[] gatherSeqOrMsaForSecStrPrediction()\r
2139   {\r
2140     SequenceI seq = null;\r
2141     SequenceI[] msa = null;\r
2142 \r
2143     if ( (viewport.getSelectionGroup() != null) &&\r
2144         (viewport.getSelectionGroup().getSize() > 0))\r
2145     {\r
2146       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2147       SequenceGroup seqs = viewport.getSelectionGroup();\r
2148 \r
2149       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
2150       {\r
2151         seq = (SequenceI) seqs.getSequenceAt(0);\r
2152       }\r
2153       else\r
2154       {\r
2155         int sz;\r
2156         msa = new SequenceI[sz = seqs.getSize()];\r
2157 \r
2158         for (int i = 0; i < sz; i++)\r
2159         {\r
2160           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2161         }\r
2162       }\r
2163     }\r
2164     else\r
2165     {\r
2166       Vector seqs = viewport.getAlignment().getSequences();\r
2167 \r
2168       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
2169       {\r
2170         seq = (SequenceI) seqs.elementAt(0);\r
2171       }\r
2172       else\r
2173       {\r
2174         msa = new SequenceI[seqs.size()];\r
2175 \r
2176         for (int i = 0; i < seqs.size(); i++)\r
2177         {\r
2178           msa[i] = (SequenceI) seqs.elementAt(i);\r
2179         }\r
2180       }\r
2181     }\r
2182     if (msa != null)\r
2183     {\r
2184       return msa;\r
2185     }\r
2186     else\r
2187     {\r
2188       if (seq != null)\r
2189       {\r
2190         return new SequenceI[]\r
2191             {\r
2192             seq};\r
2193       }\r
2194     }\r
2195     return null;\r
2196   }\r
2197   /**\r
2198    * DOCUMENT ME!\r
2199    *\r
2200    * @param e DOCUMENT ME!\r
2201    */\r
2202   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
2203   {\r
2204     // Pick the tree file\r
2205     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2206         getProperty(\r
2207             "LAST_DIRECTORY"));\r
2208     chooser.setFileView(new JalviewFileView());\r
2209     chooser.setDialogTitle("Select a newick-like tree file");\r
2210     chooser.setToolTipText("Load a tree file");\r
2211 \r
2212     int value = chooser.showOpenDialog(null);\r
2213 \r
2214     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2215     {\r
2216       String choice = chooser.getSelectedFile().getPath();\r
2217       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
2218 \r
2219       try\r
2220       {\r
2221         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
2222             "File");\r
2223         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());\r
2224       }\r
2225       catch (Exception ex)\r
2226       {\r
2227         JOptionPane.showMessageDialog(Desktop.desktop,\r
2228                                       "Problem reading tree file",\r
2229                                       ex.getMessage(),\r
2230                                       JOptionPane.WARNING_MESSAGE);\r
2231         ex.printStackTrace();\r
2232       }\r
2233     }\r
2234   }\r
2235 \r
2236 \r
2237   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
2238   {\r
2239     return ShowNewickTree(nf,title,600,500,4,5);\r
2240   }\r
2241   /**\r
2242    * DOCUMENT ME!\r
2243    *\r
2244    * @param nf DOCUMENT ME!\r
2245    * @param title DOCUMENT ME!\r
2246    *\r
2247    * @return DOCUMENT ME!\r
2248    */\r
2249   public TreePanel ShowNewickTree(NewickFile nf, String title, int w,int h,int x, int y)\r
2250   {\r
2251     TreePanel tp = null;\r
2252 \r
2253     try\r
2254     {\r
2255       nf.parse();\r
2256 \r
2257       if (nf.getTree() != null)\r
2258       {\r
2259         tp = new TreePanel(viewport,\r
2260                            viewport.getAlignment().getSequences(), nf,\r
2261                            "FromFile",\r
2262                            title);\r
2263 \r
2264         tp.setSize(w,h);\r
2265 \r
2266         if(x>0 && y>0)\r
2267           tp.setLocation(x,y);\r
2268 \r
2269 \r
2270         Desktop.addInternalFrame(tp, title, w, h);\r
2271         addTreeMenuItem(tp, title);\r
2272       }\r
2273     }\r
2274     catch (Exception ex)\r
2275     {\r
2276       ex.printStackTrace();\r
2277     }\r
2278 \r
2279     return tp;\r
2280   }\r
2281 \r
2282   class PrintThread\r
2283       extends Thread\r
2284   {\r
2285     public void run()\r
2286     {\r
2287       PrinterJob printJob = PrinterJob.getPrinterJob();\r
2288       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
2289       printJob.setPrintable(alignPanel, pf);\r
2290 \r
2291       if (printJob.printDialog())\r
2292       {\r
2293         try\r
2294         {\r
2295           printJob.print();\r
2296         }\r
2297         catch (Exception PrintException)\r
2298         {\r
2299           PrintException.printStackTrace();\r
2300         }\r
2301       }\r
2302     }\r
2303   }\r
2304 \r
2305   /**\r
2306    * Generates menu items and listener event actions for web service clients\r
2307    *\r
2308    */\r
2309   public void BuildWebServiceMenu()\r
2310   {\r
2311     if ( (Discoverer.services != null)\r
2312         && (Discoverer.services.size() > 0))\r
2313     {\r
2314       Vector msaws = (Vector) Discoverer.services.get("MsaWS");\r
2315       Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");\r
2316       Vector wsmenu = new Vector();\r
2317       if (msaws != null)\r
2318       {\r
2319         // Add any Multiple Sequence Alignment Services\r
2320         final JMenu msawsmenu = new JMenu("Alignment");\r
2321         for (int i = 0, j = msaws.size(); i < j; i++)\r
2322         {\r
2323           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.\r
2324               get(i);\r
2325           final JMenuItem method = new JMenuItem(sh.getName());\r
2326           method.addActionListener(new ActionListener()\r
2327           {\r
2328             public void actionPerformed(ActionEvent e)\r
2329             {\r
2330               SequenceI[] msa = gatherSequencesForAlignment();\r
2331               new jalview.ws.MsaWSClient(sh, title, msa,\r
2332                   false, true, viewport.getAlignment().getDataset());\r
2333 \r
2334             }\r
2335 \r
2336           });\r
2337           msawsmenu.add(method);\r
2338           // Deal with services that we know accept partial alignments.\r
2339           if (sh.getName().indexOf("lustal") > -1)\r
2340           {\r
2341             // We know that ClustalWS can accept partial alignments for refinement.\r
2342             final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");\r
2343             methodR.addActionListener(new ActionListener()\r
2344             {\r
2345               public void actionPerformed(ActionEvent e)\r
2346               {\r
2347                 SequenceI[] msa = gatherSequencesForAlignment();\r
2348                 new jalview.ws.MsaWSClient(sh, title, msa,\r
2349                     true, true, viewport.getAlignment().getDataset());\r
2350 \r
2351               }\r
2352 \r
2353             });\r
2354             msawsmenu.add(methodR);\r
2355 \r
2356           }\r
2357         }\r
2358         wsmenu.add(msawsmenu);\r
2359       }\r
2360       if (secstrpr != null)\r
2361       {\r
2362         // Add any secondary structure prediction services\r
2363         final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");\r
2364         for (int i = 0, j = secstrpr.size(); i < j; i++)\r
2365         {\r
2366           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)\r
2367               secstrpr.get(i);\r
2368           final JMenuItem method = new JMenuItem(sh.getName());\r
2369           method.addActionListener(new ActionListener()\r
2370           {\r
2371             public void actionPerformed(ActionEvent e)\r
2372             {\r
2373               SequenceI[] msa = gatherSeqOrMsaForSecStrPrediction();\r
2374               if (msa.length == 1)\r
2375               {\r
2376                 // Single Sequence prediction\r
2377                 new jalview.ws.JPredClient(sh,title, msa[0]);\r
2378               }\r
2379               else\r
2380               {\r
2381                 if (msa.length > 1)\r
2382                 {\r
2383                   // Single Sequence prediction\r
2384                   jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2385                       title, msa);\r
2386                 }\r
2387               }\r
2388             }\r
2389           });\r
2390           secstrmenu.add(method);\r
2391         }\r
2392         wsmenu.add(secstrmenu);\r
2393       }\r
2394       this.webService.removeAll();\r
2395       for (int i = 0, j = wsmenu.size(); i < j; i++)\r
2396       {\r
2397         webService.add( (JMenu) wsmenu.get(i));\r
2398       }\r
2399     }\r
2400     else\r
2401     {\r
2402       this.webService.removeAll();\r
2403       this.webService.add(this.webServiceNoServices);\r
2404     }\r
2405     // TODO: add in rediscovery function\r
2406     // TODO: reduce code redundancy.\r
2407     // TODO: group services by location as well as function.\r
2408   }\r
2409 \r
2410  /* public void vamsasStore_actionPerformed(ActionEvent e)\r
2411   {\r
2412     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2413         getProperty("LAST_DIRECTORY"));\r
2414 \r
2415     chooser.setFileView(new JalviewFileView());\r
2416     chooser.setDialogTitle("Export to Vamsas file");\r
2417     chooser.setToolTipText("Export");\r
2418 \r
2419     int value = chooser.showSaveDialog(this);\r
2420 \r
2421     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2422     {\r
2423       jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(viewport);\r
2424       //vs.store(chooser.getSelectedFile().getAbsolutePath()   );\r
2425       vs.storeJalview( chooser.getSelectedFile().getAbsolutePath(), this);\r
2426     }\r
2427   }*/\r
2428 \r
2429 \r
2430 \r
2431 \r
2432 \r
2433 public void showTranslation_actionPerformed(ActionEvent e)\r
2434 {\r
2435   int s, sSize = viewport.alignment.getHeight();\r
2436   SequenceI [] newSeq = new SequenceI[sSize];\r
2437 \r
2438   int res, resSize;\r
2439   StringBuffer protein;\r
2440   String seq;\r
2441   for(s=0; s<sSize; s++)\r
2442   {\r
2443     protein = new StringBuffer();\r
2444     seq = AlignSeq.extractGaps("-. ", viewport.alignment.getSequenceAt(s).getSequence());\r
2445     resSize = seq.length();\r
2446     resSize -= resSize%3;\r
2447 \r
2448     for(res = 0; res < resSize; res+=3)\r
2449     {\r
2450       String codon = seq.substring(res, res+3);\r
2451       codon = codon.replace('U', 'T');\r
2452       String aa = ResidueProperties.codonTranslate(codon);\r
2453       if(aa==null)\r
2454         protein.append(viewport.getGapCharacter());\r
2455       else if(aa.equals("STOP"))\r
2456         protein.append("X");\r
2457       else\r
2458         protein.append( aa );\r
2459     }\r
2460     newSeq[s] = new Sequence(viewport.alignment.getSequenceAt(s).getName(), protein.toString());\r
2461   }\r
2462 \r
2463 \r
2464   AlignmentI al = new Alignment(newSeq);\r
2465   al.setDataset(null);\r
2466 \r
2467 \r
2468   ////////////////////////////////\r
2469   // Copy annotations across\r
2470   jalview.datamodel.AlignmentAnnotation[] annotations\r
2471       = viewport.alignment.getAlignmentAnnotation();\r
2472   int a, aSize;\r
2473   for (int i = 0; i < annotations.length; i++)\r
2474   {\r
2475 \r
2476     if (annotations[i].label.equals("Quality") ||\r
2477         annotations[i].label.equals("Conservation") ||\r
2478         annotations[i].label.equals("Consensus"))\r
2479     {\r
2480       continue;\r
2481     }\r
2482 \r
2483 \r
2484     aSize = viewport.alignment.getWidth()/3;\r
2485     jalview.datamodel.Annotation [] anots =\r
2486         new jalview.datamodel.Annotation[aSize];\r
2487 \r
2488     for(a=0; a<viewport.alignment.getWidth(); a++)\r
2489     {\r
2490      if( annotations[i].annotations[a]==null\r
2491       || annotations[i].annotations[a]==null)\r
2492        continue;\r
2493 \r
2494       anots[a/3] = new Annotation(\r
2495      annotations[i].annotations[a].displayCharacter,\r
2496      annotations[i].annotations[a].description,\r
2497      annotations[i].annotations[a].secondaryStructure,\r
2498      annotations[i].annotations[a].value,\r
2499      annotations[i].annotations[a].colour);\r
2500     }\r
2501 \r
2502     jalview.datamodel.AlignmentAnnotation aa\r
2503           = new jalview.datamodel.AlignmentAnnotation(annotations[i].label,\r
2504        annotations[i].description, anots );\r
2505      al.addAnnotation(aa);\r
2506   }\r
2507 \r
2508 \r
2509     AlignFrame af = new AlignFrame(al);\r
2510     Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),\r
2511                              NEW_WINDOW_WIDTH,\r
2512                              NEW_WINDOW_HEIGHT);\r
2513 \r
2514 \r
2515    // AlignViewport newViewport = new AlignViewport(al);\r
2516    // AlignmentPanel ap = new AlignmentPanel(this, newViewport);\r
2517    // tabbedPane.add("Protein", ap);\r
2518    // viewports.add(newViewport);\r
2519   //  alignPanels.add(ap);\r
2520 \r
2521     ///Dataset tab\r
2522   /////////////////////////\r
2523 \r
2524   //  AlignViewport ds = new AlignViewport(al.getDataset());\r
2525   //  ds.setDataset(true);\r
2526   //  AlignmentPanel dap = new AlignmentPanel(this, ds);\r
2527   //  tabbedPane.add("Dataset", dap);\r
2528   //  viewports.add(ds);\r
2529   //  alignPanels.add(dap);\r
2530   /////////////////////////\r
2531 \r
2532 \r
2533 }\r
2534 \r
2535 /*public void tabSelected()\r
2536  {\r
2537   int index = tabbedPane.getSelectedIndex();\r
2538   viewport = (AlignViewport)viewports.elementAt(index);\r
2539   alignPanel = (AlignmentPanel)alignPanels.elementAt(index);\r
2540  }*/\r
2541 \r
2542 /**\r
2543  * DOCUMENT ME!\r
2544  *\r
2545  * @param String DOCUMENT ME!\r
2546  */\r
2547 public boolean parseGroupsFile(String file)\r
2548 {\r
2549     try\r
2550     {\r
2551       BufferedReader in = new BufferedReader(new FileReader(file));\r
2552       SequenceI seq = null;\r
2553       String line, type, desc, token;\r
2554 \r
2555       int index, start, end;\r
2556       StringTokenizer st;\r
2557       SequenceFeature sf;\r
2558       int lineNo = 0;\r
2559       String featureGroup = null;\r
2560       while ( (line = in.readLine()) != null)\r
2561       {\r
2562         lineNo++;\r
2563         st = new StringTokenizer(line, "\t");\r
2564         if (st.countTokens() == 2)\r
2565         {\r
2566           type = st.nextToken();\r
2567           if (type.equalsIgnoreCase("startgroup"))\r
2568           {\r
2569             featureGroup = st.nextToken();\r
2570           }\r
2571           else if (type.equalsIgnoreCase("endgroup"))\r
2572           {\r
2573             //We should check whether this is the current group,\r
2574             //but at present theres no way of showing more than 1 group\r
2575             st.nextToken();\r
2576             featureGroup = null;\r
2577           }\r
2578           else\r
2579           {\r
2580             UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
2581             alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(type,\r
2582                 ucs.findColour("A"));\r
2583           }\r
2584           continue;\r
2585         }\r
2586 \r
2587         while (st.hasMoreElements())\r
2588         {\r
2589           desc = st.nextToken();\r
2590           token = st.nextToken();\r
2591           if (!token.equals("ID_NOT_SPECIFIED"))\r
2592           {\r
2593             index = viewport.alignment.findIndex(viewport.alignment.findName(token));\r
2594             st.nextToken();\r
2595           }\r
2596           else\r
2597           {\r
2598             index = Integer.parseInt(st.nextToken());\r
2599           }\r
2600 \r
2601           start = Integer.parseInt(st.nextToken());\r
2602           end = Integer.parseInt(st.nextToken());\r
2603 \r
2604           seq = viewport.alignment.getSequenceAt(index);\r
2605 \r
2606           type = st.nextToken();\r
2607 \r
2608           if (alignPanel.seqPanel.seqCanvas.getFeatureRenderer().getColour(type) == null)\r
2609           {\r
2610             // Probably the old style groups file\r
2611             UserColourScheme ucs = new UserColourScheme(type);\r
2612             alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(type, ucs.findColour("A"));\r
2613           }\r
2614 \r
2615           sf = new SequenceFeature(type, desc, "", start, end);\r
2616           sf.setFeatureGroup(featureGroup);\r
2617 \r
2618           seq.getDatasetSequence().addSequenceFeature(sf);\r
2619         }\r
2620       }\r
2621     }\r
2622     catch (Exception ex)\r
2623     {\r
2624       ex.printStackTrace();\r
2625       System.out.println("Error parsing groups file: " + ex);\r
2626       return false;\r
2627     }\r
2628 \r
2629     viewport.showSequenceFeatures = true;\r
2630     alignPanel.repaint();\r
2631     return true;\r
2632 }\r
2633 \r
2634 public void dragEnter(DropTargetDragEvent evt)\r
2635 {}\r
2636 \r
2637 public void dragExit(DropTargetEvent evt)\r
2638 {}\r
2639 \r
2640 public void dragOver(DropTargetDragEvent evt)\r
2641 {}\r
2642 \r
2643 public void dropActionChanged(DropTargetDragEvent evt)\r
2644 {}\r
2645 \r
2646 public void drop(DropTargetDropEvent evt)\r
2647 {\r
2648     Transferable t = evt.getTransferable();\r
2649     java.util.List files = null;\r
2650 \r
2651     try\r
2652     {\r
2653       DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");\r
2654       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))\r
2655       {\r
2656         //Works on Windows and MacOSX\r
2657         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
2658         files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);\r
2659       }\r
2660       else if (t.isDataFlavorSupported(uriListFlavor))\r
2661       {\r
2662         // This is used by Unix drag system\r
2663         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
2664         String data = (String) t.getTransferData(uriListFlavor);\r
2665         files = new java.util.ArrayList(1);\r
2666         for (java.util.StringTokenizer st = new java.util.StringTokenizer(\r
2667             data,\r
2668             "\r\n");\r
2669              st.hasMoreTokens(); )\r
2670         {\r
2671           String s = st.nextToken();\r
2672           if (s.startsWith("#"))\r
2673           {\r
2674             // the line is a comment (as per the RFC 2483)\r
2675             continue;\r
2676           }\r
2677 \r
2678           java.net.URI uri = new java.net.URI(s);\r
2679           java.io.File file = new java.io.File(uri);\r
2680           files.add(file);\r
2681         }\r
2682       }\r
2683     }\r
2684     catch (Exception e)\r
2685     {\r
2686       e.printStackTrace();\r
2687     }\r
2688 \r
2689     if (files != null)\r
2690     {\r
2691       try\r
2692       {\r
2693         boolean isAnnotation = false;\r
2694 \r
2695         for (int i = 0; i < files.size(); i++)\r
2696         {\r
2697           String file = files.get(i).toString();\r
2698 \r
2699           isAnnotation = new AnnotationReader().readAnnotationFile(viewport.alignment, file);\r
2700 \r
2701           if( !isAnnotation )\r
2702           {\r
2703             boolean isGroupsFile = parseGroupsFile(file);\r
2704             if (!isGroupsFile)\r
2705             {\r
2706               String protocol = "File";\r
2707               String format = jalview.io.IdentifyFile.Identify(file, protocol);\r
2708               SequenceI[] sequences = new FormatAdapter().readFile(file, protocol, format);\r
2709 \r
2710               FastaFile ff = new FastaFile();\r
2711               Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
2712               c.setContents(new StringSelection(ff.print(sequences)), this);\r
2713 \r
2714               this.paste(false);\r
2715 \r
2716             }\r
2717           }\r
2718         }\r
2719 \r
2720         if(isAnnotation)\r
2721         {\r
2722           int height = alignPanel.annotationPanel.adjustPanelHeight();\r
2723           alignPanel.annotationScroller.setPreferredSize(\r
2724               new Dimension(alignPanel.annotationScroller.getWidth(),\r
2725                             height));\r
2726 \r
2727           alignPanel.annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
2728               alignPanel.annotationSpaceFillerHolder.getWidth(),\r
2729               height));\r
2730 \r
2731           alignPanel.addNotify();\r
2732         }\r
2733       }\r
2734       catch (Exception ex)\r
2735       {\r
2736         ex.printStackTrace();\r
2737       }\r
2738     }\r
2739 }\r
2740 \r
2741 }\r