loading/saving changes
[jalview.git] / src / jalview / gui / AlignFrame.java
1 /********************\r
2  * 2004 Jalview Reengineered\r
3  * Barton Group\r
4  * Dundee University\r
5  *\r
6  * AM Waterhouse\r
7  *******************/\r
8 \r
9 \r
10 \r
11 \r
12 package jalview.gui;\r
13 \r
14 import jalview.jbgui.GAlignFrame;\r
15 import jalview.schemes.*;\r
16 import jalview.datamodel.*;\r
17 import jalview.analysis.*;\r
18 import jalview.io.*;\r
19 import jalview.ws.*;\r
20 import java.awt.*;\r
21 import java.awt.event.*;\r
22 import java.awt.print.*;\r
23 import javax.swing.*;\r
24 import javax.swing.event.*;\r
25 import java.util.*;\r
26 import java.awt.datatransfer.*;\r
27 \r
28 \r
29 public class AlignFrame extends GAlignFrame\r
30 {\r
31   final AlignmentPanel alignPanel;\r
32   final AlignViewport viewport;\r
33   public static final int NEW_WINDOW_WIDTH = 700;\r
34   public static final int NEW_WINDOW_HEIGHT = 500;\r
35   public String currentFileFormat = "Jalview";\r
36 \r
37   public AlignFrame(AlignmentI al)\r
38   {\r
39     viewport = new AlignViewport(al);\r
40 \r
41     alignPanel = new AlignmentPanel(this, viewport);\r
42     alignPanel.annotationPanel.adjustPanelHeight();\r
43     alignPanel.annotationSpaceFillerHolder.setPreferredSize(alignPanel.annotationPanel.getPreferredSize());\r
44     alignPanel.annotationScroller.setPreferredSize(alignPanel.annotationPanel.getPreferredSize());\r
45     alignPanel.setAnnotationVisible( viewport.getShowAnnotation() );\r
46 \r
47     getContentPane().add(alignPanel, java.awt.BorderLayout.CENTER);\r
48 \r
49     addInternalFrameListener(new InternalFrameAdapter()\r
50    {\r
51      public void internalFrameActivated(InternalFrameEvent evt)\r
52      {\r
53           javax.swing.SwingUtilities.invokeLater(new Runnable()\r
54           {\r
55             public void run()\r
56             {      alignPanel.requestFocus();    }\r
57           });\r
58 \r
59      }\r
60    });\r
61 \r
62   }\r
63 \r
64   public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
65   {\r
66     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty("LAST_DIRECTORY")\r
67         ,  new String[]{"fa, fasta, fastq", "aln",  "pfam", "msf", "pir","blc","jar"},\r
68           new String[]{"FASTA", "CLUSTAL", "PFAM", "MSF", "PIR", "BLC", "Jalview"},\r
69           currentFileFormat);\r
70 \r
71     chooser.setAcceptAllFileFilterUsed(false);\r
72     chooser.setFileView(new JalviewFileView());\r
73     chooser.setDialogTitle("Save Alignment to file");\r
74     chooser.setToolTipText("Save");\r
75     int value = chooser.showSaveDialog(this);\r
76     if(value == JalviewFileChooser.APPROVE_OPTION)\r
77     {\r
78       currentFileFormat  = chooser.getSelectedFormat();\r
79 \r
80       if (currentFileFormat.equals("Jalview"))\r
81       {\r
82         String shortName = title.replace('/', '_');\r
83         title = title.replace('\\', '_');\r
84         String choice = chooser.getSelectedFile().getPath();\r
85         Jalview2XML.SaveState(this, System.currentTimeMillis(), shortName,\r
86                               choice);\r
87         // USE Jalview2XML to save this file\r
88         return;\r
89       }\r
90 \r
91       String choice =  chooser.getSelectedFile().getPath();\r
92       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
93       String output = FormatAdapter.formatSequences(currentFileFormat, viewport.getAlignment().getSequences());\r
94       try{\r
95         java.io.PrintWriter out = new java.io.PrintWriter( new java.io.FileWriter( choice )  );\r
96         out.println(output);\r
97         out.close();\r
98       }\r
99       catch(Exception ex){}\r
100     }\r
101 \r
102   }\r
103 \r
104   protected void outputText_actionPerformed(ActionEvent e)\r
105   {\r
106      CutAndPasteTransfer cap = new CutAndPasteTransfer(false);\r
107      JInternalFrame frame = new JInternalFrame();\r
108      cap.formatForOutput();\r
109      frame.setContentPane(cap);\r
110      Desktop.addInternalFrame(frame, "Alignment output - "+e.getActionCommand(), 600, 500);\r
111      cap.setText( FormatAdapter.formatSequences(e.getActionCommand(), viewport.getAlignment().getSequences()));\r
112   }\r
113 \r
114   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
115   {\r
116     HTMLOutput htmlOutput = new HTMLOutput(viewport);\r
117     htmlOutput = null;\r
118   }\r
119 \r
120   protected void createPNG_actionPerformed(ActionEvent e)\r
121   {\r
122     alignPanel.makePNG();\r
123   }\r
124 \r
125   protected void epsFile_actionPerformed(ActionEvent e)\r
126   {\r
127     alignPanel.makeEPS();\r
128   }\r
129 \r
130 \r
131   public void printMenuItem_actionPerformed(ActionEvent e)\r
132   {\r
133     //Putting in a thread avoids Swing painting problems\r
134     PrintThread thread = new PrintThread();\r
135     thread.start();\r
136   }\r
137 \r
138   class PrintThread extends Thread\r
139   {\r
140     public void run()\r
141     {\r
142       PrinterJob printJob = PrinterJob.getPrinterJob();\r
143       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
144       printJob.setPrintable(alignPanel, pf);\r
145       if (printJob.printDialog())\r
146       {\r
147         try\r
148         {\r
149           printJob.print();\r
150         }\r
151         catch (Exception PrintException)\r
152         {\r
153           PrintException.printStackTrace();\r
154         }\r
155       }\r
156     }\r
157 \r
158   }\r
159 \r
160 \r
161 \r
162 \r
163   public void closeMenuItem_actionPerformed(ActionEvent e)\r
164   {\r
165     try{\r
166       this.setClosed(true);\r
167     }catch(Exception ex){}\r
168   }\r
169 \r
170   Stack historyList = new Stack();\r
171   Stack redoList = new Stack();\r
172 \r
173   void updateEditMenuBar()\r
174   {\r
175     if(historyList.size()>0)\r
176      {\r
177        undoMenuItem.setEnabled(true);\r
178        Object [] history = (Object[])historyList.get(0);\r
179        undoMenuItem.setText("Undo "+history[0]);\r
180      }\r
181     else\r
182     {\r
183       undoMenuItem.setEnabled(false);\r
184       undoMenuItem.setText("Undo");\r
185     }\r
186 \r
187     if(redoList.size()>0)\r
188      {\r
189        redoMenuItem.setEnabled(true);\r
190        Object [] history = (Object[])redoList.get(0);\r
191        redoMenuItem.setText("Redo "+history[0]);\r
192      }\r
193     else\r
194     {\r
195       redoMenuItem.setEnabled(false);\r
196       redoMenuItem.setText("Redo");\r
197     }\r
198   }\r
199 \r
200   public void addHistoryItem(String type)\r
201   {\r
202     // must make sure we add new sequence objects her, not refs to the existing sequences\r
203     redoList.clear();\r
204 \r
205     SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
206     for(int i=0; i<viewport.getAlignment().getHeight(); i++)\r
207     {\r
208       seq[i] = new Sequence( viewport.getAlignment().getSequenceAt(i).getName(),\r
209                              viewport.getAlignment().getSequenceAt(i).getSequence());\r
210     }\r
211 \r
212 \r
213     historyList.add(0, new Object[]{type,  seq} );\r
214     updateEditMenuBar();\r
215   }\r
216 \r
217   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
218   {\r
219     Object [] history = (Object[])historyList.remove(0);\r
220     // add the redo state before continuing!!\r
221     SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
222     for (int i = 0; i < viewport.getAlignment().getHeight(); i++)\r
223     {\r
224       seq[i] = new Sequence(viewport.getAlignment().getSequenceAt(i).getName(),\r
225                             viewport.getAlignment().getSequenceAt(i).\r
226                             getSequence());\r
227     }\r
228     /////////\r
229 \r
230     redoList.add(0, new Object[] {history[0], seq});\r
231 \r
232       seq = (SequenceI[]) history[1];\r
233       AlignmentAnnotation [] old = viewport.alignment.getAlignmentAnnotation();\r
234       viewport.setAlignment( new Alignment(seq) );\r
235       viewport.alignment.setGapCharacter( Preferences.gapSymbol );\r
236       updateEditMenuBar();\r
237       for(int i=0; i<old.length; i++)\r
238         viewport.alignment.addAnnotation(old[i]);\r
239       viewport.updateConsensus();\r
240       viewport.updateConservation();\r
241       alignPanel.repaint();\r
242   }\r
243 \r
244   public void moveSelectedSequences(boolean up)\r
245   {\r
246     SequenceGroup sg = viewport.getSelectionGroup();\r
247     if (sg == null)\r
248       return;\r
249 \r
250     if (up)\r
251     {\r
252       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
253       {\r
254         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
255         if (!sg.sequences.contains(seq))\r
256           continue;\r
257 \r
258         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
259         if (sg.sequences.contains(temp))\r
260           continue;\r
261 \r
262         viewport.alignment.getSequences().setElementAt(temp, i);\r
263         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
264       }\r
265     }\r
266     else\r
267     {\r
268       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
269       {\r
270         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
271         if (!sg.sequences.contains(seq))\r
272           continue;\r
273 \r
274         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
275         if (sg.sequences.contains(temp))\r
276           continue;\r
277 \r
278         viewport.alignment.getSequences().setElementAt(temp, i);\r
279         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
280       }\r
281     }\r
282 \r
283     alignPanel.repaint();\r
284   }\r
285 \r
286 \r
287 \r
288   protected void copy_actionPerformed(ActionEvent e)\r
289   {\r
290    if(viewport.getSelectionGroup()==null)\r
291      return;\r
292 \r
293    SequenceGroup sg = viewport.getSelectionGroup();\r
294 \r
295      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
296      StringBuffer buffer= new StringBuffer();\r
297 \r
298        for(int i=0; i<sg.getSize(); i++)\r
299        {\r
300          SequenceI seq = sg.getSequenceAt(i);\r
301          buffer.append( seq.getName()+"\t"+seq.findPosition( sg.getStartRes() ) +"\t"\r
302                         +seq.findPosition( sg.getEndRes() )+ "\t"\r
303                         +sg.getSequenceAt(i).getSequence(sg.getStartRes(), sg.getEndRes()+1)+"\n");\r
304        }\r
305      c.setContents( new StringSelection( buffer.toString()) , null ) ;\r
306 \r
307   }\r
308 \r
309 \r
310   protected void pasteNew_actionPerformed(ActionEvent e)\r
311   {\r
312     paste(true);\r
313   }\r
314 \r
315   protected void pasteThis_actionPerformed(ActionEvent e)\r
316   {\r
317     addHistoryItem("Paste");\r
318     paste(false);\r
319   }\r
320 \r
321   void paste(boolean newAlignment)\r
322   {\r
323     try{\r
324       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
325       Transferable contents = c.getContents(this);\r
326       if (contents == null)\r
327         return;\r
328 \r
329       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
330       StringTokenizer st = new StringTokenizer(str);\r
331       ArrayList seqs = new ArrayList();\r
332       while (st.hasMoreElements())\r
333       {\r
334         String name = st.nextToken();\r
335         int start = Integer.parseInt(st.nextToken());\r
336         int end = Integer.parseInt(st.nextToken());\r
337         Sequence sequence = new Sequence(name,st.nextToken(), start, end);\r
338 \r
339         if(!newAlignment)\r
340           viewport.alignment.addSequence(sequence);\r
341         else\r
342           seqs.add(sequence);\r
343       }\r
344 \r
345       if(newAlignment)\r
346       {\r
347         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
348         seqs.toArray(newSeqs);\r
349         AlignFrame af = new AlignFrame(new Alignment(newSeqs));\r
350         String newtitle = new String("Copied sequences");\r
351         if( title.startsWith("Copied sequences"))\r
352          newtitle = title;\r
353        else\r
354          newtitle = newtitle.concat("- from "+title);\r
355 \r
356         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH, NEW_WINDOW_HEIGHT);\r
357       }\r
358       else\r
359       {\r
360         viewport.setEndSeq(viewport.alignment.getHeight());\r
361         viewport.alignment.getWidth();\r
362         viewport.updateConservation();\r
363         viewport.updateConsensus();\r
364         alignPanel.repaint();\r
365       }\r
366 \r
367     }catch(Exception ex){}// could be anything being pasted in here\r
368 \r
369   }\r
370 \r
371 \r
372   protected void cut_actionPerformed(ActionEvent e)\r
373   {\r
374     copy_actionPerformed(null);\r
375     delete_actionPerformed(null);\r
376   }\r
377 \r
378   protected void delete_actionPerformed(ActionEvent e)\r
379   {\r
380     addHistoryItem("Delete");\r
381     if (viewport.getSelectionGroup() == null)\r
382       return;\r
383 \r
384      SequenceGroup sg = viewport.getSelectionGroup();\r
385      for (int i=0;i < sg.sequences.size(); i++)\r
386      {\r
387        SequenceI seq = sg.getSequenceAt(i);\r
388        int index = viewport.getAlignment().findIndex(seq);\r
389        seq.deleteChars(sg.getStartRes(), sg.getEndRes()+1);\r
390 \r
391        if(seq.getSequence().length()<1)\r
392           viewport.getAlignment().deleteSequence(seq);\r
393       else\r
394           viewport.getAlignment().getSequences().setElementAt(seq, index);\r
395      }\r
396 \r
397      viewport.setSelectionGroup(null);\r
398      viewport.alignment.deleteGroup(sg);\r
399      viewport.resetSeqLimits( alignPanel.seqPanel.seqCanvas.getHeight());\r
400      if(viewport.getAlignment().getHeight()<1)\r
401      try\r
402      {\r
403        this.setClosed(true);\r
404      }catch(Exception ex){}\r
405    viewport.updateConservation();\r
406    viewport.updateConsensus();\r
407      alignPanel.repaint();\r
408 \r
409   }\r
410 \r
411 \r
412 \r
413   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
414   {\r
415      Object [] history = (Object[])redoList.remove(0);\r
416      SequenceI[] seq = (SequenceI[]) history[1];\r
417      viewport.setAlignment( new Alignment(seq) );\r
418      viewport.alignment.setGapCharacter( Preferences.gapSymbol );\r
419      updateEditMenuBar();\r
420      viewport.updateConsensus();\r
421      alignPanel.repaint();\r
422      alignPanel.repaint();\r
423   }\r
424 \r
425 \r
426   protected void deleteGroups_actionPerformed(ActionEvent e)\r
427   {\r
428     viewport.alignment.deleteAllGroups();\r
429     viewport.setSelectionGroup(null);\r
430     alignPanel.repaint();\r
431   }\r
432 \r
433 \r
434 \r
435   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
436   {\r
437     SequenceGroup sg = new SequenceGroup();\r
438     for (int i=0; i<viewport.getAlignment().getSequences().size(); i++)\r
439       sg.addSequence( viewport.getAlignment().getSequenceAt(i));\r
440     sg.setEndRes(viewport.alignment.getWidth());\r
441     viewport.setSelectionGroup(sg);\r
442     PaintRefresher.Refresh(null);\r
443   }\r
444 \r
445   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
446   {\r
447     viewport.setSelectionGroup(null);\r
448     viewport.getColumnSelection().clear();\r
449     viewport.setSelectionGroup(null);\r
450     PaintRefresher.Refresh(null);\r
451   }\r
452 \r
453   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
454   {\r
455     SequenceGroup sg = viewport.getSelectionGroup();\r
456     for (int i=0; i<viewport.getAlignment().getSequences().size(); i++)\r
457       sg.addOrRemove (viewport.getAlignment().getSequenceAt(i));\r
458 \r
459     PaintRefresher.Refresh(null);\r
460   }\r
461 \r
462   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
463   {\r
464     addHistoryItem("delete columns");\r
465     ColumnSelection colSel = viewport.getColumnSelection();\r
466     if (colSel.size() > 0)\r
467     {\r
468       int min = colSel.getMin();\r
469       viewport.getAlignment().trimLeft(min);\r
470       colSel.compensateForEdit(0,min);\r
471 \r
472       if(viewport.getSelectionGroup()!=null)\r
473         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
474 \r
475       Vector groups = viewport.alignment.getGroups();\r
476       for(int i=0; i<groups.size(); i++)\r
477       {\r
478         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
479         if(!sg.adjustForRemoveLeft(min))\r
480           viewport.alignment.deleteGroup(sg);\r
481       }\r
482 \r
483       alignPanel.repaint();\r
484     }\r
485   }\r
486 \r
487   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
488   {\r
489     addHistoryItem("delete columns");\r
490     ColumnSelection colSel = viewport.getColumnSelection();\r
491     if (colSel.size() > 0)\r
492     {\r
493       int max = colSel.getMax();\r
494       viewport.getAlignment().trimRight(max);\r
495       if(viewport.getSelectionGroup()!=null)\r
496         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
497 \r
498       Vector groups = viewport.alignment.getGroups();\r
499       for(int i=0; i<groups.size(); i++)\r
500       {\r
501         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
502         if(!sg.adjustForRemoveRight(max))\r
503           viewport.alignment.deleteGroup(sg);\r
504       }\r
505 \r
506 \r
507 \r
508       alignPanel.repaint();\r
509     }\r
510 \r
511   }\r
512 \r
513   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
514   {\r
515     addHistoryItem("delete gapped columns");\r
516     viewport.getAlignment().removeGaps();\r
517     viewport.updateConservation();\r
518     viewport.updateConsensus();\r
519     alignPanel.repaint();\r
520   }\r
521 \r
522   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
523   {\r
524     addHistoryItem("delete all gaps");\r
525     SequenceI current;\r
526     int jSize;\r
527     for (int i=0; i < viewport.getAlignment().getSequences().size();i++)\r
528     {\r
529       current = viewport.getAlignment().getSequenceAt(i);\r
530       jSize = current.getLength();\r
531       for (int j=0; j < jSize; j++)\r
532         if(jalview.util.Comparison.isGap(current.getCharAt(j)))\r
533         {\r
534           current.deleteCharAt(j);\r
535           j--;\r
536           jSize--;\r
537         }\r
538     }\r
539     viewport.updateConservation();\r
540     viewport.updateConsensus();\r
541     alignPanel.repaint();\r
542   }\r
543 \r
544 \r
545   public void findMenuItem_actionPerformed(ActionEvent e)\r
546   {\r
547     JInternalFrame frame = new JInternalFrame();\r
548     Finder finder = new Finder(viewport, alignPanel, frame);\r
549     frame.setContentPane(finder);\r
550     Desktop.addInternalFrame(frame, "Find", 340,110);\r
551     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
552 \r
553   }\r
554 \r
555 \r
556   public void font_actionPerformed(ActionEvent e)\r
557   {\r
558     FontChooser fc = new FontChooser( alignPanel );\r
559   }\r
560 \r
561   protected void fullSeqId_actionPerformed(ActionEvent e)\r
562   {\r
563     viewport.setShowFullId( fullSeqId.isSelected() );\r
564 \r
565     alignPanel.idPanel.idCanvas.setPreferredSize( alignPanel.calculateIdWidth() );\r
566     alignPanel.repaint();\r
567   }\r
568 \r
569   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
570   {\r
571       viewport.setColourText( colourTextMenuItem.isSelected() );\r
572       alignPanel.repaint();\r
573   }\r
574 \r
575   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
576   {\r
577     viewport.setWrapAlignment( wrapMenuItem.isSelected() );\r
578     alignPanel.setWrapAlignment( wrapMenuItem.isSelected() );\r
579     scaleAbove.setVisible( wrapMenuItem.isSelected() );\r
580     scaleLeft.setVisible( wrapMenuItem.isSelected() );\r
581     scaleRight.setVisible( wrapMenuItem.isSelected() );\r
582     alignPanel.repaint();\r
583   }\r
584 \r
585   protected void scaleAbove_actionPerformed(ActionEvent e)\r
586   {\r
587     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
588     alignPanel.repaint();\r
589   }\r
590 \r
591   protected void scaleLeft_actionPerformed(ActionEvent e)\r
592   {\r
593     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
594     alignPanel.repaint();\r
595   }\r
596 \r
597   protected void scaleRight_actionPerformed(ActionEvent e)\r
598   {\r
599     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
600     alignPanel.repaint();\r
601   }\r
602 \r
603 \r
604 \r
605   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
606   {\r
607     viewport.setShowBoxes( viewBoxesMenuItem.isSelected() );\r
608     alignPanel.repaint();\r
609   }\r
610 \r
611   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
612   {\r
613     viewport.setShowText( viewTextMenuItem.isSelected() );\r
614     alignPanel.repaint();\r
615   }\r
616 \r
617 \r
618   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
619   {\r
620     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
621     alignPanel.repaint();\r
622   }\r
623 \r
624   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
625   {\r
626     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
627     if(viewport.showSequenceFeatures && !((Alignment)viewport.alignment).featuresAdded)\r
628     {\r
629          SequenceFeatureFetcher sft = new SequenceFeatureFetcher(viewport.alignment, alignPanel);\r
630          ((Alignment)viewport.alignment).featuresAdded = true;\r
631     }\r
632     alignPanel.repaint();\r
633   }\r
634 \r
635   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
636   {\r
637     if(annotationPanelMenuItem.isSelected() && viewport.getWrapAlignment())\r
638     {\r
639       annotationPanelMenuItem.setSelected(false);\r
640       return;\r
641     }\r
642     viewport.setShowAnnotation( annotationPanelMenuItem.isSelected() );\r
643     alignPanel.setAnnotationVisible( annotationPanelMenuItem.isSelected() );\r
644   }\r
645 \r
646   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
647   {\r
648     if (alignPanel.overviewPanel != null)\r
649       return;\r
650 \r
651     JInternalFrame frame = new JInternalFrame();\r
652     OverviewPanel overview = new OverviewPanel(alignPanel);\r
653      frame.setContentPane(overview);\r
654     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
655                              frame.getWidth(), frame.getHeight());\r
656     frame.pack();\r
657     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
658     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
659     { public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)\r
660       {\r
661             alignPanel.setOverviewPanel(null);\r
662       };\r
663     });\r
664 \r
665     alignPanel.setOverviewPanel( overview );\r
666 \r
667 \r
668   }\r
669 \r
670   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
671   {\r
672     changeColour( null );\r
673   }\r
674 \r
675 \r
676   public void clustalColour_actionPerformed(ActionEvent e)\r
677   {\r
678     abovePIDThreshold.setSelected(false);\r
679     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
680   }\r
681 \r
682   public void zappoColour_actionPerformed(ActionEvent e)\r
683   {\r
684     changeColour(new ZappoColourScheme());\r
685   }\r
686 \r
687   public void taylorColour_actionPerformed(ActionEvent e)\r
688   {\r
689     changeColour(new TaylorColourScheme());\r
690   }\r
691 \r
692 \r
693   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
694   {\r
695     changeColour( new HydrophobicColourScheme() );\r
696   }\r
697 \r
698   public void helixColour_actionPerformed(ActionEvent e)\r
699   {\r
700     changeColour(new HelixColourScheme() );\r
701   }\r
702 \r
703 \r
704   public void strandColour_actionPerformed(ActionEvent e)\r
705   {\r
706     changeColour(new StrandColourScheme());\r
707   }\r
708 \r
709 \r
710   public void turnColour_actionPerformed(ActionEvent e)\r
711   {\r
712     changeColour(new TurnColourScheme());\r
713   }\r
714 \r
715 \r
716   public void buriedColour_actionPerformed(ActionEvent e)\r
717   {\r
718     changeColour(new BuriedColourScheme() );\r
719   }\r
720 \r
721   public void nucleotideColour_actionPerformed(ActionEvent e)\r
722   {\r
723     changeColour(new NucleotideColourScheme());\r
724   }\r
725 \r
726 \r
727   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
728   {\r
729     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
730   }\r
731 \r
732 \r
733 \r
734   void changeColour(ColourSchemeI cs)\r
735   {\r
736     int threshold = 0;\r
737 \r
738     if ( viewport.getAbovePIDThreshold() )\r
739     {\r
740       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
741 \r
742       if (cs instanceof ResidueColourScheme)\r
743         ( (ResidueColourScheme) cs).setThreshold(threshold);\r
744       else if (cs instanceof ScoreColourScheme)\r
745         ( (ScoreColourScheme) cs).setThreshold(threshold);\r
746 \r
747       viewport.setGlobalColourScheme(cs);\r
748     }\r
749     else if (cs instanceof ResidueColourScheme)\r
750       ( (ResidueColourScheme) cs).setThreshold(0);\r
751     else if (cs instanceof ScoreColourScheme)\r
752       ( (ScoreColourScheme) cs).setThreshold(0);\r
753 \r
754 \r
755 \r
756     if (viewport.getConservationSelected())\r
757     {\r
758       ConservationColourScheme ccs = null;\r
759 \r
760       Alignment al = (Alignment) viewport.alignment;\r
761       Conservation c = new Conservation("All",\r
762                                         ResidueProperties.propHash, 3,\r
763                                         al.getSequences(), 0,\r
764                                         al.getWidth() - 1);\r
765 \r
766       c.calculate();\r
767       c.verdict(false, viewport.ConsPercGaps);\r
768 \r
769       ccs = new ConservationColourScheme(c, cs);\r
770 \r
771       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
772       ccs.setConsensus( viewport.vconsensus );\r
773       viewport.setGlobalColourScheme(ccs);\r
774 \r
775       SliderPanel.setConservationSlider(alignPanel, ccs, "Background");\r
776 \r
777     }\r
778     else\r
779     {\r
780         // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
781         if (cs != null)\r
782           cs.setConsensus(viewport.vconsensus);\r
783         viewport.setGlobalColourScheme(cs);\r
784     }\r
785 \r
786 \r
787     if(viewport.getColourAppliesToAllGroups())\r
788     {\r
789       Vector groups = viewport.alignment.getGroups();\r
790       for(int i=0; i<groups.size(); i++)\r
791       {\r
792         SequenceGroup sg = (SequenceGroup)groups.elementAt(i);\r
793 \r
794         if (cs instanceof ClustalxColourScheme)\r
795         {\r
796           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
797         }\r
798         else if(cs!=null)\r
799         {\r
800           try{\r
801             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
802           }catch(Exception ex){ex.printStackTrace();}\r
803         }\r
804 \r
805         if(viewport.getAbovePIDThreshold())\r
806         {\r
807           if (sg.cs instanceof ResidueColourScheme)\r
808             ( (ResidueColourScheme) sg.cs).setThreshold(threshold);\r
809           else if (sg.cs instanceof ScoreColourScheme)\r
810             ( (ScoreColourScheme) sg.cs).setThreshold(threshold);\r
811 \r
812            sg.cs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()) );\r
813         }\r
814 \r
815         if( viewport.getConservationSelected() )\r
816         {\r
817           Conservation c = new Conservation("Group",\r
818                                             ResidueProperties.propHash, 3,\r
819                                             sg.sequences, 0, viewport.alignment.getWidth()-1);\r
820           c.calculate();\r
821           c.verdict(false, viewport.ConsPercGaps);\r
822           ConservationColourScheme ccs = new ConservationColourScheme(c, sg.cs);\r
823 \r
824           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
825           ccs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
826           sg.cs = ccs;\r
827         }\r
828         else if(cs!=null)\r
829         {\r
830           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
831           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
832         }\r
833 \r
834       }\r
835     }\r
836 \r
837     if(alignPanel.getOverviewPanel()!=null)\r
838       alignPanel.getOverviewPanel().updateOverviewImage();\r
839     alignPanel.repaint();\r
840   }\r
841 \r
842   protected void modifyPID_actionPerformed(ActionEvent e)\r
843   {\r
844       if(viewport.getAbovePIDThreshold())\r
845       {\r
846         SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
847                                    "Background");\r
848         SliderPanel.showPIDSlider();\r
849       }\r
850   }\r
851 \r
852   protected void modifyConservation_actionPerformed(ActionEvent e)\r
853   {\r
854     if(viewport.getConservationSelected())\r
855     {\r
856       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
857                                         "Background");\r
858       SliderPanel.showConservationSlider();\r
859     }\r
860   }\r
861 \r
862 \r
863   protected  void conservationMenuItem_actionPerformed(ActionEvent e)\r
864   {\r
865     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
866 \r
867     viewport.setAbovePIDThreshold(false);\r
868     abovePIDThreshold.setSelected(false);\r
869 \r
870    ColourSchemeI cs = viewport.getGlobalColourScheme();\r
871    if(cs instanceof ConservationColourScheme )\r
872      changeColour( ((ConservationColourScheme)cs).cs );\r
873     else\r
874       changeColour( cs );\r
875 \r
876     modifyConservation_actionPerformed(null);\r
877   }\r
878 \r
879   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
880   {\r
881     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
882 \r
883     conservationMenuItem.setSelected(false);\r
884     viewport.setConservationSelected(false);\r
885 \r
886     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
887 \r
888     if(cs instanceof ConservationColourScheme )\r
889         changeColour( ((ConservationColourScheme)cs).cs );\r
890     else\r
891         changeColour( cs );\r
892 \r
893     modifyPID_actionPerformed(null);\r
894   }\r
895 \r
896 \r
897 \r
898   public void userDefinedColour_actionPerformed(ActionEvent e)\r
899   {\r
900     UserDefinedColours chooser = new UserDefinedColours( alignPanel, null);\r
901   }\r
902 \r
903   public void PIDColour_actionPerformed(ActionEvent e)\r
904   {\r
905     changeColour( new PIDColourScheme() );\r
906   }\r
907 \r
908 \r
909   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
910   {\r
911     changeColour(new Blosum62ColourScheme() );\r
912   }\r
913 \r
914 \r
915 \r
916   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
917   {\r
918     addHistoryItem("sort");\r
919     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport.getAlignment().getSequenceAt(0));\r
920     alignPanel.repaint();\r
921   }\r
922 \r
923   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
924   {\r
925     addHistoryItem("sort");\r
926     AlignmentSorter.sortByID( viewport.getAlignment() );\r
927     alignPanel.repaint();\r
928   }\r
929 \r
930   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
931   {\r
932     addHistoryItem("sort");\r
933     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
934     AlignmentSorter.sortGroups(viewport.getAlignment());\r
935     alignPanel.repaint();\r
936   }\r
937 \r
938   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
939   {\r
940     RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
941     JInternalFrame frame = new JInternalFrame();\r
942     frame.setContentPane(sp);\r
943     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400, 100, false);\r
944 \r
945   }\r
946 \r
947   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
948   {\r
949     if(viewport.getSelectionGroup().getSize()<2)\r
950       JOptionPane.showInternalMessageDialog(this, "You must select at least 2 sequences.", "Invalid Selection", JOptionPane.WARNING_MESSAGE);\r
951     else\r
952     {\r
953       JInternalFrame frame = new JInternalFrame();\r
954       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
955       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
956     }\r
957   }\r
958 \r
959   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
960   {\r
961 \r
962     if( (viewport.getSelectionGroup()!=null && viewport.getSelectionGroup().getSize()<4 && viewport.getSelectionGroup().getSize()>0)\r
963        || viewport.getAlignment().getHeight()<4)\r
964     {\r
965       JOptionPane.showInternalMessageDialog(this, "Principal component analysis must take\n"\r
966                                     +"at least 4 input sequences.",\r
967                                     "Sequence selection insufficient",\r
968                                     JOptionPane.WARNING_MESSAGE);\r
969       return;\r
970     }\r
971 \r
972     try{\r
973       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
974       JInternalFrame frame = new JInternalFrame();\r
975       frame.setContentPane(pcaPanel);\r
976       Desktop.addInternalFrame(frame, "Principal component analysis", 400, 400);\r
977    }catch(java.lang.OutOfMemoryError ex)\r
978    {\r
979      JOptionPane.showInternalMessageDialog(this, "Too many sequences selected\nfor Principal Component Analysis!!",\r
980                                    "Out of memory", JOptionPane.WARNING_MESSAGE);\r
981    }\r
982 \r
983 \r
984   }\r
985 \r
986   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
987   {\r
988     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
989   }\r
990 \r
991   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
992   {\r
993     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
994   }\r
995 \r
996 \r
997   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
998   {\r
999     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1000   }\r
1001 \r
1002   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1003   {\r
1004     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
1005   }\r
1006 \r
1007   void NewTreePanel(String type, String pwType, String title)\r
1008   {\r
1009     //are the sequences aligned?\r
1010     if(!viewport.alignment.isAligned())\r
1011     {\r
1012       JOptionPane.showMessageDialog(Desktop.desktop, "The sequences must be aligned before creating a tree.",\r
1013                                     "Sequences not aligned", JOptionPane.WARNING_MESSAGE);\r
1014       return;\r
1015     }\r
1016 \r
1017     final TreePanel tp;\r
1018     if (viewport.getSelectionGroup() != null &&\r
1019         viewport.getSelectionGroup().getSize() > 3)\r
1020     {\r
1021       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
1022                          pwType,\r
1023                          0, viewport.alignment.getWidth());\r
1024     }\r
1025     else\r
1026     {\r
1027       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1028                          type, pwType, 0, viewport.alignment.getWidth());\r
1029     }\r
1030 \r
1031    addTreeMenuItem(tp, title);\r
1032 \r
1033    Desktop.addInternalFrame(tp, title, 600, 500);\r
1034   }\r
1035 \r
1036   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1037   {\r
1038     final JMenuItem item = new JMenuItem(title);\r
1039     sortByTreeMenu.add(item);\r
1040     item.addActionListener(new java.awt.event.ActionListener()\r
1041     {\r
1042       public void actionPerformed(ActionEvent e)\r
1043       {\r
1044         addHistoryItem("sort");\r
1045         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
1046         alignPanel.repaint();\r
1047       }\r
1048     });\r
1049 \r
1050     treePanel.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1051     {\r
1052       public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)\r
1053       {\r
1054         sortByTreeMenu.remove(item);\r
1055       };\r
1056     });\r
1057 \r
1058   }\r
1059 \r
1060 \r
1061   public void clustalAlignMenuItem_actionPerformed(ActionEvent e)\r
1062   {\r
1063      WebserviceInfo info = new WebserviceInfo("Clustal web service",\r
1064      "\"Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple"+\r
1065      " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice."\r
1066     +" Nucleic Acids Research, submitted, June 1994.",\r
1067      450, 150);\r
1068 \r
1069     ClustalThread thread = new ClustalThread(info);\r
1070     thread.start();\r
1071   }\r
1072 \r
1073     class ClustalThread extends Thread\r
1074     {\r
1075       WebserviceInfo info;\r
1076       public ClustalThread(WebserviceInfo info)\r
1077       {this.info = info; }\r
1078 \r
1079       public void run()\r
1080       {\r
1081         info.setStatus(WebserviceInfo.STATE_RUNNING);\r
1082         jalview.ws.Jemboss jemboss = new jalview.ws.Jemboss();\r
1083         Vector sv = viewport.getAlignment().getSequences();\r
1084         SequenceI[] seqs = new SequenceI[sv.size()];\r
1085 \r
1086         int i = 0;\r
1087         do\r
1088         {\r
1089           seqs[i] = (SequenceI) sv.elementAt(i);\r
1090         }\r
1091         while (++i < sv.size());\r
1092 \r
1093         SequenceI[] alignment = jemboss.clustalW(seqs); // gaps removed within method\r
1094         if (alignment != null)\r
1095         {\r
1096           AlignFrame af = new AlignFrame(new Alignment(alignment));\r
1097           Desktop.addInternalFrame(af, title.concat(" - ClustalW Alignment"),\r
1098                                    NEW_WINDOW_WIDTH, NEW_WINDOW_HEIGHT);\r
1099           af.clustalColour_actionPerformed(null);\r
1100           af.clustalColour.setSelected(true);\r
1101           info.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
1102         }\r
1103         else\r
1104         {\r
1105             info.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
1106             info.appendProgressText("Problem obtaining clustal alignment");\r
1107         }\r
1108       }\r
1109     }\r
1110 \r
1111   protected void jpred_actionPerformed(ActionEvent e)\r
1112 {\r
1113 \r
1114     if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>0)\r
1115     {\r
1116       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1117       SequenceGroup seqs = viewport.getSelectionGroup();\r
1118       if (seqs.getSize() == 1 || !viewport.alignment.isAligned())\r
1119       {\r
1120         JPredClient ct = new JPredClient( (SequenceI)seqs.getSequenceAt(0));\r
1121       }\r
1122       else\r
1123       {\r
1124         int sz;\r
1125         SequenceI[] msa = new SequenceI[sz=seqs.getSize()];\r
1126         for (int i = 0; i < sz; i++)\r
1127         {\r
1128           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1129         }\r
1130 \r
1131         JPredClient ct = new JPredClient(msa);\r
1132       }\r
1133 \r
1134     }\r
1135     else\r
1136     {\r
1137       Vector seqs = viewport.getAlignment().getSequences();\r
1138 \r
1139       if (seqs.size() == 1 || !viewport.alignment.isAligned())\r
1140       {\r
1141         JPredClient ct = new JPredClient( (SequenceI)\r
1142                                          seqs.elementAt(0));\r
1143       }\r
1144       else\r
1145       {\r
1146         SequenceI[] msa = new SequenceI[seqs.size()];\r
1147         for (int i = 0; i < seqs.size(); i++)\r
1148         {\r
1149           msa[i] = (SequenceI) seqs.elementAt(i);\r
1150         }\r
1151 \r
1152         JPredClient ct = new JPredClient(msa);\r
1153       }\r
1154 \r
1155     }\r
1156   }\r
1157   protected void msaAlignMenuItem_actionPerformed(ActionEvent e)\r
1158   {\r
1159     // TODO:resolve which menu item was actually selected\r
1160     // Now, check we have enough sequences\r
1161       if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>1)\r
1162       {\r
1163         // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1164         SequenceGroup seqs = viewport.getSelectionGroup();\r
1165         int sz;\r
1166         SequenceI[] msa = new SequenceI[sz=seqs.getSize()];\r
1167         for (int i = 0; i < sz; i++)\r
1168         {\r
1169           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1170         }\r
1171 \r
1172         MsaWSClient ct = new jalview.ws.MsaWSClient(msa);\r
1173       }\r
1174       else\r
1175       {\r
1176         Vector seqs = viewport.getAlignment().getSequences();\r
1177 \r
1178         if (seqs.size() > 1) {\r
1179           SequenceI[] msa = new SequenceI[seqs.size()];\r
1180           for (int i = 0; i < seqs.size(); i++)\r
1181           {\r
1182             msa[i] = (SequenceI) seqs.elementAt(i);\r
1183           }\r
1184 \r
1185           MsaWSClient ct = new MsaWSClient(msa);\r
1186         }\r
1187 \r
1188       }\r
1189     }\r
1190 \r
1191     protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) {\r
1192     // Pick the tree file\r
1193     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
1194         getProperty("LAST_DIRECTORY"));\r
1195     chooser.setFileView(new JalviewFileView());\r
1196     chooser.setDialogTitle("Select a newick-like tree file");\r
1197     chooser.setToolTipText("Load a tree file");\r
1198     int value = chooser.showOpenDialog(null);\r
1199     if (value == JalviewFileChooser.APPROVE_OPTION)\r
1200     {\r
1201       String choice = chooser.getSelectedFile().getPath();\r
1202       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
1203       try\r
1204       {\r
1205         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice, "File");\r
1206         ShowNewickTree(fin, choice);\r
1207       }\r
1208       catch (Exception ex)\r
1209       {\r
1210         JOptionPane.showMessageDialog(Desktop.desktop,\r
1211                                       "Problem reading tree file",\r
1212                                       ex.getMessage(),\r
1213                                       JOptionPane.WARNING_MESSAGE);\r
1214         ex.printStackTrace();\r
1215       }\r
1216     }\r
1217   }\r
1218 \r
1219   public void ShowNewickTree(NewickFile nf, String title)\r
1220   {\r
1221     try{\r
1222       nf.parse();\r
1223       if (nf.getTree() != null)\r
1224       {\r
1225         TreePanel tp = new TreePanel(viewport,\r
1226                                      viewport.getAlignment().getSequences(),\r
1227                                      nf, "FromFile", title);\r
1228         Desktop.addInternalFrame(tp, title, 600, 500);\r
1229         addTreeMenuItem(tp, title);\r
1230         viewport.setCurrentTree(tp.getTree());\r
1231       }\r
1232      }catch(Exception ex){ex.printStackTrace();}\r
1233   }\r
1234 \r
1235 \r
1236 }\r