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