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