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