2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3 * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
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.
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.
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
19 package jalview.appletgui;
24 import java.awt.event.*;
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;
33 public class APopupMenu
34 extends java.awt.PopupMenu implements ActionListener, ItemListener
36 Menu groupMenu = new Menu();
37 MenuItem editGroupName = new MenuItem();
38 protected MenuItem clustalColour = new MenuItem();
39 protected MenuItem zappoColour = new MenuItem();
40 protected MenuItem taylorColour = new MenuItem();
41 protected MenuItem hydrophobicityColour = new MenuItem();
42 protected MenuItem helixColour = new MenuItem();
43 protected MenuItem strandColour = new MenuItem();
44 protected MenuItem turnColour = new MenuItem();
45 protected MenuItem buriedColour = new MenuItem();
46 protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();
47 protected MenuItem userDefinedColour = new MenuItem();
48 protected MenuItem PIDColour = new MenuItem();
49 protected MenuItem BLOSUM62Colour = new MenuItem();
50 MenuItem noColourmenuItem = new MenuItem();
51 protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
53 final AlignmentPanel ap;
54 MenuItem unGroupMenuItem = new MenuItem();
55 MenuItem nucleotideMenuItem = new MenuItem();
56 Menu colourMenu = new Menu();
57 CheckboxMenuItem showBoxes = new CheckboxMenuItem();
58 CheckboxMenuItem showText = new CheckboxMenuItem();
59 CheckboxMenuItem showColourText = new CheckboxMenuItem();
60 Menu editMenu = new Menu("Edit");
61 MenuItem copy = new MenuItem("Copy (Jalview Only)");
62 MenuItem cut = new MenuItem("Cut (Jalview Only)");
63 MenuItem toUpper = new MenuItem("To Upper Case");
64 MenuItem toLower = new MenuItem("To Lower Case");
65 MenuItem toggleCase = new MenuItem("Toggle Case");
66 Menu outputmenu = new Menu();
67 Menu seqMenu = new Menu();
68 MenuItem pdb = new MenuItem();
69 MenuItem hideSeqs = new MenuItem();
70 MenuItem repGroup = new MenuItem();
71 MenuItem sequenceName = new MenuItem("Edit Name/Description");
72 MenuItem sequenceFeature = new MenuItem("Create Sequence Feature");
73 MenuItem editSequence = new MenuItem("Edit Sequence");
76 MenuItem revealAll = new MenuItem();
77 Menu menu1 = new Menu();
79 public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links)
81 ///////////////////////////////////////////////////////////
82 // If this is activated from the sequence panel, the user may want to
83 // edit or annotate a particular residue. Therefore display the residue menu
85 // If from the IDPanel, we must display the sequence menu
86 //////////////////////////////////////////////////////////
100 for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length;
103 MenuItem item = new MenuItem(jalview.io.AppletFormatAdapter.
104 WRITEABLE_FORMATS[i]);
106 item.addActionListener(this);
107 outputmenu.add(item);
110 SequenceGroup sg = ap.av.getSelectionGroup();
112 if (sg != null && sg.getSize() > 0)
114 editGroupName.setLabel(sg.getName());
115 showText.setState(sg.getDisplayText());
116 showColourText.setState(sg.getColourText());
117 showBoxes.setState(sg.getDisplayBoxes());
118 if (!ap.av.alignment.getGroups().contains(sg))
120 groupMenu.remove(unGroupMenuItem);
130 if (links != null && links.size()>0)
132 Menu linkMenu = new Menu("Link");
134 for (int i = 0; i < links.size(); i++)
136 link = links.elementAt(i).toString();
137 UrlLink urlLink = new UrlLink(link);
138 if (!urlLink.isValid())
140 System.err.println(urlLink.getInvalidMessage());
143 final String target = urlLink.getTarget(); // link.substring(0, link.indexOf("|"));
144 final String label = urlLink.getLabel();
145 if (urlLink.isDynamic())
148 // collect matching db-refs
149 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new String[]{target});
150 // collect id string too
151 String id = seq.getName();
154 for (int r=0;r<dbr.length; r++)
156 if (id!=null && dbr[r].getAccessionId().equals(id))
158 // suppress duplicate link creation for the bare sequence ID string with this link
161 // create Bare ID link for this RUL
162 String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
165 for (int u=0; u<urls.length; u+=2)
167 addshowLink(linkMenu, label+"|"+urls[u],urls[u+1]);
174 // create Bare ID link for this RUL
175 String[] urls = urlLink.makeUrls(id, true);
178 for (int u=0; u<urls.length; u+=2)
180 addshowLink(linkMenu, label,urls[u+1]);
183 // addshowLink(linkMenu, target, url_pref + id + url_suff);
186 addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1));
190 if (link.indexOf("$SEQUENCE_ID$") > -1)
192 // Substitute SEQUENCE_ID string and any matching database reference accessions
193 String url_pref = link.substring(link.indexOf("|") + 1,
194 link.indexOf("$SEQUENCE_ID$"));
196 String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
198 // collect matching db-refs
199 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new String[]{target});
200 // collect id string too
201 String id = seq.getName();
202 if (id.indexOf("|") > -1)
204 id = id.substring(id.lastIndexOf("|") + 1);
208 for (int r=0;r<dbr.length; r++)
210 if (dbr[r].getAccessionId().equals(id))
212 // suppress duplicate link creation for the bare sequence ID string with this link
215 addshowLink(linkMenu, dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
216 url_pref+dbr[r].getAccessionId()+url_suff);
221 // create Bare ID link for this RUL
222 addshowLink(linkMenu, target, url_pref + id + url_suff);
225 addshowLink(linkMenu, target, link.substring(link.lastIndexOf("|")+1));
231 seqMenu.add(linkMenu);
240 seqMenu.setLabel(seq.getName());
241 repGroup.setLabel("Represent Group with " + seq.getName());
248 if (!ap.av.hasHiddenRows)
254 * add a show URL menu item to the given linkMenu
256 * @param target - menu label string
257 * @param url - url to open
259 private void addshowLink(Menu linkMenu, final String target, final String url)
261 addshowLink(linkMenu, target, target, url);
264 * add a show URL menu item to the given linkMenu
266 * @param target - URL target window
267 * @param label - menu label string
268 * @param url - url to open
270 private void addshowLink(Menu linkMenu, final String target, final String label, final String url)
272 MenuItem item = new MenuItem(label);
273 item.addActionListener(new java.awt.event.ActionListener()
275 public void actionPerformed(ActionEvent e)
277 ap.alignFrame.showURL(url, target);
284 public void itemStateChanged(ItemEvent evt)
286 if (evt.getSource() == abovePIDColour)
288 abovePIDColour_itemStateChanged();
290 else if (evt.getSource() == showColourText)
292 showColourText_itemStateChanged();
294 else if (evt.getSource() == showText)
296 showText_itemStateChanged();
298 else if (evt.getSource() == showBoxes)
300 showBoxes_itemStateChanged();
304 public void actionPerformed(ActionEvent evt)
306 Object source = evt.getSource();
307 if (source == clustalColour)
309 clustalColour_actionPerformed();
311 else if (source == zappoColour)
313 zappoColour_actionPerformed();
315 else if (source == taylorColour)
317 taylorColour_actionPerformed();
319 else if (source == hydrophobicityColour)
321 hydrophobicityColour_actionPerformed();
323 else if (source == helixColour)
325 helixColour_actionPerformed();
327 else if (source == strandColour)
329 strandColour_actionPerformed();
331 else if (source == turnColour)
333 turnColour_actionPerformed();
335 else if (source == buriedColour)
337 buriedColour_actionPerformed();
339 else if (source == nucleotideMenuItem)
341 nucleotideMenuItem_actionPerformed();
344 else if (source == userDefinedColour)
346 userDefinedColour_actionPerformed();
348 else if (source == PIDColour)
350 PIDColour_actionPerformed();
352 else if (source == BLOSUM62Colour)
354 BLOSUM62Colour_actionPerformed();
356 else if (source == noColourmenuItem)
358 noColourmenuItem_actionPerformed();
360 else if (source == conservationMenuItem)
362 conservationMenuItem_itemStateChanged();
364 else if (source == unGroupMenuItem)
366 unGroupMenuItem_actionPerformed();
369 else if (source == sequenceName)
373 else if (source == pdb)
377 else if (source == hideSeqs)
379 hideSequences(false);
381 else if (source == repGroup)
385 else if (source == revealAll)
387 ap.av.showAllHiddenSeqs();
390 else if (source == editGroupName)
392 EditNameDialog dialog = new EditNameDialog(
393 getGroup().getName(),
394 getGroup().getDescription(),
398 "Edit Group Name / Description",
403 getGroup().setName(dialog.getName().replace(' ', '_'));
404 getGroup().setDescription(dialog.getDescription());
408 else if (source == copy)
410 ap.alignFrame.copy_actionPerformed();
412 else if (source == cut)
414 ap.alignFrame.cut_actionPerformed();
416 else if(source == editSequence)
418 SequenceGroup sg = ap.av.getSelectionGroup();
423 seq = (Sequence) sg.getSequenceAt(0);
425 EditNameDialog dialog = new EditNameDialog(seq.getSequenceAsString(
438 EditCommand editCommand = new EditCommand(
439 "Edit Sequences", EditCommand.REPLACE,
440 dialog.getName().replace(' ', ap.av.getGapCharacter()),
441 sg.getSequencesAsArray(ap.av.hiddenRepSequences),
442 sg.getStartRes(), sg.getEndRes()+1, ap.av.alignment
445 ap.alignFrame.addHistoryItem(editCommand);
447 ap.av.firePropertyChange("alignment", null,
448 ap.av.getAlignment().getSequences());
452 else if (source == toUpper || source == toLower || source == toggleCase)
454 SequenceGroup sg = ap.av.getSelectionGroup();
455 Vector regions = new Vector();
458 int start = sg.getStartRes();
459 int end = sg.getEndRes() + 1;
463 if (ap.av.hasHiddenColumns)
467 start = ap.av.colSel.adjustForHiddenColumns(start);
470 end = ap.av.colSel.getHiddenBoundaryRight(start);
473 end = sg.getEndRes() + 1;
475 if (end > sg.getEndRes())
477 end = sg.getEndRes() + 1;
481 regions.addElement(new int[]
484 if (ap.av.hasHiddenColumns)
486 start = ap.av.colSel.adjustForHiddenColumns(end);
487 start = ap.av.colSel.getHiddenBoundaryLeft(start) + 1;
490 while (end < sg.getEndRes());
492 int[][] startEnd = new int[regions.size()][2];
493 for (int i = 0; i < regions.size(); i++)
495 startEnd[i] = (int[]) regions.elementAt(i);
501 if (source == toggleCase)
503 description = "Toggle Case";
504 caseChange = ChangeCaseCommand.TOGGLE_CASE;
506 else if (source == toUpper)
508 description = "To Upper Case";
509 caseChange = ChangeCaseCommand.TO_UPPER;
513 description = "To Lower Case";
514 caseChange = ChangeCaseCommand.TO_LOWER;
517 ChangeCaseCommand caseCommand = new ChangeCaseCommand(
518 description, sg.getSequencesAsArray(ap.av.hiddenRepSequences),
522 ap.alignFrame.addHistoryItem(caseCommand);
524 ap.av.firePropertyChange("alignment", null,
525 ap.av.getAlignment().getSequences());
529 else if(source == sequenceFeature)
531 SequenceGroup sg = ap.av.getSelectionGroup();
537 int gSize = sg.getSize();
538 SequenceI[] seqs = new SequenceI[gSize];
539 SequenceFeature[] features = new SequenceFeature[gSize];
541 for (int i = 0; i < gSize; i++)
543 seqs[i] = sg.getSequenceAt(i);
544 int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
545 int end = sg.findEndRes(sg.getSequenceAt(i));
546 features[i] = new SequenceFeature(null, null, null, start, end,
550 if (ap.seqPanel.seqCanvas.getFeatureRenderer()
551 .amendFeatures(seqs, features, true, ap))
553 ap.alignFrame.sequenceFeatures.setState(true);
554 ap.av.showSequenceFeatures(true);
555 ap.highlightSearchResults(null);
565 void outputText(ActionEvent e)
567 CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
569 Frame frame = new Frame();
571 jalview.bin.JalviewLite.addFrame(frame,
572 "Selection output - " + e.getActionCommand(),
575 cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(
576 e.getActionCommand(),
577 new Alignment(ap.av.getSelectionAsNewSequence()),
578 ap.av.showJVSuffix));
584 EditNameDialog dialog = new EditNameDialog(
586 seq.getDescription(),
588 "Sequence Description",
590 "Edit Sequence Name / Description",
595 seq.setName(dialog.getName());
596 seq.setDescription(dialog.getDescription());
597 ap.paintAlignment(false);
603 if(seq.getPDBId()!=null)
605 PDBEntry entry = (PDBEntry)seq.getPDBId().firstElement();
607 if ( ap.av.applet.jmolAvailable )
608 new jalview.appletgui.AppletJmol(entry,
612 AppletFormatAdapter.URL);
614 new MCview.AppletPDBViewer(entry,
618 AppletFormatAdapter.URL);
623 CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
624 cap.setText("Paste your PDB file here.");
625 cap.setPDBImport(seq);
626 Frame frame = new Frame();
628 jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);
632 private void jbInit()
635 groupMenu.setLabel("Group");
636 groupMenu.setLabel("Selection");
637 sequenceFeature.addActionListener(this);
639 editGroupName.addActionListener(this);
640 unGroupMenuItem.setLabel("Remove Group");
641 unGroupMenuItem.addActionListener(this);
643 nucleotideMenuItem.setLabel("Nucleotide");
644 nucleotideMenuItem.addActionListener(this);
645 conservationMenuItem.addItemListener(this);
646 abovePIDColour.addItemListener(this);
647 colourMenu.setLabel("Group Colour");
648 showBoxes.setLabel("Boxes");
649 showBoxes.setState(true);
650 showBoxes.addItemListener(this);
651 sequenceName.addActionListener(this);
653 showText.setLabel("Text");
654 showText.addItemListener(this);
655 showColourText.setLabel("Colour Text");
656 showColourText.addItemListener(this);
657 outputmenu.setLabel("Output to Textbox...");
658 seqMenu.setLabel("Sequence");
659 pdb.setLabel("View PDB Structure");
660 hideSeqs.setLabel("Hide Sequences");
661 repGroup.setLabel("Represent Group with");
662 revealAll.setLabel("Reveal All");
663 menu1.setLabel("Group");
668 groupMenu.add(editGroupName);
669 groupMenu.add(editMenu);
670 groupMenu.add(outputmenu);
671 groupMenu.add(sequenceFeature);
672 groupMenu.add(menu1);
674 colourMenu.add(noColourmenuItem);
675 colourMenu.add(clustalColour);
676 colourMenu.add(BLOSUM62Colour);
677 colourMenu.add(PIDColour);
678 colourMenu.add(zappoColour);
679 colourMenu.add(taylorColour);
680 colourMenu.add(hydrophobicityColour);
681 colourMenu.add(helixColour);
682 colourMenu.add(strandColour);
683 colourMenu.add(turnColour);
684 colourMenu.add(buriedColour);
685 colourMenu.add(nucleotideMenuItem);
686 colourMenu.add(userDefinedColour);
687 colourMenu.addSeparator();
688 colourMenu.add(abovePIDColour);
689 colourMenu.add(conservationMenuItem);
691 noColourmenuItem.setLabel("None");
692 noColourmenuItem.addActionListener(this);
694 clustalColour.setLabel("Clustalx colours");
695 clustalColour.addActionListener(this);
696 zappoColour.setLabel("Zappo");
697 zappoColour.addActionListener(this);
698 taylorColour.setLabel("Taylor");
699 taylorColour.addActionListener(this);
700 hydrophobicityColour.setLabel("Hydrophobicity");
701 hydrophobicityColour.addActionListener(this);
702 helixColour.setLabel("Helix propensity");
703 helixColour.addActionListener(this);
704 strandColour.setLabel("Strand propensity");
705 strandColour.addActionListener(this);
706 turnColour.setLabel("Turn propensity");
707 turnColour.addActionListener(this);
708 buriedColour.setLabel("Buried Index");
709 buriedColour.addActionListener(this);
710 abovePIDColour.setLabel("Above % Identity");
712 userDefinedColour.setLabel("User Defined");
713 userDefinedColour.addActionListener(this);
714 PIDColour.setLabel("Percentage Identity");
715 PIDColour.addActionListener(this);
716 BLOSUM62Colour.setLabel("BLOSUM62");
717 BLOSUM62Colour.addActionListener(this);
718 conservationMenuItem.setLabel("Conservation");
721 copy.addActionListener(this);
723 cut.addActionListener(this);
725 editMenu.add(editSequence);
726 editSequence.addActionListener(this);
728 editMenu.add(toUpper);
729 toUpper.addActionListener(this);
730 editMenu.add(toLower);
731 toLower.addActionListener(this);
732 editMenu.add(toggleCase);
733 seqMenu.add(sequenceName);
735 seqMenu.add(repGroup);
736 menu1.add(unGroupMenuItem);
737 menu1.add(colourMenu);
738 menu1.add(showBoxes);
740 menu1.add(showColourText);
741 toggleCase.addActionListener(this);
742 pdb.addActionListener(this);
743 hideSeqs.addActionListener(this);
744 repGroup.addActionListener(this);
745 revealAll.addActionListener(this);
750 ap.paintAlignment(true);
753 protected void clustalColour_actionPerformed()
755 SequenceGroup sg = getGroup();
756 sg.cs = new ClustalxColourScheme(sg.getSequences(ap.av.hiddenRepSequences),
757 ap.av.alignment.getWidth());
761 protected void zappoColour_actionPerformed()
763 getGroup().cs = new ZappoColourScheme();
767 protected void taylorColour_actionPerformed()
769 getGroup().cs = new TaylorColourScheme();
773 protected void hydrophobicityColour_actionPerformed()
775 getGroup().cs = new HydrophobicColourScheme();
779 protected void helixColour_actionPerformed()
781 getGroup().cs = new HelixColourScheme();
785 protected void strandColour_actionPerformed()
787 getGroup().cs = new StrandColourScheme();
791 protected void turnColour_actionPerformed()
793 getGroup().cs = new TurnColourScheme();
797 protected void buriedColour_actionPerformed()
799 getGroup().cs = new BuriedColourScheme();
803 public void nucleotideMenuItem_actionPerformed()
805 getGroup().cs = new NucleotideColourScheme();
809 protected void abovePIDColour_itemStateChanged()
811 SequenceGroup sg = getGroup();
817 if (abovePIDColour.getState())
819 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
820 hiddenRepSequences), 0,
821 ap.av.alignment.getWidth()));
822 int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,
823 getGroup().getName());
825 sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
827 SliderPanel.showPIDSlider();
830 else // remove PIDColouring
832 sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
839 protected void userDefinedColour_actionPerformed()
841 new UserDefinedColours(ap, getGroup());
844 protected void PIDColour_actionPerformed()
846 SequenceGroup sg = getGroup();
847 sg.cs = new PIDColourScheme();
848 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
849 hiddenRepSequences), 0,
850 ap.av.alignment.getWidth()));
854 protected void BLOSUM62Colour_actionPerformed()
856 SequenceGroup sg = getGroup();
858 sg.cs = new Blosum62ColourScheme();
860 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
861 hiddenRepSequences), 0,
862 ap.av.alignment.getWidth()));
867 protected void noColourmenuItem_actionPerformed()
869 getGroup().cs = null;
873 protected void conservationMenuItem_itemStateChanged()
875 SequenceGroup sg = getGroup();
881 if (conservationMenuItem.getState())
884 Conservation c = new Conservation("Group",
885 ResidueProperties.propHash, 3,
886 sg.getSequences(ap.av.
887 hiddenRepSequences), 0,
888 ap.av.alignment.getWidth());
891 c.verdict(false, ap.av.ConsPercGaps);
893 sg.cs.setConservation(c);
895 SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
896 SliderPanel.showConservationSlider();
898 else // remove ConservationColouring
900 sg.cs.setConservation(null);
906 SequenceGroup getGroup()
908 SequenceGroup sg = ap.av.getSelectionGroup();
910 // this method won't add a new group if it already exists
913 ap.av.alignment.addGroup(sg);
919 void unGroupMenuItem_actionPerformed()
921 SequenceGroup sg = ap.av.getSelectionGroup();
922 ap.av.alignment.deleteGroup(sg);
923 ap.av.setSelectionGroup(null);
924 ap.paintAlignment(true);
927 public void showColourText_itemStateChanged()
929 getGroup().setColourText(showColourText.getState());
933 public void showText_itemStateChanged()
935 getGroup().setDisplayText(showText.getState());
939 public void showBoxes_itemStateChanged()
941 getGroup().setDisplayBoxes(showBoxes.getState());
945 void hideSequences(boolean representGroup)
947 SequenceGroup sg = ap.av.getSelectionGroup();
948 if (sg == null || sg.getSize() < 1)
950 ap.av.hideSequence(new SequenceI[]
955 ap.av.setSelectionGroup(null);
959 ap.av.hideRepSequences(seq, sg);
964 int gsize = sg.getSize();
967 hseqs = new SequenceI[gsize];
970 for (int i = 0; i < gsize; i++)
972 hseqs[index++] = sg.getSequenceAt(i);
975 ap.av.hideSequence(hseqs);