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