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