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