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