2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 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
20 package jalview.appletgui;
25 import java.awt.event.*;
27 import jalview.analysis.*;
28 import jalview.commands.*;
29 import jalview.datamodel.*;
30 import jalview.schemes.*;
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 final String target = link.substring(0, link.indexOf("|"));
141 if (link.indexOf("$SEQUENCE_ID$") > -1)
143 // Substitute SEQUENCE_ID string and any matching database reference accessions
144 String url_pref = link.substring(link.indexOf("|") + 1,
145 link.indexOf("$SEQUENCE_ID$"));
147 String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
149 // collect matching db-refs
150 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new String[]{target});
151 // collect id string too
152 String id = seq.getName();
153 if (id.indexOf("|") > -1)
155 id = id.substring(id.lastIndexOf("|") + 1);
159 for (int r=0;r<dbr.length; r++)
161 if (dbr[r].getAccessionId().equals(id))
163 // suppress duplicate link creation for the bare sequence ID string with this link
166 addshowLink(linkMenu, dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
167 url_pref+dbr[r].getAccessionId()+url_suff);
172 // create Bare ID link for this RUL
173 addshowLink(linkMenu, target, url_pref + id + url_suff);
176 addshowLink(linkMenu, target, link.substring(link.lastIndexOf("|")+1));
182 seqMenu.add(linkMenu);
191 seqMenu.setLabel(seq.getName());
192 repGroup.setLabel("Represent Group with " + seq.getName());
199 if (!ap.av.hasHiddenRows)
205 * add a show URL menu item to the given linkMenu
207 * @param target - menu label string
208 * @param url - url to open
210 private void addshowLink(Menu linkMenu, final String target, final String url)
212 addshowLink(linkMenu, target, target, url);
215 * add a show URL menu item to the given linkMenu
217 * @param target - URL target window
218 * @param label - menu label string
219 * @param url - url to open
221 private void addshowLink(Menu linkMenu, final String target, final String label, final String url)
223 MenuItem item = new MenuItem(label);
224 item.addActionListener(new java.awt.event.ActionListener()
226 public void actionPerformed(ActionEvent e)
228 ap.alignFrame.showURL(url, target);
235 public void itemStateChanged(ItemEvent evt)
237 if (evt.getSource() == abovePIDColour)
239 abovePIDColour_itemStateChanged();
241 else if (evt.getSource() == showColourText)
243 showColourText_itemStateChanged();
245 else if (evt.getSource() == showText)
247 showText_itemStateChanged();
249 else if (evt.getSource() == showBoxes)
251 showBoxes_itemStateChanged();
255 public void actionPerformed(ActionEvent evt)
257 Object source = evt.getSource();
258 if (source == clustalColour)
260 clustalColour_actionPerformed();
262 else if (source == zappoColour)
264 zappoColour_actionPerformed();
266 else if (source == taylorColour)
268 taylorColour_actionPerformed();
270 else if (source == hydrophobicityColour)
272 hydrophobicityColour_actionPerformed();
274 else if (source == helixColour)
276 helixColour_actionPerformed();
278 else if (source == strandColour)
280 strandColour_actionPerformed();
282 else if (source == turnColour)
284 turnColour_actionPerformed();
286 else if (source == buriedColour)
288 buriedColour_actionPerformed();
290 else if (source == nucleotideMenuItem)
292 nucleotideMenuItem_actionPerformed();
295 else if (source == userDefinedColour)
297 userDefinedColour_actionPerformed();
299 else if (source == PIDColour)
301 PIDColour_actionPerformed();
303 else if (source == BLOSUM62Colour)
305 BLOSUM62Colour_actionPerformed();
307 else if (source == noColourmenuItem)
309 noColourmenuItem_actionPerformed();
311 else if (source == conservationMenuItem)
313 conservationMenuItem_itemStateChanged();
315 else if (source == unGroupMenuItem)
317 unGroupMenuItem_actionPerformed();
320 else if (source == sequenceName)
324 else if (source == pdb)
328 else if (source == hideSeqs)
330 hideSequences(false);
332 else if (source == repGroup)
336 else if (source == revealAll)
338 ap.av.showAllHiddenSeqs();
341 else if (source == editGroupName)
343 EditNameDialog dialog = new EditNameDialog(
344 getGroup().getName(),
345 getGroup().getDescription(),
349 "Edit Group Name / Description",
354 getGroup().setName(dialog.getName().replace(' ', '_'));
355 getGroup().setDescription(dialog.getDescription());
359 else if (source == copy)
361 ap.alignFrame.copy_actionPerformed();
363 else if (source == cut)
365 ap.alignFrame.cut_actionPerformed();
367 else if(source == editSequence)
369 SequenceGroup sg = ap.av.getSelectionGroup();
374 seq = (Sequence) sg.getSequenceAt(0);
376 EditNameDialog dialog = new EditNameDialog(seq.getSequenceAsString(
389 EditCommand editCommand = new EditCommand(
390 "Edit Sequences", EditCommand.REPLACE,
391 dialog.getName().replace(' ', ap.av.getGapCharacter()),
392 sg.getSequencesAsArray(ap.av.hiddenRepSequences),
393 sg.getStartRes(), sg.getEndRes()+1, ap.av.alignment
396 ap.alignFrame.addHistoryItem(editCommand);
398 ap.av.firePropertyChange("alignment", null,
399 ap.av.getAlignment().getSequences());
403 else if (source == toUpper || source == toLower || source == toggleCase)
405 SequenceGroup sg = ap.av.getSelectionGroup();
406 Vector regions = new Vector();
409 int start = sg.getStartRes();
410 int end = sg.getEndRes() + 1;
414 if (ap.av.hasHiddenColumns)
418 start = ap.av.colSel.adjustForHiddenColumns(start);
421 end = ap.av.colSel.getHiddenBoundaryRight(start);
424 end = sg.getEndRes() + 1;
426 if (end > sg.getEndRes())
428 end = sg.getEndRes() + 1;
432 regions.addElement(new int[]
435 if (ap.av.hasHiddenColumns)
437 start = ap.av.colSel.adjustForHiddenColumns(end);
438 start = ap.av.colSel.getHiddenBoundaryLeft(start) + 1;
441 while (end < sg.getEndRes());
443 int[][] startEnd = new int[regions.size()][2];
444 for (int i = 0; i < regions.size(); i++)
446 startEnd[i] = (int[]) regions.elementAt(i);
452 if (source == toggleCase)
454 description = "Toggle Case";
455 caseChange = ChangeCaseCommand.TOGGLE_CASE;
457 else if (source == toUpper)
459 description = "To Upper Case";
460 caseChange = ChangeCaseCommand.TO_UPPER;
464 description = "To Lower Case";
465 caseChange = ChangeCaseCommand.TO_LOWER;
468 ChangeCaseCommand caseCommand = new ChangeCaseCommand(
469 description, sg.getSequencesAsArray(ap.av.hiddenRepSequences),
473 ap.alignFrame.addHistoryItem(caseCommand);
475 ap.av.firePropertyChange("alignment", null,
476 ap.av.getAlignment().getSequences());
480 else if(source == sequenceFeature)
482 SequenceGroup sg = ap.av.getSelectionGroup();
488 int gSize = sg.getSize();
489 SequenceI[] seqs = new SequenceI[gSize];
490 SequenceFeature[] features = new SequenceFeature[gSize];
492 for (int i = 0; i < gSize; i++)
494 seqs[i] = sg.getSequenceAt(i);
495 int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
496 int end = sg.findEndRes(sg.getSequenceAt(i));
497 features[i] = new SequenceFeature(null, null, null, start, end,
501 if (ap.seqPanel.seqCanvas.getFeatureRenderer()
502 .amendFeatures(seqs, features, true, ap))
504 ap.alignFrame.sequenceFeatures.setState(true);
505 ap.av.showSequenceFeatures(true);
506 ap.highlightSearchResults(null);
516 void outputText(ActionEvent e)
518 CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
520 Frame frame = new Frame();
522 jalview.bin.JalviewLite.addFrame(frame,
523 "Selection output - " + e.getActionCommand(),
526 cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(
527 e.getActionCommand(),
528 new Alignment(ap.av.getSelectionAsNewSequence()),
529 ap.av.showJVSuffix));
535 EditNameDialog dialog = new EditNameDialog(
537 seq.getDescription(),
539 "Sequence Description",
541 "Edit Sequence Name / Description",
546 seq.setName(dialog.getName());
547 seq.setDescription(dialog.getDescription());
548 ap.paintAlignment(false);
554 if(seq.getPDBId()!=null)
556 PDBEntry entry = (PDBEntry)seq.getPDBId().firstElement();
558 if ( ap.av.applet.jmolAvailable )
559 new jalview.appletgui.AppletJmol(entry,
563 AppletFormatAdapter.URL);
565 new MCview.AppletPDBViewer(entry,
569 AppletFormatAdapter.URL);
574 CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
575 cap.setText("Paste your PDB file here.");
576 cap.setPDBImport(seq);
577 Frame frame = new Frame();
579 jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);
583 private void jbInit()
586 groupMenu.setLabel("Group");
587 groupMenu.setLabel("Selection");
588 sequenceFeature.addActionListener(this);
590 editGroupName.addActionListener(this);
591 unGroupMenuItem.setLabel("Remove Group");
592 unGroupMenuItem.addActionListener(this);
594 nucleotideMenuItem.setLabel("Nucleotide");
595 nucleotideMenuItem.addActionListener(this);
596 conservationMenuItem.addItemListener(this);
597 abovePIDColour.addItemListener(this);
598 colourMenu.setLabel("Group Colour");
599 showBoxes.setLabel("Boxes");
600 showBoxes.setState(true);
601 showBoxes.addItemListener(this);
602 sequenceName.addActionListener(this);
604 showText.setLabel("Text");
605 showText.addItemListener(this);
606 showColourText.setLabel("Colour Text");
607 showColourText.addItemListener(this);
608 outputmenu.setLabel("Output to Textbox...");
609 seqMenu.setLabel("Sequence");
610 pdb.setLabel("View PDB Structure");
611 hideSeqs.setLabel("Hide Sequences");
612 repGroup.setLabel("Represent Group with");
613 revealAll.setLabel("Reveal All");
614 menu1.setLabel("Group");
619 groupMenu.add(editGroupName);
620 groupMenu.add(editMenu);
621 groupMenu.add(outputmenu);
622 groupMenu.add(sequenceFeature);
623 groupMenu.add(menu1);
625 colourMenu.add(noColourmenuItem);
626 colourMenu.add(clustalColour);
627 colourMenu.add(BLOSUM62Colour);
628 colourMenu.add(PIDColour);
629 colourMenu.add(zappoColour);
630 colourMenu.add(taylorColour);
631 colourMenu.add(hydrophobicityColour);
632 colourMenu.add(helixColour);
633 colourMenu.add(strandColour);
634 colourMenu.add(turnColour);
635 colourMenu.add(buriedColour);
636 colourMenu.add(nucleotideMenuItem);
637 colourMenu.add(userDefinedColour);
638 colourMenu.addSeparator();
639 colourMenu.add(abovePIDColour);
640 colourMenu.add(conservationMenuItem);
642 noColourmenuItem.setLabel("None");
643 noColourmenuItem.addActionListener(this);
645 clustalColour.setLabel("Clustalx colours");
646 clustalColour.addActionListener(this);
647 zappoColour.setLabel("Zappo");
648 zappoColour.addActionListener(this);
649 taylorColour.setLabel("Taylor");
650 taylorColour.addActionListener(this);
651 hydrophobicityColour.setLabel("Hydrophobicity");
652 hydrophobicityColour.addActionListener(this);
653 helixColour.setLabel("Helix propensity");
654 helixColour.addActionListener(this);
655 strandColour.setLabel("Strand propensity");
656 strandColour.addActionListener(this);
657 turnColour.setLabel("Turn propensity");
658 turnColour.addActionListener(this);
659 buriedColour.setLabel("Buried Index");
660 buriedColour.addActionListener(this);
661 abovePIDColour.setLabel("Above % Identity");
663 userDefinedColour.setLabel("User Defined");
664 userDefinedColour.addActionListener(this);
665 PIDColour.setLabel("Percentage Identity");
666 PIDColour.addActionListener(this);
667 BLOSUM62Colour.setLabel("BLOSUM62");
668 BLOSUM62Colour.addActionListener(this);
669 conservationMenuItem.setLabel("Conservation");
672 copy.addActionListener(this);
674 cut.addActionListener(this);
676 editMenu.add(editSequence);
677 editSequence.addActionListener(this);
679 editMenu.add(toUpper);
680 toUpper.addActionListener(this);
681 editMenu.add(toLower);
682 toLower.addActionListener(this);
683 editMenu.add(toggleCase);
684 seqMenu.add(sequenceName);
686 seqMenu.add(repGroup);
687 menu1.add(unGroupMenuItem);
688 menu1.add(colourMenu);
689 menu1.add(showBoxes);
691 menu1.add(showColourText);
692 toggleCase.addActionListener(this);
693 pdb.addActionListener(this);
694 hideSeqs.addActionListener(this);
695 repGroup.addActionListener(this);
696 revealAll.addActionListener(this);
701 ap.paintAlignment(true);
704 protected void clustalColour_actionPerformed()
706 SequenceGroup sg = getGroup();
707 sg.cs = new ClustalxColourScheme(sg.getSequences(ap.av.hiddenRepSequences),
708 ap.av.alignment.getWidth());
712 protected void zappoColour_actionPerformed()
714 getGroup().cs = new ZappoColourScheme();
718 protected void taylorColour_actionPerformed()
720 getGroup().cs = new TaylorColourScheme();
724 protected void hydrophobicityColour_actionPerformed()
726 getGroup().cs = new HydrophobicColourScheme();
730 protected void helixColour_actionPerformed()
732 getGroup().cs = new HelixColourScheme();
736 protected void strandColour_actionPerformed()
738 getGroup().cs = new StrandColourScheme();
742 protected void turnColour_actionPerformed()
744 getGroup().cs = new TurnColourScheme();
748 protected void buriedColour_actionPerformed()
750 getGroup().cs = new BuriedColourScheme();
754 public void nucleotideMenuItem_actionPerformed()
756 getGroup().cs = new NucleotideColourScheme();
760 protected void abovePIDColour_itemStateChanged()
762 SequenceGroup sg = getGroup();
768 if (abovePIDColour.getState())
770 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
771 hiddenRepSequences), 0,
772 ap.av.alignment.getWidth()));
773 int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,
774 getGroup().getName());
776 sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
778 SliderPanel.showPIDSlider();
781 else // remove PIDColouring
783 sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
790 protected void userDefinedColour_actionPerformed()
792 new UserDefinedColours(ap, getGroup());
795 protected void PIDColour_actionPerformed()
797 SequenceGroup sg = getGroup();
798 sg.cs = new PIDColourScheme();
799 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
800 hiddenRepSequences), 0,
801 ap.av.alignment.getWidth()));
805 protected void BLOSUM62Colour_actionPerformed()
807 SequenceGroup sg = getGroup();
809 sg.cs = new Blosum62ColourScheme();
811 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
812 hiddenRepSequences), 0,
813 ap.av.alignment.getWidth()));
818 protected void noColourmenuItem_actionPerformed()
820 getGroup().cs = null;
824 protected void conservationMenuItem_itemStateChanged()
826 SequenceGroup sg = getGroup();
832 if (conservationMenuItem.getState())
835 Conservation c = new Conservation("Group",
836 ResidueProperties.propHash, 3,
837 sg.getSequences(ap.av.
838 hiddenRepSequences), 0,
839 ap.av.alignment.getWidth());
842 c.verdict(false, ap.av.ConsPercGaps);
844 sg.cs.setConservation(c);
846 SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
847 SliderPanel.showConservationSlider();
849 else // remove ConservationColouring
851 sg.cs.setConservation(null);
857 SequenceGroup getGroup()
859 SequenceGroup sg = ap.av.getSelectionGroup();
861 // this method won't add a new group if it already exists
864 ap.av.alignment.addGroup(sg);
870 void unGroupMenuItem_actionPerformed()
872 SequenceGroup sg = ap.av.getSelectionGroup();
873 ap.av.alignment.deleteGroup(sg);
874 ap.av.setSelectionGroup(null);
875 ap.paintAlignment(true);
878 public void showColourText_itemStateChanged()
880 getGroup().setColourText(showColourText.getState());
884 public void showText_itemStateChanged()
886 getGroup().setDisplayText(showText.getState());
890 public void showBoxes_itemStateChanged()
892 getGroup().setDisplayBoxes(showBoxes.getState());
896 void hideSequences(boolean representGroup)
898 SequenceGroup sg = ap.av.getSelectionGroup();
899 if (sg == null || sg.getSize() < 1)
901 ap.av.hideSequence(new SequenceI[]
906 ap.av.setSelectionGroup(null);
910 ap.av.hideRepSequences(seq, sg);
915 int gsize = sg.getSize();
918 hseqs = new SequenceI[gsize];
921 for (int i = 0; i < gsize; i++)
923 hseqs[index++] = sg.getSequenceAt(i);
926 ap.av.hideSequence(hseqs);