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