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