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