Jalview 2.6 source licence
[jalview.git] / src / jalview / appletgui / APopupMenu.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.appletgui;
19
20 import java.util.*;
21
22 import java.awt.*;
23 import java.awt.event.*;
24
25 import jalview.analysis.*;
26 import jalview.commands.*;
27 import jalview.datamodel.*;
28 import jalview.schemes.*;
29 import jalview.util.UrlLink;
30 import jalview.io.AppletFormatAdapter;
31
32 public class APopupMenu extends java.awt.PopupMenu implements
33         ActionListener, ItemListener
34 {
35   Menu groupMenu = new Menu();
36
37   MenuItem editGroupName = new MenuItem();
38
39   protected MenuItem clustalColour = new MenuItem();
40
41   protected MenuItem zappoColour = new MenuItem();
42
43   protected MenuItem taylorColour = new MenuItem();
44
45   protected MenuItem hydrophobicityColour = new MenuItem();
46
47   protected MenuItem helixColour = new MenuItem();
48
49   protected MenuItem strandColour = new MenuItem();
50
51   protected MenuItem turnColour = new MenuItem();
52
53   protected MenuItem buriedColour = new MenuItem();
54
55   protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();
56
57   protected MenuItem userDefinedColour = new MenuItem();
58
59   protected MenuItem PIDColour = new MenuItem();
60
61   protected MenuItem BLOSUM62Colour = new MenuItem();
62
63   MenuItem noColourmenuItem = new MenuItem();
64
65   protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
66
67   final AlignmentPanel ap;
68
69   MenuItem unGroupMenuItem = new MenuItem();
70
71   MenuItem nucleotideMenuItem = new MenuItem();
72
73   Menu colourMenu = new Menu();
74
75   CheckboxMenuItem showBoxes = new CheckboxMenuItem();
76
77   CheckboxMenuItem showText = new CheckboxMenuItem();
78
79   CheckboxMenuItem showColourText = new CheckboxMenuItem();
80
81   CheckboxMenuItem displayNonconserved = new CheckboxMenuItem();
82
83   Menu editMenu = new Menu("Edit");
84
85   MenuItem copy = new MenuItem("Copy (Jalview Only)");
86
87   MenuItem cut = new MenuItem("Cut (Jalview Only)");
88
89   MenuItem toUpper = new MenuItem("To Upper Case");
90
91   MenuItem toLower = new MenuItem("To Lower Case");
92
93   MenuItem toggleCase = new MenuItem("Toggle Case");
94
95   Menu outputmenu = new Menu();
96
97   Menu seqMenu = new Menu();
98
99   MenuItem pdb = new MenuItem();
100
101   MenuItem hideSeqs = new MenuItem();
102
103   MenuItem repGroup = new MenuItem();
104
105   MenuItem sequenceName = new MenuItem("Edit Name/Description");
106
107   MenuItem sequenceFeature = new MenuItem("Create Sequence Feature");
108
109   MenuItem editSequence = new MenuItem("Edit Sequence");
110
111   Sequence seq;
112
113   MenuItem revealAll = new MenuItem();
114
115   Menu menu1 = new Menu();
116
117   public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links)
118   {
119     // /////////////////////////////////////////////////////////
120     // If this is activated from the sequence panel, the user may want to
121     // edit or annotate a particular residue. Therefore display the residue menu
122     //
123     // If from the IDPanel, we must display the sequence menu
124     // ////////////////////////////////////////////////////////
125
126     this.ap = apanel;
127     this.seq = seq;
128
129     try
130     {
131       jbInit();
132     } catch (Exception e)
133     {
134       e.printStackTrace();
135     }
136
137     for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++)
138     {
139       MenuItem item = new MenuItem(
140               jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
141
142       item.addActionListener(this);
143       outputmenu.add(item);
144     }
145
146     SequenceGroup sg = ap.av.getSelectionGroup();
147
148     if (sg != null && sg.getSize() > 0)
149     {
150       editGroupName.setLabel(sg.getName());
151       showText.setState(sg.getDisplayText());
152       showColourText.setState(sg.getColourText());
153       showBoxes.setState(sg.getDisplayBoxes());
154       displayNonconserved.setState(sg.getShowNonconserved());
155       if (!ap.av.alignment.getGroups().contains(sg))
156       {
157         groupMenu.remove(unGroupMenuItem);
158       }
159
160     }
161     else
162     {
163       remove(hideSeqs);
164       remove(groupMenu);
165     }
166
167     if (links != null && links.size() > 0)
168     {
169       Menu linkMenu = new Menu("Link");
170       String link;
171       for (int i = 0; i < links.size(); i++)
172       {
173         link = links.elementAt(i).toString();
174         UrlLink urlLink = new UrlLink(link);
175         if (!urlLink.isValid())
176         {
177           System.err.println(urlLink.getInvalidMessage());
178           continue;
179         }
180         final String target = urlLink.getTarget(); // link.substring(0,
181         // link.indexOf("|"));
182         final String label = urlLink.getLabel();
183         if (urlLink.isDynamic())
184         {
185
186           // collect matching db-refs
187           DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq
188                   .getDBRef(), new String[]
189           { target });
190           // collect id string too
191           String id = seq.getName();
192           String descr = seq.getDescription();
193           if (descr != null && descr.length() < 1)
194           {
195             descr = null;
196           }
197           if (dbr != null)
198           {
199             for (int r = 0; r < dbr.length; r++)
200             {
201               if (id != null && dbr[r].getAccessionId().equals(id))
202               {
203                 // suppress duplicate link creation for the bare sequence ID
204                 // string with this link
205                 id = null;
206               }
207               // create Bare ID link for this RUL
208               String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(),
209                       true);
210               if (urls != null)
211               {
212                 for (int u = 0; u < urls.length; u += 2)
213                 {
214                   addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
215                 }
216               }
217             }
218           }
219           if (id != null)
220           {
221             // create Bare ID link for this RUL
222             String[] urls = urlLink.makeUrls(id, true);
223             if (urls != null)
224             {
225               for (int u = 0; u < urls.length; u += 2)
226               {
227                 addshowLink(linkMenu, label, urls[u + 1]);
228               }
229             }
230             // addshowLink(linkMenu, target, url_pref + id + url_suff);
231           }
232           // Now construct URLs from description but only try to do it for regex
233           // URL links
234           if (descr != null && urlLink.getRegexReplace() != null)
235           {
236             // create link for this URL from description only if regex matches
237             String[] urls = urlLink.makeUrls(descr, true);
238             if (urls != null)
239             {
240               for (int u = 0; u < urls.length; u += 2)
241               {
242                 addshowLink(linkMenu, label, urls[u + 1]);
243               }
244             }
245           }
246         }
247         else
248         {
249           addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1));
250         }
251         /*
252          * final String url;
253          * 
254          * if (link.indexOf("$SEQUENCE_ID$") > -1) { // Substitute SEQUENCE_ID
255          * string and any matching database reference accessions String url_pref
256          * = link.substring(link.indexOf("|") + 1,
257          * link.indexOf("$SEQUENCE_ID$"));
258          * 
259          * String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
260          * // collect matching db-refs DBRefEntry[] dbr =
261          * jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new
262          * String[]{target}); // collect id string too String id =
263          * seq.getName(); if (id.indexOf("|") > -1) { id =
264          * id.substring(id.lastIndexOf("|") + 1); } if (dbr!=null) { for (int
265          * r=0;r<dbr.length; r++) { if (dbr[r].getAccessionId().equals(id)) { //
266          * suppress duplicate link creation for the bare sequence ID string with
267          * this link id = null; } addshowLink(linkMenu,
268          * dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
269          * url_pref+dbr[r].getAccessionId()+url_suff); } } if (id!=null) { //
270          * create Bare ID link for this RUL addshowLink(linkMenu, target,
271          * url_pref + id + url_suff); } } else { addshowLink(linkMenu, target,
272          * link.substring(link.lastIndexOf("|")+1)); }
273          */
274       }
275       if (linkMenu.getItemCount() > 0)
276       {
277         if (seq != null)
278         {
279           seqMenu.add(linkMenu);
280         }
281         else
282         {
283           add(linkMenu);
284         }
285       }
286     }
287     // TODO: add group link menu entry here
288     if (seq != null)
289     {
290       seqMenu.setLabel(seq.getName());
291       repGroup.setLabel("Represent Group with " + seq.getName());
292     }
293     else
294     {
295       remove(seqMenu);
296     }
297
298     if (!ap.av.hasHiddenRows)
299     {
300       remove(revealAll);
301     }
302   }
303
304   /**
305    * add a show URL menu item to the given linkMenu
306    * 
307    * @param linkMenu
308    * @param target
309    *          - menu label string
310    * @param url
311    *          - url to open
312    */
313   private void addshowLink(Menu linkMenu, final String target,
314           final String url)
315   {
316     addshowLink(linkMenu, target, target, url);
317   }
318
319   /**
320    * add a show URL menu item to the given linkMenu
321    * 
322    * @param linkMenu
323    * @param target
324    *          - URL target window
325    * @param label
326    *          - menu label string
327    * @param url
328    *          - url to open
329    */
330   private void addshowLink(Menu linkMenu, final String target,
331           final String label, final String url)
332   {
333     MenuItem item = new MenuItem(label);
334     item.addActionListener(new java.awt.event.ActionListener()
335     {
336       public void actionPerformed(ActionEvent e)
337       {
338         ap.alignFrame.showURL(url, target);
339       }
340     });
341     linkMenu.add(item);
342   }
343
344   public void itemStateChanged(ItemEvent evt)
345   {
346     if (evt.getSource() == abovePIDColour)
347     {
348       abovePIDColour_itemStateChanged();
349     }
350     else if (evt.getSource() == showColourText)
351     {
352       showColourText_itemStateChanged();
353     }
354     else if (evt.getSource() == showText)
355     {
356       showText_itemStateChanged();
357     }
358     else if (evt.getSource() == showBoxes)
359     {
360       showBoxes_itemStateChanged();
361     }
362     else if (evt.getSource() == displayNonconserved)
363     {
364       this.showNonconserved_itemStateChanged();
365     }
366   }
367
368   public void actionPerformed(ActionEvent evt)
369   {
370     Object source = evt.getSource();
371     if (source == clustalColour)
372     {
373       clustalColour_actionPerformed();
374     }
375     else if (source == zappoColour)
376     {
377       zappoColour_actionPerformed();
378     }
379     else if (source == taylorColour)
380     {
381       taylorColour_actionPerformed();
382     }
383     else if (source == hydrophobicityColour)
384     {
385       hydrophobicityColour_actionPerformed();
386     }
387     else if (source == helixColour)
388     {
389       helixColour_actionPerformed();
390     }
391     else if (source == strandColour)
392     {
393       strandColour_actionPerformed();
394     }
395     else if (source == turnColour)
396     {
397       turnColour_actionPerformed();
398     }
399     else if (source == buriedColour)
400     {
401       buriedColour_actionPerformed();
402     }
403     else if (source == nucleotideMenuItem)
404     {
405       nucleotideMenuItem_actionPerformed();
406     }
407
408     else if (source == userDefinedColour)
409     {
410       userDefinedColour_actionPerformed();
411     }
412     else if (source == PIDColour)
413     {
414       PIDColour_actionPerformed();
415     }
416     else if (source == BLOSUM62Colour)
417     {
418       BLOSUM62Colour_actionPerformed();
419     }
420     else if (source == noColourmenuItem)
421     {
422       noColourmenuItem_actionPerformed();
423     }
424     else if (source == conservationMenuItem)
425     {
426       conservationMenuItem_itemStateChanged();
427     }
428     else if (source == unGroupMenuItem)
429     {
430       unGroupMenuItem_actionPerformed();
431     }
432
433     else if (source == sequenceName)
434     {
435       editName();
436     }
437     else if (source == pdb)
438     {
439       addPDB();
440     }
441     else if (source == hideSeqs)
442     {
443       hideSequences(false);
444     }
445     else if (source == repGroup)
446     {
447       hideSequences(true);
448     }
449     else if (source == revealAll)
450     {
451       ap.av.showAllHiddenSeqs();
452     }
453
454     else if (source == editGroupName)
455     {
456       EditNameDialog dialog = new EditNameDialog(getGroup().getName(),
457               getGroup().getDescription(), "       Group Name",
458               "Group Description", ap.alignFrame,
459               "Edit Group Name / Description", 500, 100, true);
460
461       if (dialog.accept)
462       {
463         getGroup().setName(dialog.getName().replace(' ', '_'));
464         getGroup().setDescription(dialog.getDescription());
465       }
466
467     }
468     else if (source == copy)
469     {
470       ap.alignFrame.copy_actionPerformed();
471     }
472     else if (source == cut)
473     {
474       ap.alignFrame.cut_actionPerformed();
475     }
476     else if (source == editSequence)
477     {
478       SequenceGroup sg = ap.av.getSelectionGroup();
479
480       if (sg != null)
481       {
482         if (seq == null)
483           seq = (Sequence) sg.getSequenceAt(0);
484
485         EditNameDialog dialog = new EditNameDialog(seq.getSequenceAsString(
486                 sg.getStartRes(), sg.getEndRes() + 1), null,
487                 "Edit Sequence ", null,
488
489                 ap.alignFrame, "Edit Sequence", 500, 100, true);
490
491         if (dialog.accept)
492         {
493           EditCommand editCommand = new EditCommand("Edit Sequences",
494                   EditCommand.REPLACE, dialog.getName().replace(' ',
495                           ap.av.getGapCharacter()), sg
496                           .getSequencesAsArray(ap.av.hiddenRepSequences),
497                   sg.getStartRes(), sg.getEndRes() + 1, ap.av.alignment);
498
499           ap.alignFrame.addHistoryItem(editCommand);
500
501           ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
502                   .getSequences());
503         }
504       }
505     }
506     else if (source == toUpper || source == toLower || source == toggleCase)
507     {
508       SequenceGroup sg = ap.av.getSelectionGroup();
509       Vector regions = new Vector();
510       if (sg != null)
511       {
512         int start = sg.getStartRes();
513         int end = sg.getEndRes() + 1;
514
515         do
516         {
517           if (ap.av.hasHiddenColumns)
518           {
519             if (start == 0)
520             {
521               start = ap.av.colSel.adjustForHiddenColumns(start);
522             }
523
524             end = ap.av.colSel.getHiddenBoundaryRight(start);
525             if (start == end)
526             {
527               end = sg.getEndRes() + 1;
528             }
529             if (end > sg.getEndRes())
530             {
531               end = sg.getEndRes() + 1;
532             }
533           }
534
535           regions.addElement(new int[]
536           { start, end });
537
538           if (ap.av.hasHiddenColumns)
539           {
540             start = ap.av.colSel.adjustForHiddenColumns(end);
541             start = ap.av.colSel.getHiddenBoundaryLeft(start) + 1;
542           }
543         } while (end < sg.getEndRes());
544
545         int[][] startEnd = new int[regions.size()][2];
546         for (int i = 0; i < regions.size(); i++)
547         {
548           startEnd[i] = (int[]) regions.elementAt(i);
549         }
550
551         String description;
552         int caseChange;
553
554         if (source == toggleCase)
555         {
556           description = "Toggle Case";
557           caseChange = ChangeCaseCommand.TOGGLE_CASE;
558         }
559         else if (source == toUpper)
560         {
561           description = "To Upper Case";
562           caseChange = ChangeCaseCommand.TO_UPPER;
563         }
564         else
565         {
566           description = "To Lower Case";
567           caseChange = ChangeCaseCommand.TO_LOWER;
568         }
569
570         ChangeCaseCommand caseCommand = new ChangeCaseCommand(description,
571                 sg.getSequencesAsArray(ap.av.hiddenRepSequences), startEnd,
572                 caseChange);
573
574         ap.alignFrame.addHistoryItem(caseCommand);
575
576         ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
577                 .getSequences());
578
579       }
580     }
581     else if (source == sequenceFeature)
582     {
583       SequenceGroup sg = ap.av.getSelectionGroup();
584       if (sg == null)
585       {
586         return;
587       }
588
589       int rsize = 0, gSize = sg.getSize();
590       SequenceI[] rseqs, seqs = new SequenceI[gSize];
591       SequenceFeature[] tfeatures, features = new SequenceFeature[gSize];
592
593       for (int i = 0; i < gSize; i++)
594       {
595         int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
596         int end = sg.findEndRes(sg.getSequenceAt(i));
597         if (start <= end)
598         {
599           seqs[rsize] = sg.getSequenceAt(i);
600           features[rsize] = new SequenceFeature(null, null, null, start,
601                   end, "Jalview");
602           rsize++;
603         }
604       }
605       rseqs = new SequenceI[rsize];
606       tfeatures = new SequenceFeature[rsize];
607       System.arraycopy(seqs, 0, rseqs, 0, rsize);
608       System.arraycopy(features, 0, tfeatures, 0, rsize);
609       features = tfeatures;
610       seqs = rseqs;
611
612       if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
613               features, true, ap))
614       {
615         ap.alignFrame.sequenceFeatures.setState(true);
616         ap.av.showSequenceFeatures(true);
617         ap.highlightSearchResults(null);
618       }
619     }
620     else
621     {
622       outputText(evt);
623     }
624
625   }
626
627   void outputText(ActionEvent e)
628   {
629     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
630
631     Frame frame = new Frame();
632     frame.add(cap);
633     jalview.bin.JalviewLite.addFrame(frame, "Selection output - "
634             + e.getActionCommand(), 600, 500);
635
636     cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(e
637             .getActionCommand(), new Alignment(ap.av
638             .getSelectionAsNewSequence()), ap.av.showJVSuffix));
639
640   }
641
642   void editName()
643   {
644     EditNameDialog dialog = new EditNameDialog(seq.getName(), seq
645             .getDescription(), "       Sequence Name",
646             "Sequence Description", ap.alignFrame,
647             "Edit Sequence Name / Description", 500, 100, true);
648
649     if (dialog.accept)
650     {
651       seq.setName(dialog.getName());
652       seq.setDescription(dialog.getDescription());
653       ap.paintAlignment(false);
654     }
655   }
656
657   void addPDB()
658   {
659     if (seq.getPDBId() != null)
660     {
661       PDBEntry entry = (PDBEntry) seq.getPDBId().firstElement();
662
663       if (ap.av.applet.jmolAvailable)
664         new jalview.appletgui.AppletJmol(entry, new Sequence[]
665         { seq }, null, ap, AppletFormatAdapter.URL);
666       else
667         new MCview.AppletPDBViewer(entry, new Sequence[]
668         { seq }, null, ap, AppletFormatAdapter.URL);
669
670     }
671     else
672     {
673       CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
674       cap.setText("Paste your PDB file here.");
675       cap.setPDBImport(seq);
676       Frame frame = new Frame();
677       frame.add(cap);
678       jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);
679     }
680   }
681
682   private void jbInit() throws Exception
683   {
684     groupMenu.setLabel("Group");
685     groupMenu.setLabel("Selection");
686     sequenceFeature.addActionListener(this);
687
688     editGroupName.addActionListener(this);
689     unGroupMenuItem.setLabel("Remove Group");
690     unGroupMenuItem.addActionListener(this);
691
692     nucleotideMenuItem.setLabel("Nucleotide");
693     nucleotideMenuItem.addActionListener(this);
694     conservationMenuItem.addItemListener(this);
695     abovePIDColour.addItemListener(this);
696     colourMenu.setLabel("Group Colour");
697     showBoxes.setLabel("Boxes");
698     showBoxes.setState(true);
699     showBoxes.addItemListener(this);
700     sequenceName.addActionListener(this);
701     displayNonconserved.setLabel("Show Nonconserved");
702     displayNonconserved.setState(false);
703     displayNonconserved.addItemListener(this);
704     showText.setLabel("Text");
705     showText.addItemListener(this);
706     showColourText.setLabel("Colour Text");
707     showColourText.addItemListener(this);
708     outputmenu.setLabel("Output to Textbox...");
709     seqMenu.setLabel("Sequence");
710     pdb.setLabel("View PDB Structure");
711     hideSeqs.setLabel("Hide Sequences");
712     repGroup.setLabel("Represent Group with");
713     revealAll.setLabel("Reveal All");
714     menu1.setLabel("Group");
715     add(groupMenu);
716     this.add(seqMenu);
717     this.add(hideSeqs);
718     this.add(revealAll);
719     groupMenu.add(editGroupName);
720     groupMenu.add(editMenu);
721     groupMenu.add(outputmenu);
722     groupMenu.add(sequenceFeature);
723     groupMenu.add(menu1);
724
725     colourMenu.add(noColourmenuItem);
726     colourMenu.add(clustalColour);
727     colourMenu.add(BLOSUM62Colour);
728     colourMenu.add(PIDColour);
729     colourMenu.add(zappoColour);
730     colourMenu.add(taylorColour);
731     colourMenu.add(hydrophobicityColour);
732     colourMenu.add(helixColour);
733     colourMenu.add(strandColour);
734     colourMenu.add(turnColour);
735     colourMenu.add(buriedColour);
736     colourMenu.add(nucleotideMenuItem);
737     colourMenu.add(userDefinedColour);
738     colourMenu.addSeparator();
739     colourMenu.add(abovePIDColour);
740     colourMenu.add(conservationMenuItem);
741
742     noColourmenuItem.setLabel("None");
743     noColourmenuItem.addActionListener(this);
744
745     clustalColour.setLabel("Clustalx colours");
746     clustalColour.addActionListener(this);
747     zappoColour.setLabel("Zappo");
748     zappoColour.addActionListener(this);
749     taylorColour.setLabel("Taylor");
750     taylorColour.addActionListener(this);
751     hydrophobicityColour.setLabel("Hydrophobicity");
752     hydrophobicityColour.addActionListener(this);
753     helixColour.setLabel("Helix propensity");
754     helixColour.addActionListener(this);
755     strandColour.setLabel("Strand propensity");
756     strandColour.addActionListener(this);
757     turnColour.setLabel("Turn propensity");
758     turnColour.addActionListener(this);
759     buriedColour.setLabel("Buried Index");
760     buriedColour.addActionListener(this);
761     abovePIDColour.setLabel("Above % Identity");
762
763     userDefinedColour.setLabel("User Defined");
764     userDefinedColour.addActionListener(this);
765     PIDColour.setLabel("Percentage Identity");
766     PIDColour.addActionListener(this);
767     BLOSUM62Colour.setLabel("BLOSUM62");
768     BLOSUM62Colour.addActionListener(this);
769     conservationMenuItem.setLabel("Conservation");
770
771     editMenu.add(copy);
772     copy.addActionListener(this);
773     editMenu.add(cut);
774     cut.addActionListener(this);
775
776     editMenu.add(editSequence);
777     editSequence.addActionListener(this);
778
779     editMenu.add(toUpper);
780     toUpper.addActionListener(this);
781     editMenu.add(toLower);
782     toLower.addActionListener(this);
783     editMenu.add(toggleCase);
784     seqMenu.add(sequenceName);
785     seqMenu.add(pdb);
786     seqMenu.add(repGroup);
787     menu1.add(unGroupMenuItem);
788     menu1.add(colourMenu);
789     menu1.add(showBoxes);
790     menu1.add(showText);
791     menu1.add(showColourText);
792     menu1.add(displayNonconserved);
793     toggleCase.addActionListener(this);
794     pdb.addActionListener(this);
795     hideSeqs.addActionListener(this);
796     repGroup.addActionListener(this);
797     revealAll.addActionListener(this);
798   }
799
800   void refresh()
801   {
802     ap.paintAlignment(true);
803   }
804
805   protected void clustalColour_actionPerformed()
806   {
807     SequenceGroup sg = getGroup();
808     sg.cs = new ClustalxColourScheme(sg
809             .getSequences(ap.av.hiddenRepSequences), ap.av.alignment
810             .getWidth());
811     refresh();
812   }
813
814   protected void zappoColour_actionPerformed()
815   {
816     getGroup().cs = new ZappoColourScheme();
817     refresh();
818   }
819
820   protected void taylorColour_actionPerformed()
821   {
822     getGroup().cs = new TaylorColourScheme();
823     refresh();
824   }
825
826   protected void hydrophobicityColour_actionPerformed()
827   {
828     getGroup().cs = new HydrophobicColourScheme();
829     refresh();
830   }
831
832   protected void helixColour_actionPerformed()
833   {
834     getGroup().cs = new HelixColourScheme();
835     refresh();
836   }
837
838   protected void strandColour_actionPerformed()
839   {
840     getGroup().cs = new StrandColourScheme();
841     refresh();
842   }
843
844   protected void turnColour_actionPerformed()
845   {
846     getGroup().cs = new TurnColourScheme();
847     refresh();
848   }
849
850   protected void buriedColour_actionPerformed()
851   {
852     getGroup().cs = new BuriedColourScheme();
853     refresh();
854   }
855
856   public void nucleotideMenuItem_actionPerformed()
857   {
858     getGroup().cs = new NucleotideColourScheme();
859     refresh();
860   }
861
862   protected void abovePIDColour_itemStateChanged()
863   {
864     SequenceGroup sg = getGroup();
865     if (sg.cs == null)
866     {
867       return;
868     }
869
870     if (abovePIDColour.getState())
871     {
872       sg.cs.setConsensus(AAFrequency.calculate(sg
873               .getSequences(ap.av.hiddenRepSequences), 0, ap.av.alignment
874               .getWidth()));
875       int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
876               .getName());
877
878       sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
879
880       SliderPanel.showPIDSlider();
881
882     }
883     else
884     // remove PIDColouring
885     {
886       sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
887     }
888
889     refresh();
890
891   }
892
893   protected void userDefinedColour_actionPerformed()
894   {
895     new UserDefinedColours(ap, getGroup());
896   }
897
898   protected void PIDColour_actionPerformed()
899   {
900     SequenceGroup sg = getGroup();
901     sg.cs = new PIDColourScheme();
902     sg.cs.setConsensus(AAFrequency.calculate(sg
903             .getSequences(ap.av.hiddenRepSequences), 0, ap.av.alignment
904             .getWidth()));
905     refresh();
906   }
907
908   protected void BLOSUM62Colour_actionPerformed()
909   {
910     SequenceGroup sg = getGroup();
911
912     sg.cs = new Blosum62ColourScheme();
913
914     sg.cs.setConsensus(AAFrequency.calculate(sg
915             .getSequences(ap.av.hiddenRepSequences), 0, ap.av.alignment
916             .getWidth()));
917
918     refresh();
919   }
920
921   protected void noColourmenuItem_actionPerformed()
922   {
923     getGroup().cs = null;
924     refresh();
925   }
926
927   protected void conservationMenuItem_itemStateChanged()
928   {
929     SequenceGroup sg = getGroup();
930     if (sg.cs == null)
931     {
932       return;
933     }
934
935     if (conservationMenuItem.getState())
936     {
937
938       Conservation c = new Conservation("Group",
939               ResidueProperties.propHash, 3, sg
940                       .getSequences(ap.av.hiddenRepSequences), 0,
941               ap.av.alignment.getWidth());
942
943       c.calculate();
944       c.verdict(false, ap.av.ConsPercGaps);
945
946       sg.cs.setConservation(c);
947
948       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
949       SliderPanel.showConservationSlider();
950     }
951     else
952     // remove ConservationColouring
953     {
954       sg.cs.setConservation(null);
955     }
956
957     refresh();
958   }
959
960   SequenceGroup getGroup()
961   {
962     SequenceGroup sg = ap.av.getSelectionGroup();
963
964     // this method won't add a new group if it already exists
965     if (sg != null)
966     {
967       ap.av.alignment.addGroup(sg);
968     }
969
970     return sg;
971   }
972
973   void unGroupMenuItem_actionPerformed()
974   {
975     SequenceGroup sg = ap.av.getSelectionGroup();
976     ap.av.alignment.deleteGroup(sg);
977     ap.av.setSelectionGroup(null);
978     ap.paintAlignment(true);
979   }
980
981   public void showColourText_itemStateChanged()
982   {
983     getGroup().setColourText(showColourText.getState());
984     refresh();
985   }
986
987   public void showText_itemStateChanged()
988   {
989     getGroup().setDisplayText(showText.getState());
990     refresh();
991   }
992
993   public void showNonconserved_itemStateChanged()
994   {
995     getGroup().setShowNonconserved(this.displayNonconserved.getState());
996     refresh();
997   }
998
999   public void showBoxes_itemStateChanged()
1000   {
1001     getGroup().setDisplayBoxes(showBoxes.getState());
1002     refresh();
1003   }
1004
1005   void hideSequences(boolean representGroup)
1006   {
1007     SequenceGroup sg = ap.av.getSelectionGroup();
1008     if (sg == null || sg.getSize() < 1)
1009     {
1010       ap.av.hideSequence(new SequenceI[]
1011       { seq });
1012       return;
1013     }
1014
1015     ap.av.setSelectionGroup(null);
1016
1017     if (representGroup)
1018     {
1019       ap.av.hideRepSequences(seq, sg);
1020
1021       return;
1022     }
1023
1024     int gsize = sg.getSize();
1025     SequenceI[] hseqs;
1026
1027     hseqs = new SequenceI[gsize];
1028
1029     int index = 0;
1030     for (int i = 0; i < gsize; i++)
1031     {
1032       hseqs[index++] = sg.getSequenceAt(i);
1033     }
1034
1035     ap.av.hideSequence(hseqs);
1036   }
1037
1038 }