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