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