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