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