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