28e40eb1ea7591de061b72b0b36bf6dca98c7357
[jalview.git] / src / jalview / appletgui / APopupMenu.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.awt.*;\r
23 import java.awt.event.*;\r
24 import java.util.Vector;\r
25 \r
26 import jalview.analysis.*;\r
27 import jalview.datamodel.*;\r
28 import jalview.schemes.*;\r
29 \r
30 public class APopupMenu\r
31     extends java.awt.PopupMenu implements ActionListener, ItemListener\r
32 {\r
33   Menu groupMenu = new Menu();\r
34   protected MenuItem clustalColour = new MenuItem();\r
35   protected MenuItem zappoColour = new MenuItem();\r
36   protected MenuItem taylorColour = new MenuItem();\r
37   protected MenuItem hydrophobicityColour = new MenuItem();\r
38   protected MenuItem helixColour = new MenuItem();\r
39   protected MenuItem strandColour = new MenuItem();\r
40   protected MenuItem turnColour = new MenuItem();\r
41   protected MenuItem buriedColour = new MenuItem();\r
42   protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();\r
43   protected MenuItem userDefinedColour = new MenuItem();\r
44   protected MenuItem PIDColour = new MenuItem();\r
45   protected MenuItem BLOSUM62Colour = new MenuItem();\r
46   MenuItem noColourmenuItem = new MenuItem();\r
47   protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();\r
48 \r
49   final AlignmentPanel ap;\r
50   MenuItem unGroupMenuItem = new MenuItem();\r
51   MenuItem nucleotideMenuItem = new MenuItem();\r
52   Menu colourMenu = new Menu();\r
53   CheckboxMenuItem showBoxes = new CheckboxMenuItem();\r
54   CheckboxMenuItem showText = new CheckboxMenuItem();\r
55   CheckboxMenuItem showColourText = new CheckboxMenuItem();\r
56   Menu editMenu = new Menu("Edit");\r
57   MenuItem copy = new MenuItem("Copy (Jalview Only)");\r
58   MenuItem cut = new MenuItem("Cut (Jalview Only)");\r
59   MenuItem toUpper = new MenuItem("To Upper Case");\r
60   MenuItem toLower = new MenuItem("To Lower Case");\r
61   MenuItem toggleCase = new MenuItem("Toggle Case");\r
62   Menu outputmenu = new Menu();\r
63   Menu seqMenu = new Menu();\r
64   MenuItem pdb = new MenuItem();\r
65   MenuItem hideSeqs = new MenuItem();\r
66   MenuItem repGroup = new MenuItem();\r
67 \r
68   Sequence seq;\r
69   MenuItem revealAll = new MenuItem();\r
70 \r
71   public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links)\r
72   {\r
73     ///////////////////////////////////////////////////////////\r
74     // If this is activated from the sequence panel, the user may want to\r
75     // edit or annotate a particular residue. Therefore display the residue menu\r
76     //\r
77     // If from the IDPanel, we must display the sequence menu\r
78     //////////////////////////////////////////////////////////\r
79 \r
80     this.ap = apanel;\r
81     this.seq = seq;\r
82 \r
83     try\r
84     {\r
85       jbInit();\r
86     }\r
87     catch (Exception e)\r
88     {\r
89       e.printStackTrace();\r
90     }\r
91 \r
92     for (int i = 0; i < jalview.io.AppletFormatAdapter.formats.size()-1; i++)\r
93     {\r
94       MenuItem item = new MenuItem( (String) jalview.io.AppletFormatAdapter.formats.\r
95                                      elementAt(\r
96                                          i));\r
97       item.addActionListener(this);\r
98       outputmenu.add(item);\r
99     }\r
100 \r
101     SequenceGroup sg = ap.av.getSelectionGroup();\r
102 \r
103     if (sg != null && sg.getSize(false)>0)\r
104     {\r
105       showText.setState(sg.getDisplayText());\r
106       showColourText.setState(sg.getColourText());\r
107       showBoxes.setState(sg.getDisplayBoxes());\r
108       if (!ap.av.alignment.getGroups().contains(sg))\r
109       {\r
110         groupMenu.remove(unGroupMenuItem);\r
111       }\r
112 \r
113     }\r
114     else\r
115     {\r
116       remove(groupMenu);\r
117     }\r
118 \r
119     if (links!=null)\r
120     {\r
121       Menu linkMenu = new Menu("Link");\r
122       MenuItem item;\r
123       String link;\r
124       for(int i=0; i<links.size(); i++)\r
125       {\r
126         link = links.elementAt(i).toString();\r
127         final String target = link.substring(0, link.indexOf("|"));\r
128         item = new MenuItem(target);\r
129 \r
130         final String url;\r
131 \r
132         if (link.indexOf("$SEQUENCE_ID$") > -1)\r
133         {\r
134           String id = seq.getName();\r
135           if (id.indexOf("|") > -1)\r
136             id = id.substring(id.lastIndexOf("|") + 1);\r
137 \r
138           url = link.substring(link.indexOf("|") + 1,\r
139                                link.indexOf("$SEQUENCE_ID$"))\r
140               + id +\r
141               link.substring(link.indexOf("$SEQUENCE_ID$") + 13);\r
142         }\r
143         else\r
144           url = link.substring(link.lastIndexOf("|")+1);\r
145 \r
146            item.addActionListener(new java.awt.event.ActionListener()\r
147            {\r
148                public void actionPerformed(ActionEvent e)\r
149                {\r
150                   ap.alignFrame.showURL(url, target);\r
151                }\r
152            });\r
153           linkMenu.add(item);\r
154       }\r
155       seqMenu.add(linkMenu);\r
156     }\r
157     if(seq!=null)\r
158     {\r
159       seqMenu.setLabel(seq.getName());\r
160       repGroup.setLabel("Represent Group with " + seq.getName());\r
161     }\r
162     else\r
163       remove(seqMenu);\r
164 \r
165     if(!ap.av.hasHiddenRows)\r
166       remove(revealAll);\r
167   }\r
168 \r
169   public void itemStateChanged(ItemEvent evt)\r
170   {\r
171     if(evt.getSource()==abovePIDColour)\r
172       abovePIDColour_itemStateChanged();\r
173     else if(evt.getSource()==showColourText)\r
174       showColourText_itemStateChanged();\r
175     else if(evt.getSource()==showText)\r
176       showText_itemStateChanged();\r
177     else if(evt.getSource()==showBoxes)\r
178        showBoxes_itemStateChanged()   ;\r
179   }\r
180 \r
181   public void actionPerformed(ActionEvent evt)\r
182   {\r
183     Object source = evt.getSource();\r
184     if(source==clustalColour)\r
185       clustalColour_actionPerformed();\r
186     else if(source==zappoColour)\r
187       zappoColour_actionPerformed();\r
188     else if(source==taylorColour)\r
189       taylorColour_actionPerformed();\r
190     else if(source==hydrophobicityColour)\r
191       hydrophobicityColour_actionPerformed();\r
192     else if(source==helixColour)\r
193       helixColour_actionPerformed();\r
194     else if(source==strandColour)\r
195       strandColour_actionPerformed();\r
196     else if(source==clustalColour)\r
197       turnColour_actionPerformed();\r
198     else if(source==buriedColour)\r
199       buriedColour_actionPerformed();\r
200     else if(source==nucleotideMenuItem)\r
201       nucleotideMenuItem_actionPerformed();\r
202 \r
203     else if (source == userDefinedColour)\r
204       userDefinedColour_actionPerformed();\r
205     else if (source == PIDColour)\r
206       PIDColour_actionPerformed();\r
207     else if (source == BLOSUM62Colour)\r
208       BLOSUM62Colour_actionPerformed();\r
209     else if (source == noColourmenuItem)\r
210       noColourmenuItem_actionPerformed();\r
211     else if (source == conservationMenuItem)\r
212       conservationMenuItem_itemStateChanged();\r
213     else if (source == unGroupMenuItem)\r
214       unGroupMenuItem_actionPerformed();\r
215 \r
216     else if(source == pdb)\r
217       addPDB();\r
218     else if(source == hideSeqs)\r
219       hideSequences(false);\r
220     else if(source == repGroup)\r
221       hideSequences(true);\r
222     else if(source == revealAll)\r
223     {\r
224         ap.av.showAllHiddenSeqs();\r
225         ap.repaint();\r
226     }\r
227 \r
228     else if(source==copy)\r
229       ap.alignFrame.copy_actionPerformed();\r
230     else if(source==cut)\r
231       ap.alignFrame.cut_actionPerformed();\r
232     else if(source==toUpper || source==toLower || source==toggleCase)\r
233     {\r
234       SequenceGroup sg = ap.av.getSelectionGroup();\r
235       if (sg != null)\r
236       {\r
237         for (int g = 0; g < sg.getSize(true); g++)\r
238         {\r
239           if (source == toggleCase)\r
240            ((SequenceI) sg.getSequences(true).elementAt(g))\r
241           .toggleCase(sg.getStartRes(), sg.getEndRes() + 1);\r
242           else\r
243             ((SequenceI) sg.getSequences(true).elementAt(g))\r
244                 .changeCase(source == toUpper, sg.getStartRes(),\r
245                                            sg.getEndRes() + 1);\r
246         }\r
247         ap.seqPanel.seqCanvas.repaint();\r
248       }\r
249     }\r
250     else\r
251       outputText(evt);\r
252 \r
253   }\r
254 \r
255   void outputText(ActionEvent e)\r
256   {\r
257     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);\r
258     Vector vseqs = new Vector();\r
259 \r
260       String [] selection = ap.av.getViewAsString(true);\r
261       SequenceI [] seqs = ap.av.getSelectionAsNewSequence();\r
262       if (selection != null)\r
263       {\r
264         for (int i = 0; i < selection.length; i++)\r
265         {\r
266           Sequence seq = new Sequence(\r
267               seqs[i].getName(),\r
268               selection[i],\r
269               seqs[i].getStart(), seqs[i].getEnd());\r
270           seq.setDescription(seqs[i].getDescription());\r
271           vseqs.addElement( seq );\r
272       }\r
273     }\r
274 \r
275     Frame frame = new Frame();\r
276     frame.add(cap);\r
277     jalview.bin.JalviewLite.addFrame(frame,\r
278                                      "Selection output - " + e.getActionCommand(),\r
279                                      600, 500);\r
280 \r
281     cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(\r
282         e.getActionCommand(),\r
283         vseqs,\r
284         ap.av.showJVSuffix));\r
285 \r
286   }\r
287 \r
288   void addPDB()\r
289   {\r
290     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);\r
291     cap.setText("Paste your PDB file here.");\r
292     cap.setPDBImport(seq);\r
293     Frame frame = new Frame();\r
294     frame.add(cap);\r
295     jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);\r
296   }\r
297 \r
298   private void jbInit()\r
299       throws Exception\r
300   {\r
301     groupMenu.setLabel("Group");\r
302     groupMenu.setLabel("Selection");\r
303 \r
304     unGroupMenuItem.setLabel("Remove Group");\r
305     unGroupMenuItem.addActionListener(this);\r
306 \r
307     nucleotideMenuItem.setLabel("Nucleotide");\r
308     nucleotideMenuItem.addActionListener(this);\r
309     conservationMenuItem.addItemListener(this);\r
310     abovePIDColour.addItemListener(this);\r
311     colourMenu.setLabel("Group Colour");\r
312     showBoxes.setLabel("Boxes");\r
313     showBoxes.setState(true);\r
314     showBoxes.addItemListener(this);\r
315 \r
316     showText.setLabel("Text");\r
317     showText.addItemListener(this);\r
318     showColourText.setLabel("Colour Text");\r
319     showColourText.addItemListener(this);\r
320     outputmenu.setLabel("Output to Textbox...");\r
321     seqMenu.setLabel("Sequence");\r
322     pdb.setLabel("View PDB Structure");\r
323     hideSeqs.setLabel("Hide Sequences");\r
324     repGroup.setLabel("Represent Group with");\r
325     revealAll.setLabel("Reveal All");\r
326 \r
327     add(groupMenu);\r
328     this.add(seqMenu);\r
329     this.add(hideSeqs);\r
330     this.add(revealAll);\r
331     groupMenu.add(editMenu);\r
332     groupMenu.add(outputmenu);\r
333     groupMenu.addSeparator();\r
334     groupMenu.add(unGroupMenuItem);\r
335     groupMenu.add(colourMenu);\r
336     groupMenu.add(showBoxes);\r
337     groupMenu.add(showText);\r
338     groupMenu.add(showColourText);\r
339     colourMenu.add(noColourmenuItem);\r
340     colourMenu.add(clustalColour);\r
341     colourMenu.add(BLOSUM62Colour);\r
342     colourMenu.add(PIDColour);\r
343     colourMenu.add(zappoColour);\r
344     colourMenu.add(taylorColour);\r
345     colourMenu.add(hydrophobicityColour);\r
346     colourMenu.add(helixColour);\r
347     colourMenu.add(strandColour);\r
348     colourMenu.add(turnColour);\r
349     colourMenu.add(buriedColour);\r
350     colourMenu.add(nucleotideMenuItem);\r
351     colourMenu.add(userDefinedColour);\r
352     colourMenu.addSeparator();\r
353     colourMenu.add(abovePIDColour);\r
354     colourMenu.add(conservationMenuItem);\r
355 \r
356     noColourmenuItem.setLabel("None");\r
357     noColourmenuItem.addActionListener(this);\r
358 \r
359     clustalColour.setLabel("Clustalx colours");\r
360     clustalColour.addActionListener(this);\r
361     zappoColour.setLabel("Zappo");\r
362     zappoColour.addActionListener(this);\r
363     taylorColour.setLabel("Taylor");\r
364     taylorColour.addActionListener(this);\r
365     hydrophobicityColour.setLabel("Hydrophobicity");\r
366     hydrophobicityColour.addActionListener(this);\r
367     helixColour.setLabel("Helix propensity");\r
368     helixColour.addActionListener(this);\r
369     strandColour.setLabel("Strand propensity");\r
370     strandColour.addActionListener(this);\r
371     turnColour.setLabel("Turn propensity");\r
372     turnColour.addActionListener(this);\r
373     buriedColour.setLabel("Buried Index");\r
374     buriedColour.addActionListener(this);\r
375     abovePIDColour.setLabel("Above % Identity");\r
376 \r
377     userDefinedColour.setLabel("User Defined");\r
378     userDefinedColour.addActionListener(this);\r
379     PIDColour.setLabel("Percentage Identity");\r
380     PIDColour.addActionListener(this);\r
381     BLOSUM62Colour.setLabel("BLOSUM62");\r
382     BLOSUM62Colour.addActionListener(this);\r
383     conservationMenuItem.setLabel("Conservation");\r
384 \r
385     editMenu.add(copy);\r
386     copy.addActionListener(this);\r
387     editMenu.add(cut);\r
388     cut.addActionListener(this);\r
389     editMenu.add(toUpper);\r
390     toUpper.addActionListener(this);\r
391     editMenu.add(toLower);\r
392     toLower.addActionListener(this);\r
393     editMenu.add(toggleCase);\r
394     seqMenu.add(pdb);\r
395     seqMenu.add(repGroup);\r
396     toggleCase.addActionListener(this);\r
397     pdb.addActionListener(this);\r
398     hideSeqs.addActionListener(this);\r
399     repGroup.addActionListener(this);\r
400     revealAll.addActionListener(this);\r
401 \r
402   }\r
403 \r
404   void refresh()\r
405   {\r
406     ap.seqPanel.seqCanvas.repaint();\r
407     if(ap.overviewPanel!=null)\r
408       ap.overviewPanel.updateOverviewImage();\r
409   }\r
410 \r
411   protected void clustalColour_actionPerformed()\r
412   {\r
413     SequenceGroup sg = getGroup();\r
414     sg.cs = new ClustalxColourScheme(sg.getSequences(true), ap.av.alignment.getWidth());\r
415     refresh();\r
416   }\r
417 \r
418   protected void zappoColour_actionPerformed()\r
419   {\r
420     getGroup().cs = new ZappoColourScheme();\r
421     refresh();\r
422   }\r
423 \r
424   protected void taylorColour_actionPerformed()\r
425   {\r
426     getGroup().cs = new TaylorColourScheme();\r
427     refresh();\r
428   }\r
429 \r
430   protected void hydrophobicityColour_actionPerformed()\r
431   {\r
432     getGroup().cs = new HydrophobicColourScheme();\r
433     refresh();\r
434   }\r
435 \r
436   protected void helixColour_actionPerformed()\r
437   {\r
438     getGroup().cs = new HelixColourScheme();\r
439     refresh();\r
440   }\r
441 \r
442   protected void strandColour_actionPerformed()\r
443   {\r
444     getGroup().cs = new StrandColourScheme();\r
445     refresh();\r
446   }\r
447 \r
448   protected void turnColour_actionPerformed()\r
449   {\r
450     getGroup().cs = new TurnColourScheme();\r
451     refresh();\r
452   }\r
453 \r
454   protected void buriedColour_actionPerformed()\r
455   {\r
456     getGroup().cs = new BuriedColourScheme();\r
457     refresh();\r
458   }\r
459 \r
460   public void nucleotideMenuItem_actionPerformed()\r
461   {\r
462     getGroup().cs = new NucleotideColourScheme();\r
463     refresh();\r
464   }\r
465 \r
466   protected void abovePIDColour_itemStateChanged()\r
467   {\r
468     SequenceGroup sg = getGroup();\r
469     if(sg.cs==null)\r
470           return;\r
471 \r
472     if (abovePIDColour.getState())\r
473     {\r
474       sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,\r
475                                                ap.av.alignment.getWidth()));\r
476       int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,\r
477           getGroup().getName());\r
478 \r
479       sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());\r
480 \r
481       SliderPanel.showPIDSlider();\r
482 \r
483     }\r
484     else // remove PIDColouring\r
485     {\r
486       sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
487     }\r
488 \r
489     refresh();\r
490 \r
491   }\r
492 \r
493   protected void userDefinedColour_actionPerformed()\r
494   {\r
495     new UserDefinedColours(ap, getGroup());\r
496   }\r
497 \r
498   protected void PIDColour_actionPerformed()\r
499   {\r
500     SequenceGroup sg = getGroup();\r
501     sg.cs = new PIDColourScheme();\r
502     sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,\r
503                                              ap.av.alignment.getWidth()));\r
504     refresh();\r
505   }\r
506 \r
507   protected void BLOSUM62Colour_actionPerformed()\r
508   {\r
509     SequenceGroup sg = getGroup();\r
510 \r
511     sg.cs = new Blosum62ColourScheme();\r
512 \r
513     sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(true), 0,\r
514                                              ap.av.alignment.getWidth()));\r
515 \r
516     refresh();\r
517   }\r
518 \r
519   protected void noColourmenuItem_actionPerformed()\r
520   {\r
521     getGroup().cs = null;\r
522     refresh();\r
523   }\r
524 \r
525   protected void conservationMenuItem_itemStateChanged()\r
526   {\r
527     SequenceGroup sg = getGroup();\r
528     if(sg.cs==null)\r
529           return;\r
530 \r
531     if (conservationMenuItem.getState())\r
532     {\r
533 \r
534       Conservation c = new Conservation("Group",\r
535                                         ResidueProperties.propHash, 3,\r
536                                         sg.getSequences(true), 0,\r
537                                         ap.av.alignment.getWidth());\r
538 \r
539       c.calculate();\r
540       c.verdict(false, ap.av.ConsPercGaps);\r
541 \r
542       sg.cs.setConservation(c);\r
543 \r
544       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());\r
545       SliderPanel.showConservationSlider();\r
546     }\r
547     else // remove ConservationColouring\r
548     {\r
549       sg.cs.setConservation(null);\r
550     }\r
551 \r
552     refresh();\r
553   }\r
554 \r
555 \r
556   SequenceGroup getGroup()\r
557   {\r
558     SequenceGroup sg = ap.av.getSelectionGroup();\r
559 \r
560     // this method won't add a new group if it already exists\r
561     if(sg!=null)\r
562       ap.av.alignment.addGroup(sg);\r
563 \r
564     return sg;\r
565   }\r
566 \r
567   void unGroupMenuItem_actionPerformed()\r
568   {\r
569     SequenceGroup sg = ap.av.getSelectionGroup();\r
570     ap.av.alignment.deleteGroup(sg);\r
571     ap.av.setSelectionGroup(null);\r
572     ap.repaint();\r
573   }\r
574 \r
575   public void showColourText_itemStateChanged()\r
576   {\r
577     getGroup().setColourText(showColourText.getState());\r
578     refresh();\r
579   }\r
580 \r
581   public void showText_itemStateChanged()\r
582   {\r
583     getGroup().setDisplayText(showText.getState());\r
584     refresh();\r
585   }\r
586 \r
587   public void showBoxes_itemStateChanged()\r
588   {\r
589     getGroup().setDisplayBoxes(showBoxes.getState());\r
590     refresh();\r
591   }\r
592 \r
593   void hideSequences(boolean representGroup)\r
594   {\r
595     SequenceGroup sg = ap.av.getSelectionGroup();\r
596     if(sg==null || sg.getSize(false)<1)\r
597     {\r
598       ap.av.hideSequence(seq);\r
599       return;\r
600     }\r
601 \r
602       int index = 0;\r
603       while(index < sg.getSize(false))\r
604       {\r
605         if(representGroup && sg.getSequenceAt(index)!=seq)\r
606         {\r
607           seq.addHiddenSequence(sg.getSequenceAt(index));\r
608           ap.av.hideSequence(sg.getSequenceAt(index));\r
609         }\r
610         else if(!representGroup)\r
611         {\r
612           ap.av.hideSequence(sg.getSequenceAt(index));\r
613         }\r
614         index ++;\r
615       }\r
616 \r
617       ap.av.setSelectionGroup(null);\r
618       ap.repaint();\r
619       refresh();\r
620     }\r
621 \r
622 }\r