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