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