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