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